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:
parent
e2c4bce569
commit
8a1afa6087
6
c_sh.c
6
c_sh.c
@ -1,4 +1,4 @@
|
|||||||
/** $MirBSD: c_sh.c,v 1.7 2004/10/28 11:53:39 tg Exp $ */
|
/** $MirBSD: c_sh.c,v 1.8 2004/12/10 22:21:24 tg Exp $ */
|
||||||
/* $OpenBSD: c_sh.c,v 1.17 2003/03/13 09:03:07 deraadt Exp $ */
|
/* $OpenBSD: c_sh.c,v 1.17 2003/03/13 09:03:07 deraadt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include "ksh_time.h"
|
#include "ksh_time.h"
|
||||||
#include "ksh_times.h"
|
#include "ksh_times.h"
|
||||||
|
|
||||||
__RCSID("$MirBSD: c_sh.c,v 1.7 2004/10/28 11:53:39 tg Exp $");
|
__RCSID("$MirBSD: c_sh.c,v 1.8 2004/12/10 22:21:24 tg Exp $");
|
||||||
|
|
||||||
static char *clocktos(clock_t t);
|
static char *clocktos(clock_t t);
|
||||||
|
|
||||||
@ -540,7 +540,7 @@ c_exitreturn(char **wp)
|
|||||||
how = LSHELL;
|
how = LSHELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
quitenv(); /* get rid of any i/o redirections */
|
quitenv(NULL); /* get rid of any i/o redirections */
|
||||||
unwind(how);
|
unwind(how);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return 0;
|
return 0;
|
||||||
|
9
eval.c
9
eval.c
@ -1,4 +1,4 @@
|
|||||||
/** $MirBSD: eval.c,v 1.10 2004/12/10 16:01:34 tg Exp $ */
|
/** $MirBSD: eval.c,v 1.11 2004/12/10 22:21:25 tg Exp $ */
|
||||||
/* $OpenBSD: eval.c,v 1.16 2004/12/08 21:23:18 millert Exp $ */
|
/* $OpenBSD: eval.c,v 1.16 2004/12/08 21:23:18 millert Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include "ksh_dir.h"
|
#include "ksh_dir.h"
|
||||||
#include "ksh_stat.h"
|
#include "ksh_stat.h"
|
||||||
|
|
||||||
__RCSID("$MirBSD: eval.c,v 1.10 2004/12/10 16:01:34 tg Exp $");
|
__RCSID("$MirBSD: eval.c,v 1.11 2004/12/10 22:21:25 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -287,12 +287,12 @@ expand(char *cp, XPtrV *wp, int f)
|
|||||||
char endc;
|
char endc;
|
||||||
char *str, *end;
|
char *str, *end;
|
||||||
|
|
||||||
|
sp = varname - 2; /* restore sp */
|
||||||
end = (char *) wdscan(sp, CSUBST);
|
end = (char *) wdscan(sp, CSUBST);
|
||||||
/* ({) the } or x is already skipped */
|
/* ({) the } or x is already skipped */
|
||||||
endc = *end;
|
endc = *end;
|
||||||
*end = EOS;
|
*end = EOS;
|
||||||
str = snptreef((char *) 0, 64, "%S",
|
str = snptreef(NULL, 64, "%S", sp);
|
||||||
varname - 1);
|
|
||||||
*end = endc;
|
*end = endc;
|
||||||
errorf("%s: bad substitution", str);
|
errorf("%s: bad substitution", str);
|
||||||
}
|
}
|
||||||
@ -801,6 +801,7 @@ varsub(Expand *xp, char *sp, char *word, int *stypep, int *slenp)
|
|||||||
case '=': /* can't assign to a vector */
|
case '=': /* can't assign to a vector */
|
||||||
case '%': /* can't trim a vector (yet) */
|
case '%': /* can't trim a vector (yet) */
|
||||||
case '#':
|
case '#':
|
||||||
|
case '?':
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
XPinit(wv, 32);
|
XPinit(wv, 32);
|
||||||
|
21
exec.c
21
exec.c
@ -1,4 +1,4 @@
|
|||||||
/** $MirBSD: exec.c,v 1.6 2004/10/28 11:53:41 tg Exp $ */
|
/** $MirBSD: exec.c,v 1.7 2004/12/10 22:21:25 tg Exp $ */
|
||||||
/* $OpenBSD: exec.c,v 1.31 2003/12/15 05:25:52 otto Exp $ */
|
/* $OpenBSD: exec.c,v 1.31 2003/12/15 05:25:52 otto Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "ksh_stat.h"
|
#include "ksh_stat.h"
|
||||||
|
|
||||||
__RCSID("$MirBSD: exec.c,v 1.6 2004/10/28 11:53:41 tg Exp $");
|
__RCSID("$MirBSD: exec.c,v 1.7 2004/12/10 22:21:25 tg Exp $");
|
||||||
|
|
||||||
/* Does ps4 get parameter substitutions done? */
|
/* Does ps4 get parameter substitutions done? */
|
||||||
#ifdef KSH
|
#ifdef KSH
|
||||||
@ -215,7 +215,7 @@ execute(struct op *volatile t, volatile int flags)
|
|||||||
i = ksh_sigsetjmp(e->jbuf, 0);
|
i = ksh_sigsetjmp(e->jbuf, 0);
|
||||||
if (i) {
|
if (i) {
|
||||||
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
unwind(i);
|
unwind(i);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
@ -321,7 +321,7 @@ execute(struct op *volatile t, volatile int flags)
|
|||||||
if ((e->flags&EF_BRKCONT_PASS)
|
if ((e->flags&EF_BRKCONT_PASS)
|
||||||
|| (i != LBREAK && i != LCONTIN))
|
|| (i != LBREAK && i != LCONTIN))
|
||||||
{
|
{
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
unwind(i);
|
unwind(i);
|
||||||
} else if (i == LBREAK) {
|
} else if (i == LBREAK) {
|
||||||
rv = 0;
|
rv = 0;
|
||||||
@ -361,7 +361,7 @@ execute(struct op *volatile t, volatile int flags)
|
|||||||
if ((e->flags&EF_BRKCONT_PASS)
|
if ((e->flags&EF_BRKCONT_PASS)
|
||||||
|| (i != LBREAK && i != LCONTIN))
|
|| (i != LBREAK && i != LCONTIN))
|
||||||
{
|
{
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
unwind(i);
|
unwind(i);
|
||||||
} else if (i == LBREAK) {
|
} else if (i == LBREAK) {
|
||||||
rv = 0;
|
rv = 0;
|
||||||
@ -431,7 +431,7 @@ execute(struct op *volatile t, volatile int flags)
|
|||||||
Break:
|
Break:
|
||||||
exstat = rv;
|
exstat = rv;
|
||||||
|
|
||||||
quitenv(); /* restores IO */
|
quitenv(NULL); /* restores IO */
|
||||||
if ((flags&XEXEC))
|
if ((flags&XEXEC))
|
||||||
unwind(LEXIT); /* exit child */
|
unwind(LEXIT); /* exit child */
|
||||||
if (rv != 0 && !(flags & XERROK)) {
|
if (rv != 0 && !(flags & XERROK)) {
|
||||||
@ -686,11 +686,11 @@ comexec(struct op *t, struct tbl *volatile tp, char **ap, volatile int flags)
|
|||||||
case LEXIT:
|
case LEXIT:
|
||||||
case LLEAVE:
|
case LLEAVE:
|
||||||
case LSHELL:
|
case LSHELL:
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
unwind(i);
|
unwind(i);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
default:
|
default:
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
internal_errorf(1, "CFUNC %d", i);
|
internal_errorf(1, "CFUNC %d", i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1453,8 +1453,7 @@ herein(const char *content, int sub)
|
|||||||
i = ksh_sigsetjmp(e->jbuf, 0);
|
i = ksh_sigsetjmp(e->jbuf, 0);
|
||||||
if (i) {
|
if (i) {
|
||||||
source = osource;
|
source = osource;
|
||||||
quitenv();
|
quitenv(shf);
|
||||||
shf_close(shf); /* after quitenv */
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return -2; /* special to iosetup(): don't print error */
|
return -2; /* special to iosetup(): don't print error */
|
||||||
}
|
}
|
||||||
@ -1470,7 +1469,7 @@ herein(const char *content, int sub)
|
|||||||
} else
|
} else
|
||||||
shf_puts(content, shf);
|
shf_puts(content, shf);
|
||||||
|
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
|
|
||||||
if (shf_close(shf) == EOF) {
|
if (shf_close(shf) == EOF) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
8
expr.c
8
expr.c
@ -1,4 +1,4 @@
|
|||||||
/** $MirBSD: expr.c,v 1.7 2004/10/28 11:53:41 tg Exp $ */
|
/** $MirBSD: expr.c,v 1.8 2004/12/10 22:21:25 tg Exp $ */
|
||||||
/* $OpenBSD: expr.c,v 1.9 2003/10/22 07:40:38 jmc Exp $ */
|
/* $OpenBSD: expr.c,v 1.9 2003/10/22 07:40:38 jmc Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
__RCSID("$MirBSD: expr.c,v 1.7 2004/10/28 11:53:41 tg Exp $");
|
__RCSID("$MirBSD: expr.c,v 1.8 2004/12/10 22:21:25 tg Exp $");
|
||||||
|
|
||||||
/* The order of these enums is constrained by the order of opinfo[] */
|
/* The order of these enums is constrained by the order of opinfo[] */
|
||||||
enum token {
|
enum token {
|
||||||
@ -176,7 +176,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok)
|
|||||||
/* Clear EXPRINEVAL in of any variables we were playing with */
|
/* Clear EXPRINEVAL in of any variables we were playing with */
|
||||||
if (curstate.evaling)
|
if (curstate.evaling)
|
||||||
curstate.evaling->flag &= ~EXPRINEVAL;
|
curstate.evaling->flag &= ~EXPRINEVAL;
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
if (i == LAEXPR) {
|
if (i == LAEXPR) {
|
||||||
if (error_ok == KSH_RETURN_ERROR)
|
if (error_ok == KSH_RETURN_ERROR)
|
||||||
return 0;
|
return 0;
|
||||||
@ -202,7 +202,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok)
|
|||||||
/* can fail if readonly */
|
/* can fail if readonly */
|
||||||
setstr(vp, str_val(v), error_ok);
|
setstr(vp, str_val(v), error_ok);
|
||||||
|
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
6
lex.c
6
lex.c
@ -1,4 +1,4 @@
|
|||||||
/** $MirBSD: lex.c,v 1.7 2004/10/28 11:53:42 tg Exp $ */
|
/** $MirBSD: lex.c,v 1.8 2004/12/10 22:21:25 tg Exp $ */
|
||||||
/* $OpenBSD: lex.c,v 1.18 2003/08/06 21:08:05 millert Exp $ */
|
/* $OpenBSD: lex.c,v 1.18 2003/08/06 21:08:05 millert Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
__RCSID("$MirBSD: lex.c,v 1.7 2004/10/28 11:53:42 tg Exp $");
|
__RCSID("$MirBSD: lex.c,v 1.8 2004/12/10 22:21:25 tg Exp $");
|
||||||
|
|
||||||
/* Structure to keep track of the lexing state and the various pieces of info
|
/* Structure to keep track of the lexing state and the various pieces of info
|
||||||
* needed for each particular state.
|
* needed for each particular state.
|
||||||
@ -1140,7 +1140,7 @@ set_prompt(int to, Source *s)
|
|||||||
} else
|
} else
|
||||||
prompt = str_save(substitute(ps1, 0),
|
prompt = str_save(substitute(ps1, 0),
|
||||||
saved_atemp);
|
saved_atemp);
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
}
|
}
|
||||||
#else /* KSH */
|
#else /* KSH */
|
||||||
prompt = str_val(global("PS1"));
|
prompt = str_val(global("PS1"));
|
||||||
|
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 $ */
|
/* $OpenBSD: main.c,v 1.28 2004/08/23 14:56:32 millert Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#include "ksh_stat.h"
|
#include "ksh_stat.h"
|
||||||
#include "ksh_time.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;
|
extern char **environ;
|
||||||
|
|
||||||
@ -479,9 +479,7 @@ include(const char *name, int argc, char **argv, int intr_ok)
|
|||||||
newenv(E_INCL);
|
newenv(E_INCL);
|
||||||
i = ksh_sigsetjmp(e->jbuf, 0);
|
i = ksh_sigsetjmp(e->jbuf, 0);
|
||||||
if (i) {
|
if (i) {
|
||||||
if (s) /* Do this before quitenv(), which frees the memory */
|
quitenv(s ? s->u.shf : NULL);
|
||||||
shf_close(s->u.shf);
|
|
||||||
quitenv();
|
|
||||||
if (old_argv) {
|
if (old_argv) {
|
||||||
e->loc->argv = old_argv;
|
e->loc->argv = old_argv;
|
||||||
e->loc->argc = old_argc;
|
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->u.shf = shf;
|
||||||
s->file = str_save(name, ATEMP);
|
s->file = str_save(name, ATEMP);
|
||||||
i = shell(s, FALSE);
|
i = shell(s, FALSE);
|
||||||
shf_close(s->u.shf);
|
quitenv(s->u.shf);
|
||||||
quitenv();
|
|
||||||
if (old_argv) {
|
if (old_argv) {
|
||||||
e->loc->argv = old_argv;
|
e->loc->argv = old_argv;
|
||||||
e->loc->argc = old_argc;
|
e->loc->argc = old_argc;
|
||||||
@ -582,12 +579,12 @@ shell(Source *volatile s, volatile int toplevel)
|
|||||||
case LLEAVE:
|
case LLEAVE:
|
||||||
case LRETURN:
|
case LRETURN:
|
||||||
source = old_source;
|
source = old_source;
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
unwind(i); /* keep on going */
|
unwind(i); /* keep on going */
|
||||||
/*NOREACHED*/
|
/*NOREACHED*/
|
||||||
default:
|
default:
|
||||||
source = old_source;
|
source = old_source;
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
internal_errorf(1, "shell: %d", i);
|
internal_errorf(1, "shell: %d", i);
|
||||||
/*NOREACHED*/
|
/*NOREACHED*/
|
||||||
}
|
}
|
||||||
@ -639,7 +636,7 @@ shell(Source *volatile s, volatile int toplevel)
|
|||||||
|
|
||||||
reclaim();
|
reclaim();
|
||||||
}
|
}
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
source = old_source;
|
source = old_source;
|
||||||
return exstat;
|
return exstat;
|
||||||
}
|
}
|
||||||
@ -674,7 +671,7 @@ unwind(int i)
|
|||||||
/* Fall through... */
|
/* Fall through... */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
quitenv();
|
quitenv(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,7 +693,7 @@ newenv(int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
quitenv(void)
|
quitenv(struct shf *shf)
|
||||||
{
|
{
|
||||||
struct env *ep = e;
|
struct env *ep = e;
|
||||||
int fd;
|
int fd;
|
||||||
@ -711,7 +708,6 @@ quitenv(void)
|
|||||||
if (ep->savefd[2]) /* Clear any write errors */
|
if (ep->savefd[2]) /* Clear any write errors */
|
||||||
shf_reopen(2, SHF_WR, shl_out);
|
shf_reopen(2, SHF_WR, shl_out);
|
||||||
}
|
}
|
||||||
reclaim();
|
|
||||||
|
|
||||||
/* Bottom of the stack.
|
/* Bottom of the stack.
|
||||||
* Either main shell is exiting or cleanup_parents_env() was called.
|
* Either main shell is exiting or cleanup_parents_env() was called.
|
||||||
@ -740,8 +736,14 @@ quitenv(void)
|
|||||||
chmem_allfree();
|
chmem_allfree();
|
||||||
#endif /* MEM_DEBUG */
|
#endif /* MEM_DEBUG */
|
||||||
}
|
}
|
||||||
|
if (shf)
|
||||||
|
shf_close(shf);
|
||||||
|
reclaim();
|
||||||
exit(exstat);
|
exit(exstat);
|
||||||
}
|
}
|
||||||
|
if (shf)
|
||||||
|
shf_close(shf);
|
||||||
|
reclaim();
|
||||||
|
|
||||||
e = e->oenv;
|
e = e->oenv;
|
||||||
afree(ep, ATEMP);
|
afree(ep, ATEMP);
|
||||||
|
4
proto.h
4
proto.h
@ -1,4 +1,4 @@
|
|||||||
/** $MirBSD: proto.h,v 1.10 2004/11/10 17:13:11 tg Exp $ */
|
/** $MirBSD: proto.h,v 1.11 2004/12/10 22:21:26 tg Exp $ */
|
||||||
/* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */
|
/* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */
|
||||||
/* $From: proto.h,v 1.3 1994/05/19 18:32:40 michael Exp michael $ */
|
/* $From: proto.h,v 1.3 1994/05/19 18:32:40 michael Exp michael $ */
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ int command(const char *comm);
|
|||||||
int shell(Source *volatile s, int volatile toplevel);
|
int shell(Source *volatile s, int volatile toplevel);
|
||||||
void unwind(int i) GCC_FUNC_ATTR(noreturn);
|
void unwind(int i) GCC_FUNC_ATTR(noreturn);
|
||||||
void newenv(int type);
|
void newenv(int type);
|
||||||
void quitenv(void);
|
void quitenv(struct shf *shf);
|
||||||
void cleanup_parents_env(void);
|
void cleanup_parents_env(void);
|
||||||
void cleanup_proc_env(void);
|
void cleanup_proc_env(void);
|
||||||
void aerror(Area *ap, const char *msg)
|
void aerror(Area *ap, const char *msg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user