experimental diff:
From: Todd C. Miller <Todd.Miller@courtesan.com> The following ksh diff needs wide testing. It does the following: 1) proper error message for bad substitution. Before: $ echo ${a[@]:foo} ksh: : bad substitution After: $ echo ${a[@]:foo} ksh: ${a[@]:foo}: bad substitution 2) fix a core dump for "echo ${a[@]:?foo}". 3) fix a use-after-free bug (from otto@)
This commit is contained in:
28
main.c
28
main.c
@ -1,4 +1,4 @@
|
||||
/** $MirBSD: main.c,v 1.15 2004/11/10 17:13:11 tg Exp $ */
|
||||
/** $MirBSD: main.c,v 1.16 2004/12/10 22:21:25 tg Exp $ */
|
||||
/* $OpenBSD: main.c,v 1.28 2004/08/23 14:56:32 millert Exp $ */
|
||||
|
||||
/*
|
||||
@ -11,7 +11,7 @@
|
||||
#include "ksh_stat.h"
|
||||
#include "ksh_time.h"
|
||||
|
||||
__RCSID("$MirBSD: main.c,v 1.15 2004/11/10 17:13:11 tg Exp $");
|
||||
__RCSID("$MirBSD: main.c,v 1.16 2004/12/10 22:21:25 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -479,9 +479,7 @@ include(const char *name, int argc, char **argv, int intr_ok)
|
||||
newenv(E_INCL);
|
||||
i = ksh_sigsetjmp(e->jbuf, 0);
|
||||
if (i) {
|
||||
if (s) /* Do this before quitenv(), which frees the memory */
|
||||
shf_close(s->u.shf);
|
||||
quitenv();
|
||||
quitenv(s ? s->u.shf : NULL);
|
||||
if (old_argv) {
|
||||
e->loc->argv = old_argv;
|
||||
e->loc->argc = old_argc;
|
||||
@ -515,8 +513,7 @@ include(const char *name, int argc, char **argv, int intr_ok)
|
||||
s->u.shf = shf;
|
||||
s->file = str_save(name, ATEMP);
|
||||
i = shell(s, FALSE);
|
||||
shf_close(s->u.shf);
|
||||
quitenv();
|
||||
quitenv(s->u.shf);
|
||||
if (old_argv) {
|
||||
e->loc->argv = old_argv;
|
||||
e->loc->argc = old_argc;
|
||||
@ -582,12 +579,12 @@ shell(Source *volatile s, volatile int toplevel)
|
||||
case LLEAVE:
|
||||
case LRETURN:
|
||||
source = old_source;
|
||||
quitenv();
|
||||
quitenv(NULL);
|
||||
unwind(i); /* keep on going */
|
||||
/*NOREACHED*/
|
||||
default:
|
||||
source = old_source;
|
||||
quitenv();
|
||||
quitenv(NULL);
|
||||
internal_errorf(1, "shell: %d", i);
|
||||
/*NOREACHED*/
|
||||
}
|
||||
@ -639,7 +636,7 @@ shell(Source *volatile s, volatile int toplevel)
|
||||
|
||||
reclaim();
|
||||
}
|
||||
quitenv();
|
||||
quitenv(NULL);
|
||||
source = old_source;
|
||||
return exstat;
|
||||
}
|
||||
@ -674,7 +671,7 @@ unwind(int i)
|
||||
/* Fall through... */
|
||||
|
||||
default:
|
||||
quitenv();
|
||||
quitenv(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -696,7 +693,7 @@ newenv(int type)
|
||||
}
|
||||
|
||||
void
|
||||
quitenv(void)
|
||||
quitenv(struct shf *shf)
|
||||
{
|
||||
struct env *ep = e;
|
||||
int fd;
|
||||
@ -711,7 +708,6 @@ quitenv(void)
|
||||
if (ep->savefd[2]) /* Clear any write errors */
|
||||
shf_reopen(2, SHF_WR, shl_out);
|
||||
}
|
||||
reclaim();
|
||||
|
||||
/* Bottom of the stack.
|
||||
* Either main shell is exiting or cleanup_parents_env() was called.
|
||||
@ -740,8 +736,14 @@ quitenv(void)
|
||||
chmem_allfree();
|
||||
#endif /* MEM_DEBUG */
|
||||
}
|
||||
if (shf)
|
||||
shf_close(shf);
|
||||
reclaim();
|
||||
exit(exstat);
|
||||
}
|
||||
if (shf)
|
||||
shf_close(shf);
|
||||
reclaim();
|
||||
|
||||
e = e->oenv;
|
||||
afree(ep, ATEMP);
|
||||
|
Reference in New Issue
Block a user