ash: fix a bug in >${varexp} handling. Closes 5282

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2012-06-09 02:06:57 +02:00
parent 37ca36a711
commit f451b2cfe0
3 changed files with 26 additions and 10 deletions

View File

@ -23,8 +23,9 @@
* define DEBUG=1 to compile in debugging ('set -o debug' to turn on) * define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
* define DEBUG=2 to compile in and turn on debugging. * define DEBUG=2 to compile in and turn on debugging.
* *
* When debugging is on, debugging info will be written to ./trace and * When debugging is on (DEBUG is 1 and "set -o debug" was executed),
* a quit signal will generate a core dump. * debugging info will be written to ./trace and a quit signal
* will generate a core dump.
*/ */
#define DEBUG 0 #define DEBUG 0
/* Tweak debug output verbosity here */ /* Tweak debug output verbosity here */
@ -5105,15 +5106,14 @@ openredirect(union node *redir)
char *fname; char *fname;
int f; int f;
fname = redir->nfile.expfname;
switch (redir->nfile.type) { switch (redir->nfile.type) {
case NFROM: case NFROM:
fname = redir->nfile.expfname;
f = open(fname, O_RDONLY); f = open(fname, O_RDONLY);
if (f < 0) if (f < 0)
goto eopen; goto eopen;
break; break;
case NFROMTO: case NFROMTO:
fname = redir->nfile.expfname;
f = open(fname, O_RDWR|O_CREAT, 0666); f = open(fname, O_RDWR|O_CREAT, 0666);
if (f < 0) if (f < 0)
goto ecreate; goto ecreate;
@ -5124,7 +5124,6 @@ openredirect(union node *redir)
#endif #endif
/* Take care of noclobber mode. */ /* Take care of noclobber mode. */
if (Cflag) { if (Cflag) {
fname = redir->nfile.expfname;
f = noclobberopen(fname); f = noclobberopen(fname);
if (f < 0) if (f < 0)
goto ecreate; goto ecreate;
@ -5132,13 +5131,11 @@ openredirect(union node *redir)
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
case NCLOBBER: case NCLOBBER:
fname = redir->nfile.expfname;
f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
if (f < 0) if (f < 0)
goto ecreate; goto ecreate;
break; break;
case NAPPEND: case NAPPEND:
fname = redir->nfile.expfname;
f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
if (f < 0) if (f < 0)
goto ecreate; goto ecreate;
@ -6138,7 +6135,9 @@ argstr(char *p, int flags, struct strlist *var_str_list)
length++; length++;
goto addquote; goto addquote;
case CTLVAR: case CTLVAR:
TRACE(("argstr: evalvar('%s')\n", p));
p = evalvar(p, flags, var_str_list); p = evalvar(p, flags, var_str_list);
TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
goto start; goto start;
case CTLBACKQ: case CTLBACKQ:
c = '\0'; c = '\0';
@ -6846,8 +6845,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
patloc = expdest - (char *)stackblock(); patloc = expdest - (char *)stackblock();
if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
startloc, varflags, startloc, varflags,
//TODO: | EXP_REDIR too? All other such places do it too /* quotes: */ flags & (EXP_FULL | EXP_CASE | EXP_REDIR),
/* quotes: */ flags & (EXP_FULL | EXP_CASE),
var_str_list) var_str_list)
) { ) {
int amount = expdest - ( int amount = expdest - (
@ -7249,6 +7247,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
STARTSTACKSTR(expdest); STARTSTACKSTR(expdest);
ifsfirst.next = NULL; ifsfirst.next = NULL;
ifslastp = NULL; ifslastp = NULL;
TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
argstr(arg->narg.text, flag, argstr(arg->narg.text, flag,
/* var_str_list: */ arglist ? arglist->list : NULL); /* var_str_list: */ arglist ? arglist->list : NULL);
p = _STPUTC('\0', expdest); p = _STPUTC('\0', expdest);
@ -7257,6 +7256,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
return; /* here document expanded */ return; /* here document expanded */
} }
p = grabstackstr(p); p = grabstackstr(p);
TRACE(("expandarg: p:'%s'\n", p));
exparg.lastp = &exparg.list; exparg.lastp = &exparg.list;
/* /*
* TODO - EXP_REDIR * TODO - EXP_REDIR
@ -7267,8 +7267,10 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
exparg.lastp = &exparg.list; exparg.lastp = &exparg.list;
expandmeta(exparg.list /*, flag*/); expandmeta(exparg.list /*, flag*/);
} else { } else {
if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ if (flag & EXP_REDIR) { /*XXX - for now, just remove escapes */
rmescapes(p, 0); rmescapes(p, 0);
TRACE(("expandarg: rmescapes:'%s'\n", p));
}
sp = stzalloc(sizeof(*sp)); sp = stzalloc(sizeof(*sp));
sp->text = p; sp->text = p;
*exparg.lastp = sp; *exparg.lastp = sp;
@ -8665,6 +8667,7 @@ expredir(union node *n)
case NCLOBBER: case NCLOBBER:
case NAPPEND: case NAPPEND:
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
TRACE(("expredir expanded to '%s'\n", fn.list->text));
#if ENABLE_ASH_BASH_COMPAT #if ENABLE_ASH_BASH_COMPAT
store_expfname: store_expfname:
#endif #endif

View File

@ -0,0 +1,2 @@
tmp11
tmp11

View File

@ -0,0 +1,11 @@
x="tmp11:tmp22"
# Bug was incorrectly expanding variables in >redir
echo "${x%:*}" >"${x%:*}"
echo tmp1*
rm tmp1*
# Also try unquoted
echo "${x%:*}" >${x%:*}
echo tmp1*
rm tmp1*