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