diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2012-06-09 02:06:57 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-06-09 02:06:57 +0200 |
| commit | f451b2cfe042e3029b73261758b9ab7e956eaa03 (patch) | |
| tree | 9e9ac2a6c3eab61e993eafb8299bf0b5694a8b2a /shell | |
| parent | 37ca36a71114a6fc5303d33cabc311cd8b9bf19a (diff) | |
| download | busybox-w32-f451b2cfe042e3029b73261758b9ab7e956eaa03.tar.gz busybox-w32-f451b2cfe042e3029b73261758b9ab7e956eaa03.tar.bz2 busybox-w32-f451b2cfe042e3029b73261758b9ab7e956eaa03.zip | |
ash: fix a bug in >${varexp} handling. Closes 5282
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 23 | ||||
| -rw-r--r-- | shell/ash_test/ash-redir/redirA.right | 2 | ||||
| -rwxr-xr-x | shell/ash_test/ash-redir/redirA.tests | 11 |
3 files changed, 26 insertions, 10 deletions
diff --git a/shell/ash.c b/shell/ash.c index d197fa19a..e23b2034d 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -23,8 +23,9 @@ | |||
| 23 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) | 23 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) |
| 24 | * define DEBUG=2 to compile in and turn on debugging. | 24 | * define DEBUG=2 to compile in and turn on debugging. |
| 25 | * | 25 | * |
| 26 | * When debugging is on, debugging info will be written to ./trace and | 26 | * When debugging is on (DEBUG is 1 and "set -o debug" was executed), |
| 27 | * a quit signal will generate a core dump. | 27 | * debugging info will be written to ./trace and a quit signal |
| 28 | * will generate a core dump. | ||
| 28 | */ | 29 | */ |
| 29 | #define DEBUG 0 | 30 | #define DEBUG 0 |
| 30 | /* Tweak debug output verbosity here */ | 31 | /* Tweak debug output verbosity here */ |
| @@ -5105,15 +5106,14 @@ openredirect(union node *redir) | |||
| 5105 | char *fname; | 5106 | char *fname; |
| 5106 | int f; | 5107 | int f; |
| 5107 | 5108 | ||
| 5109 | fname = redir->nfile.expfname; | ||
| 5108 | switch (redir->nfile.type) { | 5110 | switch (redir->nfile.type) { |
| 5109 | case NFROM: | 5111 | case NFROM: |
| 5110 | fname = redir->nfile.expfname; | ||
| 5111 | f = open(fname, O_RDONLY); | 5112 | f = open(fname, O_RDONLY); |
| 5112 | if (f < 0) | 5113 | if (f < 0) |
| 5113 | goto eopen; | 5114 | goto eopen; |
| 5114 | break; | 5115 | break; |
| 5115 | case NFROMTO: | 5116 | case NFROMTO: |
| 5116 | fname = redir->nfile.expfname; | ||
| 5117 | f = open(fname, O_RDWR|O_CREAT, 0666); | 5117 | f = open(fname, O_RDWR|O_CREAT, 0666); |
| 5118 | if (f < 0) | 5118 | if (f < 0) |
| 5119 | goto ecreate; | 5119 | goto ecreate; |
| @@ -5124,7 +5124,6 @@ openredirect(union node *redir) | |||
| 5124 | #endif | 5124 | #endif |
| 5125 | /* Take care of noclobber mode. */ | 5125 | /* Take care of noclobber mode. */ |
| 5126 | if (Cflag) { | 5126 | if (Cflag) { |
| 5127 | fname = redir->nfile.expfname; | ||
| 5128 | f = noclobberopen(fname); | 5127 | f = noclobberopen(fname); |
| 5129 | if (f < 0) | 5128 | if (f < 0) |
| 5130 | goto ecreate; | 5129 | goto ecreate; |
| @@ -5132,13 +5131,11 @@ openredirect(union node *redir) | |||
| 5132 | } | 5131 | } |
| 5133 | /* FALLTHROUGH */ | 5132 | /* FALLTHROUGH */ |
| 5134 | case NCLOBBER: | 5133 | case NCLOBBER: |
| 5135 | fname = redir->nfile.expfname; | ||
| 5136 | f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); | 5134 | f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); |
| 5137 | if (f < 0) | 5135 | if (f < 0) |
| 5138 | goto ecreate; | 5136 | goto ecreate; |
| 5139 | break; | 5137 | break; |
| 5140 | case NAPPEND: | 5138 | case NAPPEND: |
| 5141 | fname = redir->nfile.expfname; | ||
| 5142 | f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); | 5139 | f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); |
| 5143 | if (f < 0) | 5140 | if (f < 0) |
| 5144 | goto ecreate; | 5141 | goto ecreate; |
| @@ -6138,7 +6135,9 @@ argstr(char *p, int flags, struct strlist *var_str_list) | |||
| 6138 | length++; | 6135 | length++; |
| 6139 | goto addquote; | 6136 | goto addquote; |
| 6140 | case CTLVAR: | 6137 | case CTLVAR: |
| 6138 | TRACE(("argstr: evalvar('%s')\n", p)); | ||
| 6141 | p = evalvar(p, flags, var_str_list); | 6139 | p = evalvar(p, flags, var_str_list); |
| 6140 | TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock())); | ||
| 6142 | goto start; | 6141 | goto start; |
| 6143 | case CTLBACKQ: | 6142 | case CTLBACKQ: |
| 6144 | c = '\0'; | 6143 | c = '\0'; |
| @@ -6846,8 +6845,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
| 6846 | patloc = expdest - (char *)stackblock(); | 6845 | patloc = expdest - (char *)stackblock(); |
| 6847 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, | 6846 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, |
| 6848 | startloc, varflags, | 6847 | startloc, varflags, |
| 6849 | //TODO: | EXP_REDIR too? All other such places do it too | 6848 | /* quotes: */ flags & (EXP_FULL | EXP_CASE | EXP_REDIR), |
| 6850 | /* quotes: */ flags & (EXP_FULL | EXP_CASE), | ||
| 6851 | var_str_list) | 6849 | var_str_list) |
| 6852 | ) { | 6850 | ) { |
| 6853 | int amount = expdest - ( | 6851 | int amount = expdest - ( |
| @@ -7249,6 +7247,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
| 7249 | STARTSTACKSTR(expdest); | 7247 | STARTSTACKSTR(expdest); |
| 7250 | ifsfirst.next = NULL; | 7248 | ifsfirst.next = NULL; |
| 7251 | ifslastp = NULL; | 7249 | ifslastp = NULL; |
| 7250 | TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); | ||
| 7252 | argstr(arg->narg.text, flag, | 7251 | argstr(arg->narg.text, flag, |
| 7253 | /* var_str_list: */ arglist ? arglist->list : NULL); | 7252 | /* var_str_list: */ arglist ? arglist->list : NULL); |
| 7254 | p = _STPUTC('\0', expdest); | 7253 | p = _STPUTC('\0', expdest); |
| @@ -7257,6 +7256,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
| 7257 | return; /* here document expanded */ | 7256 | return; /* here document expanded */ |
| 7258 | } | 7257 | } |
| 7259 | p = grabstackstr(p); | 7258 | p = grabstackstr(p); |
| 7259 | TRACE(("expandarg: p:'%s'\n", p)); | ||
| 7260 | exparg.lastp = &exparg.list; | 7260 | exparg.lastp = &exparg.list; |
| 7261 | /* | 7261 | /* |
| 7262 | * TODO - EXP_REDIR | 7262 | * TODO - EXP_REDIR |
| @@ -7267,8 +7267,10 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
| 7267 | exparg.lastp = &exparg.list; | 7267 | exparg.lastp = &exparg.list; |
| 7268 | expandmeta(exparg.list /*, flag*/); | 7268 | expandmeta(exparg.list /*, flag*/); |
| 7269 | } else { | 7269 | } else { |
| 7270 | if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ | 7270 | if (flag & EXP_REDIR) { /*XXX - for now, just remove escapes */ |
| 7271 | rmescapes(p, 0); | 7271 | rmescapes(p, 0); |
| 7272 | TRACE(("expandarg: rmescapes:'%s'\n", p)); | ||
| 7273 | } | ||
| 7272 | sp = stzalloc(sizeof(*sp)); | 7274 | sp = stzalloc(sizeof(*sp)); |
| 7273 | sp->text = p; | 7275 | sp->text = p; |
| 7274 | *exparg.lastp = sp; | 7276 | *exparg.lastp = sp; |
| @@ -8665,6 +8667,7 @@ expredir(union node *n) | |||
| 8665 | case NCLOBBER: | 8667 | case NCLOBBER: |
| 8666 | case NAPPEND: | 8668 | case NAPPEND: |
| 8667 | expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); | 8669 | expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); |
| 8670 | TRACE(("expredir expanded to '%s'\n", fn.list->text)); | ||
| 8668 | #if ENABLE_ASH_BASH_COMPAT | 8671 | #if ENABLE_ASH_BASH_COMPAT |
| 8669 | store_expfname: | 8672 | store_expfname: |
| 8670 | #endif | 8673 | #endif |
diff --git a/shell/ash_test/ash-redir/redirA.right b/shell/ash_test/ash-redir/redirA.right new file mode 100644 index 000000000..31406e336 --- /dev/null +++ b/shell/ash_test/ash-redir/redirA.right | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | tmp11 | ||
| 2 | tmp11 | ||
diff --git a/shell/ash_test/ash-redir/redirA.tests b/shell/ash_test/ash-redir/redirA.tests new file mode 100755 index 000000000..56833f938 --- /dev/null +++ b/shell/ash_test/ash-redir/redirA.tests | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | x="tmp11:tmp22" | ||
| 2 | |||
| 3 | # Bug was incorrectly expanding variables in >redir | ||
| 4 | echo "${x%:*}" >"${x%:*}" | ||
| 5 | echo tmp1* | ||
| 6 | rm tmp1* | ||
| 7 | |||
| 8 | # Also try unquoted | ||
| 9 | echo "${x%:*}" >${x%:*} | ||
| 10 | echo tmp1* | ||
| 11 | rm tmp1* | ||
