aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-09-05 04:06:06 -0500
committerRob Landley <rob@landley.net>2020-09-05 04:06:06 -0500
commita7fe8d598ce8f4b0163ba72609aaa2c66f6a4315 (patch)
treee9ce229cfdff42d57f0cc632aacc86ff3a20e4fd /toys
parent1ff35e6c508fc605fd4268d479e5473f50debb67 (diff)
downloadtoybox-a7fe8d598ce8f4b0163ba72609aaa2c66f6a4315.tar.gz
Fix segfault for sh -c 'echo {a..Z}'
Bash produces different output for that test, but I'm not sure I care? http://lists.landley.net/pipermail/toybox-landley.net/2020-September/011990.html The problem is parse_word() guarantees its output's quotes/escapes are completed, but brace expansion happens after parse_word() and thus violating assumptions later code depends on to not do redundant error checking. The easy fix is to escape punctuation produced by parse_word (which in bash can only happen when you span upper and lower case ranges so "\" is the only interesting character). I could special case this to match bash exactly, but I'm waiting for someone to complain instead.
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/sh.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/toys/pending/sh.c b/toys/pending/sh.c
index 797b96a3..4c3735d7 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -1417,10 +1417,10 @@ static int expand_arg(struct sh_arg *arg, char *old, unsigned flags,
if (!bnext || bb->cnt<0 || bnext->commas[0]>bb->commas[bb->idx+1]) {
// output uninterrupted span
- if (bb->cnt<0)
- s += sprintf(s, (bb->cnt==-1) ? "%c" : "%d",
- bb->commas[2]+bb->commas[4]*bb->idx);
- else {
+ if (bb->cnt<0) {
+ k = bb->commas[2]+bb->commas[4]*bb->idx;
+ s += sprintf(s, (bb->cnt==-1) ? "\\%c"+!ispunct(k) : "%d", k);
+ } else {
i = bb->commas[bstk->idx]+1;
s = stpncpy(s, old+i, bb->commas[bb->idx+1]-i);
}