aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-02-22 19:38:40 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-02-24 19:20:51 +0100
commit1555895b4af44ce47fe2365aec82e8e67c685f08 (patch)
treebd821be779bc1d489ac966b0d83e4a5e026979dd /shell
parent823318822ccb0e0910abbd4e1f983637dfd9d3c0 (diff)
downloadbusybox-w32-1555895b4af44ce47fe2365aec82e8e67c685f08.tar.gz
busybox-w32-1555895b4af44ce47fe2365aec82e8e67c685f08.tar.bz2
busybox-w32-1555895b4af44ce47fe2365aec82e8e67c685f08.zip
ash: expand: Fix multiple issues with EXP_DISCARD in evalvar
Upstream commit: Date: Wed, 12 Sep 2018 14:27:16 +0800 expand: Fix multiple issues with EXP_DISCARD in evalvar The commit 3cd538634f71538370f5af239f342aec48b7470b broke parameter expansion in multiple ways because the EXP_DISCARD flag wasn't set or tested for various cases: $ src/dash -c 'var=; echo ${var:+nonempty}' nonempty $ src/dash -u -c 'unset foo bar; echo ${foo+${bar}}' dash: 1: bar: parameter not set $ src/dash -c 'foo=bar; echo ${foo=BUG}; echo $foo' barBUG bar $ This patch fixes them by introducing a new discard variable that tracks whether the extra word should be discarded or not when it is parsed. Reported-by: Martijn Dekker <martijn@inlv.org> Fixes: 3cd538634f71 ("expand: Do not reprocess data when...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 425da6bb6..d0d99f60e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -7454,6 +7454,7 @@ evalvar(char *p, int flag)
7454 int patloc; 7454 int patloc;
7455 int startloc; 7455 int startloc;
7456 ssize_t varlen; 7456 ssize_t varlen;
7457 int discard;
7457 int quoted; 7458 int quoted;
7458 7459
7459 varflags = (unsigned char) *p++; 7460 varflags = (unsigned char) *p++;
@@ -7469,33 +7470,31 @@ evalvar(char *p, int flag)
7469 if (varflags & VSNUL) 7470 if (varflags & VSNUL)
7470 varlen--; 7471 varlen--;
7471 7472
7473 discard = varlen < 0 ? EXP_DISCARD : 0;
7474
7472 switch (subtype) { 7475 switch (subtype) {
7473 case VSPLUS: 7476 case VSPLUS:
7474 varlen = -1 - varlen; 7477 discard ^= EXP_DISCARD;
7475 /* fall through */ 7478 /* fall through */
7476 case 0: 7479 case 0:
7477 case VSMINUS: 7480 case VSMINUS:
7478 p = argstr(p, flag | EXP_TILDE | EXP_WORD); 7481 p = argstr(p, flag | EXP_TILDE | EXP_WORD | (discard ^ EXP_DISCARD));
7479 if (varlen < 0)
7480 return p;
7481 goto record; 7482 goto record;
7482 7483
7483 case VSASSIGN: 7484 case VSASSIGN:
7484 case VSQUESTION: 7485 case VSQUESTION:
7485 if (varlen >= 0)
7486 goto record;
7487
7488 p = subevalvar(p, var, 0, startloc, varflags, 7486 p = subevalvar(p, var, 0, startloc, varflags,
7489 flag & ~QUOTES_ESC); 7487 (flag & ~QUOTES_ESC) | (discard ^ EXP_DISCARD));
7490 7488
7491 if (flag & EXP_DISCARD) 7489 if ((flag | ~discard) & EXP_DISCARD)
7492 return p; 7490 goto record;
7493 7491
7494 varflags &= ~VSNUL; 7492 varflags &= ~VSNUL;
7493 subtype = VSNORMAL;
7495 goto again; 7494 goto again;
7496 } 7495 }
7497 7496
7498 if (varlen < 0 && uflag) 7497 if ((discard & ~flag) && uflag)
7499 varunset(p, var, 0, 0); 7498 varunset(p, var, 0, 0);
7500 7499
7501 if (subtype == VSLENGTH) { 7500 if (subtype == VSLENGTH) {
@@ -7503,7 +7502,7 @@ evalvar(char *p, int flag)
7503 if (flag & EXP_DISCARD) 7502 if (flag & EXP_DISCARD)
7504 return p; 7503 return p;
7505 cvtnum(varlen > 0 ? varlen : 0, flag); 7504 cvtnum(varlen > 0 ? varlen : 0, flag);
7506 goto record; 7505 goto really_record;
7507 } 7506 }
7508 7507
7509 if (subtype == VSNORMAL) 7508 if (subtype == VSNORMAL)
@@ -7528,7 +7527,7 @@ evalvar(char *p, int flag)
7528 } 7527 }
7529#endif 7528#endif
7530 7529
7531 flag |= varlen < 0 ? EXP_DISCARD : 0; 7530 flag |= discard;
7532 if (!(flag & EXP_DISCARD)) { 7531 if (!(flag & EXP_DISCARD)) {
7533 /* 7532 /*
7534 * Terminate the string and start recording the pattern 7533 * Terminate the string and start recording the pattern
@@ -7541,9 +7540,10 @@ evalvar(char *p, int flag)
7541 p = subevalvar(p, NULL, patloc, startloc, varflags, flag); 7540 p = subevalvar(p, NULL, patloc, startloc, varflags, flag);
7542 7541
7543 record: 7542 record:
7544 if (flag & EXP_DISCARD) 7543 if ((flag | discard) & EXP_DISCARD)
7545 return p; 7544 return p;
7546 7545
7546 really_record:
7547 if (quoted) { 7547 if (quoted) {
7548 quoted = *var == '@' && shellparam.nparam; 7548 quoted = *var == '@' && shellparam.nparam;
7549 if (!quoted) 7549 if (!quoted)