diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-13 14:43:29 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-13 14:44:11 +0100 |
commit | 8de5b9f88ba9fe2f203abab9ca7d85129c3eb679 (patch) | |
tree | ddadeda2afcfaa0560fc697bbb5d884ee0363ec0 | |
parent | 3459024bf404af814cacfe90a0deb719e282ae62 (diff) | |
download | busybox-w32-8de5b9f88ba9fe2f203abab9ca7d85129c3eb679.tar.gz busybox-w32-8de5b9f88ba9fe2f203abab9ca7d85129c3eb679.tar.bz2 busybox-w32-8de5b9f88ba9fe2f203abab9ca7d85129c3eb679.zip |
ash : fix double-quoted "\z" handling
function old new delta
readtoken1 2602 2608 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 23 | ||||
-rw-r--r-- | shell/ash_test/ash-quoting/bkslash_case1.right | 10 | ||||
-rwxr-xr-x | shell/ash_test/ash-quoting/bkslash_case1.tests | 38 | ||||
-rw-r--r-- | shell/hush_test/hush-quoting/bkslash_case1.right | 10 | ||||
-rwxr-xr-x | shell/hush_test/hush-quoting/bkslash_case1.tests | 38 |
5 files changed, 113 insertions, 6 deletions
diff --git a/shell/ash.c b/shell/ash.c index 4c1b5e409..5e281b5ce 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6146,12 +6146,12 @@ rmescapes(char *str, int flag, int *slash_position) | |||
6146 | if (*p == '*' | 6146 | if (*p == '*' |
6147 | || *p == '?' | 6147 | || *p == '?' |
6148 | || *p == '[' | 6148 | || *p == '[' |
6149 | || *p == '\\' /* case '\' in \\ ) echo ok;; *) echo WRONG;; esac */ | 6149 | || *p == '\\' /* case '\' in \\ ) echo ok;; *) echo WRONG;; esac */ |
6150 | || *p == ']' /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */ | 6150 | || *p == ']' /* case ']' in [a\]] ) echo ok;; *) echo WRONG;; esac */ |
6151 | || *p == '-' /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */ | 6151 | || *p == '-' /* case '-' in [a\-c]) echo ok;; *) echo WRONG;; esac */ |
6152 | || *p == '!' /* case '!' in [\!] ) echo ok;; *) echo WRONG;; esac */ | 6152 | || *p == '!' /* case '!' in [\!] ) echo ok;; *) echo WRONG;; esac */ |
6153 | /* Some libc support [^negate], that's why "^" also needs love */ | 6153 | /* Some libc support [^negate], that's why "^" also needs love */ |
6154 | || *p == '^' /* case '^' in [\^] ) echo ok;; *) echo WRONG;; esac */ | 6154 | || *p == '^' /* case '^' in [\^] ) echo ok;; *) echo WRONG;; esac */ |
6155 | ) { | 6155 | ) { |
6156 | *q++ = '\\'; | 6156 | *q++ = '\\'; |
6157 | } | 6157 | } |
@@ -11992,13 +11992,24 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11992 | USTPUTC(CTLESC, out); | 11992 | USTPUTC(CTLESC, out); |
11993 | USTPUTC('\\', out); | 11993 | USTPUTC('\\', out); |
11994 | } | 11994 | } |
11995 | /* Backslash is retained if we are in "str" and next char isn't special */ | 11995 | /* Backslash is retained if we are in "str" |
11996 | * and next char isn't dquote-special. | ||
11997 | */ | ||
11996 | if (dblquote | 11998 | if (dblquote |
11997 | && c != '\\' | 11999 | && c != '\\' |
11998 | && c != '`' | 12000 | && c != '`' |
11999 | && c != '$' | 12001 | && c != '$' |
12000 | && (c != '"' || eofmark != NULL) | 12002 | && (c != '"' || eofmark != NULL) |
12001 | ) { | 12003 | ) { |
12004 | //dash survives not doing USTPUTC(CTLESC), but merely by chance: | ||
12005 | //Example: "\z" gets encoded as "\<CTLESC>z". | ||
12006 | //rmescapes() then emits "\", "\z", protecting z from globbing. | ||
12007 | //But it's wrong, should protect _both_ from globbing: | ||
12008 | //everything in double quotes is not globbed. | ||
12009 | //Unlike dash, we have a fix in rmescapes() which emits bare "z" | ||
12010 | //for "<CTLESC>z" since "z" is not glob-special (else unicode may break), | ||
12011 | //and glob would see "\z" and eat "\". Thus: | ||
12012 | USTPUTC(CTLESC, out); /* protect '\' from glob */ | ||
12002 | USTPUTC('\\', out); | 12013 | USTPUTC('\\', out); |
12003 | } | 12014 | } |
12004 | USTPUTC(CTLESC, out); | 12015 | USTPUTC(CTLESC, out); |
diff --git a/shell/ash_test/ash-quoting/bkslash_case1.right b/shell/ash_test/ash-quoting/bkslash_case1.right new file mode 100644 index 000000000..1b52491f7 --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_case1.right | |||
@@ -0,0 +1,10 @@ | |||
1 | ok1 | ||
2 | ok2 | ||
3 | ok3 | ||
4 | ok4 | ||
5 | ok5 | ||
6 | Ok:0 | ||
7 | ok6 | ||
8 | ok7 | ||
9 | ok8 | ||
10 | Ok:0 | ||
diff --git a/shell/ash_test/ash-quoting/bkslash_case1.tests b/shell/ash_test/ash-quoting/bkslash_case1.tests new file mode 100755 index 000000000..d0c359927 --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_case1.tests | |||
@@ -0,0 +1,38 @@ | |||
1 | # Case argument is globbed, match patterns are not. | ||
2 | # This caught some bugs in the past. | ||
3 | |||
4 | case z in | ||
5 | \z ) echo ok1 ;; | ||
6 | * ) echo BUG ;; | ||
7 | esac | ||
8 | case \z in | ||
9 | z ) echo ok2 ;; | ||
10 | * ) echo BUG ;; | ||
11 | esac | ||
12 | case \z in | ||
13 | \z ) echo ok3 ;; | ||
14 | * ) echo BUG ;; | ||
15 | esac | ||
16 | case z in | ||
17 | \z ) echo ok4 ;; | ||
18 | * ) echo BUG ;; | ||
19 | esac | ||
20 | case \\z in | ||
21 | \\z ) echo ok5 ;; | ||
22 | * ) echo BUG ;; | ||
23 | esac | ||
24 | echo Ok:$? | ||
25 | |||
26 | case "\z" in | ||
27 | "\z" ) echo ok6 ;; | ||
28 | * ) echo BUG ;; | ||
29 | esac | ||
30 | case "\\z" in | ||
31 | "\\z" ) echo ok7 ;; | ||
32 | * ) echo BUG ;; | ||
33 | esac | ||
34 | case "\\\z" in | ||
35 | "\\\z") echo ok8 ;; | ||
36 | * ) echo BUG ;; | ||
37 | esac | ||
38 | echo Ok:$? | ||
diff --git a/shell/hush_test/hush-quoting/bkslash_case1.right b/shell/hush_test/hush-quoting/bkslash_case1.right new file mode 100644 index 000000000..1b52491f7 --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_case1.right | |||
@@ -0,0 +1,10 @@ | |||
1 | ok1 | ||
2 | ok2 | ||
3 | ok3 | ||
4 | ok4 | ||
5 | ok5 | ||
6 | Ok:0 | ||
7 | ok6 | ||
8 | ok7 | ||
9 | ok8 | ||
10 | Ok:0 | ||
diff --git a/shell/hush_test/hush-quoting/bkslash_case1.tests b/shell/hush_test/hush-quoting/bkslash_case1.tests new file mode 100755 index 000000000..d0c359927 --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_case1.tests | |||
@@ -0,0 +1,38 @@ | |||
1 | # Case argument is globbed, match patterns are not. | ||
2 | # This caught some bugs in the past. | ||
3 | |||
4 | case z in | ||
5 | \z ) echo ok1 ;; | ||
6 | * ) echo BUG ;; | ||
7 | esac | ||
8 | case \z in | ||
9 | z ) echo ok2 ;; | ||
10 | * ) echo BUG ;; | ||
11 | esac | ||
12 | case \z in | ||
13 | \z ) echo ok3 ;; | ||
14 | * ) echo BUG ;; | ||
15 | esac | ||
16 | case z in | ||
17 | \z ) echo ok4 ;; | ||
18 | * ) echo BUG ;; | ||
19 | esac | ||
20 | case \\z in | ||
21 | \\z ) echo ok5 ;; | ||
22 | * ) echo BUG ;; | ||
23 | esac | ||
24 | echo Ok:$? | ||
25 | |||
26 | case "\z" in | ||
27 | "\z" ) echo ok6 ;; | ||
28 | * ) echo BUG ;; | ||
29 | esac | ||
30 | case "\\z" in | ||
31 | "\\z" ) echo ok7 ;; | ||
32 | * ) echo BUG ;; | ||
33 | esac | ||
34 | case "\\\z" in | ||
35 | "\\\z") echo ok8 ;; | ||
36 | * ) echo BUG ;; | ||
37 | esac | ||
38 | echo Ok:$? | ||