diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-09-25 20:54:25 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-09-25 20:54:25 +0200 |
commit | 13f20919b2477230063bb940396bef51b463d6df (patch) | |
tree | 0b5f9053840208d92d70a4f6fe13ef2a5cb50604 | |
parent | bcf47eaa1f13dfdcc4564ddb1e5aedce4b3ca2b2 (diff) | |
download | busybox-w32-13f20919b2477230063bb940396bef51b463d6df.tar.gz busybox-w32-13f20919b2477230063bb940396bef51b463d6df.tar.bz2 busybox-w32-13f20919b2477230063bb940396bef51b463d6df.zip |
ash: fix handling of NULs in $'abc\000def\x00asd'. Closes 9286
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 18 | ||||
-rw-r--r-- | shell/ash_test/ash-quoting/dollar_squote_bash2.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-quoting/dollar_squote_bash2.tests | 10 |
3 files changed, 29 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c index 267493708..578b3dc22 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -5651,6 +5651,10 @@ rmescapes(char *str, int flag) | |||
5651 | } | 5651 | } |
5652 | if ((unsigned char)*p == CTLESC) { | 5652 | if ((unsigned char)*p == CTLESC) { |
5653 | p++; | 5653 | p++; |
5654 | #if DEBUG | ||
5655 | if (*p == '\0') | ||
5656 | ash_msg_and_raise_error("CTLESC at EOL (shouldn't happen)"); | ||
5657 | #endif | ||
5654 | if (protect_against_glob) { | 5658 | if (protect_against_glob) { |
5655 | *q++ = '\\'; | 5659 | *q++ = '\\'; |
5656 | } | 5660 | } |
@@ -11302,20 +11306,24 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11302 | USTPUTC(c, out); | 11306 | USTPUTC(c, out); |
11303 | break; | 11307 | break; |
11304 | case CCTL: | 11308 | case CCTL: |
11305 | if (eofmark == NULL || dblquote) | ||
11306 | USTPUTC(CTLESC, out); | ||
11307 | #if ENABLE_ASH_BASH_COMPAT | 11309 | #if ENABLE_ASH_BASH_COMPAT |
11308 | if (c == '\\' && bash_dollar_squote) { | 11310 | if (c == '\\' && bash_dollar_squote) { |
11309 | c = decode_dollar_squote(); | 11311 | c = decode_dollar_squote(); |
11312 | if (c == '\0') { | ||
11313 | /* skip $'\000', $'\x00' (like bash) */ | ||
11314 | break; | ||
11315 | } | ||
11310 | if (c & 0x100) { | 11316 | if (c & 0x100) { |
11311 | USTPUTC('\\', out); | 11317 | /* Unknown escape. Encode as '\z' */ |
11318 | c = (unsigned char)c; | ||
11312 | if (eofmark == NULL || dblquote) | 11319 | if (eofmark == NULL || dblquote) |
11313 | /* Or else this SEGVs: $'\<0x82>' */ | ||
11314 | USTPUTC(CTLESC, out); | 11320 | USTPUTC(CTLESC, out); |
11315 | c = (unsigned char)c; | 11321 | USTPUTC('\\', out); |
11316 | } | 11322 | } |
11317 | } | 11323 | } |
11318 | #endif | 11324 | #endif |
11325 | if (eofmark == NULL || dblquote) | ||
11326 | USTPUTC(CTLESC, out); | ||
11319 | USTPUTC(c, out); | 11327 | USTPUTC(c, out); |
11320 | break; | 11328 | break; |
11321 | case CBACK: /* backslash */ | 11329 | case CBACK: /* backslash */ |
diff --git a/shell/ash_test/ash-quoting/dollar_squote_bash2.right b/shell/ash_test/ash-quoting/dollar_squote_bash2.right new file mode 100644 index 000000000..f7a1731dd --- /dev/null +++ b/shell/ash_test/ash-quoting/dollar_squote_bash2.right | |||
@@ -0,0 +1,6 @@ | |||
1 | strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr | ||
2 | strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr | ||
3 | 80:\ | ||
4 | 81:\ | ||
5 | 82:\ | ||
6 | Done:0 | ||
diff --git a/shell/ash_test/ash-quoting/dollar_squote_bash2.tests b/shell/ash_test/ash-quoting/dollar_squote_bash2.tests new file mode 100755 index 000000000..449772813 --- /dev/null +++ b/shell/ash_test/ash-quoting/dollar_squote_bash2.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Embedded NULs | ||
2 | echo $'str\x00'strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr | ||
3 | echo $'str\000'strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr | ||
4 | |||
5 | # The chars after '\' are hex 0x80,81,82... | ||
6 | echo 80:$'\' | ||
7 | echo 81:$'\' | ||
8 | echo 82:$'\' | ||
9 | |||
10 | echo Done:$? | ||