aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-02-21 16:30:44 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-02-21 16:30:44 +0100
commit45dd87aac05ddf8bbfb110fde85ef875f3adfb65 (patch)
tree2d18a0cc2abd0e15f4163f5dc1ce928739b8097d
parentda2e46dff6576c29fa1d379c943bb7943aa6e7ce (diff)
downloadbusybox-w32-45dd87aac05ddf8bbfb110fde85ef875f3adfb65.tar.gz
busybox-w32-45dd87aac05ddf8bbfb110fde85ef875f3adfb65.tar.bz2
busybox-w32-45dd87aac05ddf8bbfb110fde85ef875f3adfb65.zip
ash: expand: Ensure result is escaped in cvtnum
Upstream commit: Date: Fri, 1 Jun 2018 18:25:29 +0800 expand: Ensure result is escaped in cvtnum The minus sign generated from arithmetic expansion is currently unquoted which causes anomalies when the result is used in where the quoting matters. This patch fixes it by explicitly calling memtodest on the result in cvtnum. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c49
-rw-r--r--shell/ash_test/ash-quoting/negative_arith.right2
-rwxr-xr-xshell/ash_test/ash-quoting/negative_arith.tests8
-rw-r--r--shell/hush_test/hush-quoting/negative_arith.right2
-rwxr-xr-xshell/hush_test/hush-quoting/negative_arith.tests8
5 files changed, 44 insertions, 25 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 8d1822847..005d87ecf 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6071,26 +6071,6 @@ static struct ifsregion *ifslastp;
6071static struct arglist exparg; 6071static struct arglist exparg;
6072 6072
6073/* 6073/*
6074 * Our own itoa().
6075 * cvtnum() is used even if math support is off (to prepare $? values and such).
6076 */
6077static int
6078cvtnum(arith_t num)
6079{
6080 int len;
6081
6082 /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6083 len = sizeof(arith_t) * 3;
6084 /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6085 if (sizeof(arith_t) < 4) len += 2;
6086
6087 expdest = makestrspace(len, expdest);
6088 len = fmtstr(expdest, len, ARITH_FMT, num);
6089 STADJUST(len, expdest);
6090 return len;
6091}
6092
6093/*
6094 * Break the argument string into pieces based upon IFS and add the 6074 * Break the argument string into pieces based upon IFS and add the
6095 * strings to the argument list. The regions of the string to be 6075 * strings to the argument list. The regions of the string to be
6096 * searched for IFS characters have been stored by recordregion. 6076 * searched for IFS characters have been stored by recordregion.
@@ -6347,16 +6327,18 @@ preglob(const char *pattern, int flag)
6347/* 6327/*
6348 * Put a string on the stack. 6328 * Put a string on the stack.
6349 */ 6329 */
6350static void 6330static size_t
6351memtodest(const char *p, size_t len, int flags) 6331memtodest(const char *p, size_t len, int flags)
6352{ 6332{
6353 int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX; 6333 int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6354 char *q; 6334 char *q;
6335 char *s;
6355 6336
6356 if (!len) 6337 if (!len)
6357 return; 6338 return 0;
6358 6339
6359 q = makestrspace(len * 2, expdest); 6340 q = makestrspace(len * 2, expdest);
6341 s = q;
6360 6342
6361 do { 6343 do {
6362 unsigned char c = *p++; 6344 unsigned char c = *p++;
@@ -6375,6 +6357,7 @@ memtodest(const char *p, size_t len, int flags)
6375 } while (--len); 6357 } while (--len);
6376 6358
6377 expdest = q; 6359 expdest = q;
6360 return q - s;
6378} 6361}
6379 6362
6380static size_t 6363static size_t
@@ -6386,6 +6369,22 @@ strtodest(const char *p, int flags)
6386} 6369}
6387 6370
6388/* 6371/*
6372 * Our own itoa().
6373 * cvtnum() is used even if math support is off (to prepare $? values and such).
6374 */
6375static int
6376cvtnum(arith_t num, int flags)
6377{
6378 /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6379 /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6380 int len = (sizeof(arith_t) >= 4) ? sizeof(arith_t) * 3 : sizeof(arith_t) * 3 + 2;
6381 char buf[len];
6382
6383 len = fmtstr(buf, len, ARITH_FMT, num);
6384 return memtodest(buf, len, flags);
6385}
6386
6387/*
6389 * Record the fact that we have to scan this region of the 6388 * Record the fact that we have to scan this region of the
6390 * string for IFS characters. 6389 * string for IFS characters.
6391 */ 6390 */
@@ -6683,7 +6682,7 @@ expari(int flag)
6683 if (flag & QUOTES_ESC) 6682 if (flag & QUOTES_ESC)
6684 rmescapes(p + 1, 0, NULL); 6683 rmescapes(p + 1, 0, NULL);
6685 6684
6686 len = cvtnum(ash_arith(p + 1)); 6685 len = cvtnum(ash_arith(p + 1), flag);
6687 6686
6688 if (!(flag & EXP_QUOTED)) 6687 if (!(flag & EXP_QUOTED))
6689 recordregion(begoff, begoff + len, 0); 6688 recordregion(begoff, begoff + len, 0);
@@ -7328,7 +7327,7 @@ varvalue(char *name, int varflags, int flags, int quoted)
7328 if (num == 0) 7327 if (num == 0)
7329 return -1; 7328 return -1;
7330 numvar: 7329 numvar:
7331 len = cvtnum(num); 7330 len = cvtnum(num, flags);
7332 goto check_1char_name; 7331 goto check_1char_name;
7333 case '-': 7332 case '-':
7334 expdest = makestrspace(NOPTS, expdest); 7333 expdest = makestrspace(NOPTS, expdest);
@@ -7494,7 +7493,7 @@ evalvar(char *p, int flag)
7494 varunset(p, var, 0, 0); 7493 varunset(p, var, 0, 0);
7495 7494
7496 if (subtype == VSLENGTH) { 7495 if (subtype == VSLENGTH) {
7497 cvtnum(varlen > 0 ? varlen : 0); 7496 cvtnum(varlen > 0 ? varlen : 0, flag);
7498 goto record; 7497 goto record;
7499 } 7498 }
7500 7499
diff --git a/shell/ash_test/ash-quoting/negative_arith.right b/shell/ash_test/ash-quoting/negative_arith.right
new file mode 100644
index 000000000..e7e51eee7
--- /dev/null
+++ b/shell/ash_test/ash-quoting/negative_arith.right
@@ -0,0 +1,2 @@
1tempfile0.tmp tempfile9.tmp
2tempfile0.tmp tempfile1.tmp tempfile9.tmp
diff --git a/shell/ash_test/ash-quoting/negative_arith.tests b/shell/ash_test/ash-quoting/negative_arith.tests
new file mode 100755
index 000000000..8e47ca111
--- /dev/null
+++ b/shell/ash_test/ash-quoting/negative_arith.tests
@@ -0,0 +1,8 @@
1>tempfile0.tmp
2>tempfile1.tmp
3>tempfile9.tmp
4# The [...] is interpreted as: "any of the chars 0, -, and 9"
5echo tempfile[0"$((-9))"].tmp
6# The [...] is [0-9], interpreted as: "any digit"
7echo tempfile[0$((-9))].tmp
8rm tempfile?.tmp
diff --git a/shell/hush_test/hush-quoting/negative_arith.right b/shell/hush_test/hush-quoting/negative_arith.right
new file mode 100644
index 000000000..e7e51eee7
--- /dev/null
+++ b/shell/hush_test/hush-quoting/negative_arith.right
@@ -0,0 +1,2 @@
1tempfile0.tmp tempfile9.tmp
2tempfile0.tmp tempfile1.tmp tempfile9.tmp
diff --git a/shell/hush_test/hush-quoting/negative_arith.tests b/shell/hush_test/hush-quoting/negative_arith.tests
new file mode 100755
index 000000000..8e47ca111
--- /dev/null
+++ b/shell/hush_test/hush-quoting/negative_arith.tests
@@ -0,0 +1,8 @@
1>tempfile0.tmp
2>tempfile1.tmp
3>tempfile9.tmp
4# The [...] is interpreted as: "any of the chars 0, -, and 9"
5echo tempfile[0"$((-9))"].tmp
6# The [...] is [0-9], interpreted as: "any digit"
7echo tempfile[0$((-9))].tmp
8rm tempfile?.tmp