ash: fix a bug in >${varexp} handling. Closes 5282
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 9 Jun 2012 00:06:57 +0000 (02:06 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 9 Jun 2012 00:06:57 +0000 (02:06 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/ash_test/ash-redir/redirA.right [new file with mode: 0644]
shell/ash_test/ash-redir/redirA.tests [new file with mode: 0755]

index d197fa19a4d44cdad139b2f2224e617e72e2e567..e23b2034d373a7c07e3ddf7bb51918d479eb62fb 100644 (file)
@@ -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 @@ openredirect(union node *redir)
        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 @@ openredirect(union node *redir)
 #endif
                /* Take care of noclobber mode. */
                if (Cflag) {
-                       fname = redir->nfile.expfname;
                        f = noclobberopen(fname);
                        if (f < 0)
                                goto ecreate;
@@ -5132,13 +5131,11 @@ openredirect(union node *redir)
                }
                /* 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 @@ argstr(char *p, int flags, struct strlist *var_str_list)
                        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 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
                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 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
        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 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
                return;                 /* here document expanded */
        }
        p = grabstackstr(p);
+       TRACE(("expandarg: p:'%s'\n", p));
        exparg.lastp = &exparg.list;
        /*
         * TODO - EXP_REDIR
@@ -7267,8 +7267,10 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
                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 @@ expredir(union node *n)
                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 (file)
index 0000000..31406e3
--- /dev/null
@@ -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 (executable)
index 0000000..56833f9
--- /dev/null
@@ -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*