aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
static struct arglist exparg;
/*
- * Our own itoa().
- * cvtnum() is used even if math support is off (to prepare $? values and such).
- */
-static int
-cvtnum(arith_t num)
-{
- int len;
-
- /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
- len = sizeof(arith_t) * 3;
- /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
- if (sizeof(arith_t) < 4) len += 2;
-
- expdest = makestrspace(len, expdest);
- len = fmtstr(expdest, len, ARITH_FMT, num);
- STADJUST(len, expdest);
- return len;
-}
-
-/*
* Break the argument string into pieces based upon IFS and add the
* strings to the argument list. The regions of the string to be
* searched for IFS characters have been stored by recordregion.
@@ -6347,16 +6327,18 @@ preglob(const char *pattern, int flag)
/*
* Put a string on the stack.
*/
-static void
+static size_t
memtodest(const char *p, size_t len, int flags)
{
int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
char *q;
+ char *s;
if (!len)
- return;
+ return 0;
q = makestrspace(len * 2, expdest);
+ s = q;
do {
unsigned char c = *p++;
@@ -6375,6 +6357,7 @@ memtodest(const char *p, size_t len, int flags)
} while (--len);
expdest = q;
+ return q - s;
}
static size_t
@@ -6386,6 +6369,22 @@ strtodest(const char *p, int flags)
}
/*
+ * Our own itoa().
+ * cvtnum() is used even if math support is off (to prepare $? values and such).
+ */
+static int
+cvtnum(arith_t num, int flags)
+{
+ /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
+ /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
+ int len = (sizeof(arith_t) >= 4) ? sizeof(arith_t) * 3 : sizeof(arith_t) * 3 + 2;
+ char buf[len];
+
+ len = fmtstr(buf, len, ARITH_FMT, num);
+ return memtodest(buf, len, flags);
+}
+
+/*
* Record the fact that we have to scan this region of the
* string for IFS characters.
*/
@@ -6683,7 +6682,7 @@ expari(int flag)
if (flag & QUOTES_ESC)
rmescapes(p + 1, 0, NULL);
- len = cvtnum(ash_arith(p + 1));
+ len = cvtnum(ash_arith(p + 1), flag);
if (!(flag & EXP_QUOTED))
recordregion(begoff, begoff + len, 0);
@@ -7328,7 +7327,7 @@ varvalue(char *name, int varflags, int flags, int quoted)
if (num == 0)
return -1;
numvar:
- len = cvtnum(num);
+ len = cvtnum(num, flags);
goto check_1char_name;
case '-':
expdest = makestrspace(NOPTS, expdest);
@@ -7494,7 +7493,7 @@ evalvar(char *p, int flag)
varunset(p, var, 0, 0);
if (subtype == VSLENGTH) {
- cvtnum(varlen > 0 ? varlen : 0);
+ cvtnum(varlen > 0 ? varlen : 0, flag);
goto record;
}
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 @@
+tempfile0.tmp tempfile9.tmp
+tempfile0.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 @@
+>tempfile0.tmp
+>tempfile1.tmp
+>tempfile9.tmp
+# The [...] is interpreted as: "any of the chars 0, -, and 9"
+echo tempfile[0"$((-9))"].tmp
+# The [...] is [0-9], interpreted as: "any digit"
+echo tempfile[0$((-9))].tmp
+rm 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 @@
+tempfile0.tmp tempfile9.tmp
+tempfile0.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 @@
+>tempfile0.tmp
+>tempfile1.tmp
+>tempfile9.tmp
+# The [...] is interpreted as: "any of the chars 0, -, and 9"
+echo tempfile[0"$((-9))"].tmp
+# The [...] is [0-9], interpreted as: "any digit"
+echo tempfile[0$((-9))].tmp
+rm tempfile?.tmp