diff options
author | Ron Yorston <rmy@pobox.com> | 2018-03-15 08:49:48 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-03-15 08:49:48 +0000 |
commit | 6fe4ad9a6c96624c2b75c0d51b035bc1a71d9eba (patch) | |
tree | bb7620a3217f5adf6fb5f3358b2b89a97331b5e8 /shell | |
parent | f3d24e08a385a68c4bacb284bd8a8e3da7f0f4b3 (diff) | |
parent | bbe47d9b9aee3824845f1ce08c9caeb262c15059 (diff) | |
download | busybox-w32-6fe4ad9a6c96624c2b75c0d51b035bc1a71d9eba.tar.gz busybox-w32-6fe4ad9a6c96624c2b75c0d51b035bc1a71d9eba.tar.bz2 busybox-w32-6fe4ad9a6c96624c2b75c0d51b035bc1a71d9eba.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
22 files changed, 137 insertions, 11 deletions
diff --git a/shell/ash_test/ash-quoting/bkslash_in_varexp.right b/shell/ash_test/ash-quoting/bkslash_in_varexp.right new file mode 100644 index 000000000..d03047024 --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_in_varexp.right | |||
@@ -0,0 +1,5 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Nothing: | ||
4 | Nothing: | ||
5 | Ok:0 | ||
diff --git a/shell/ash_test/ash-quoting/bkslash_in_varexp.tests b/shell/ash_test/ash-quoting/bkslash_in_varexp.tests new file mode 100755 index 000000000..6c7b4b0cc --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_in_varexp.tests | |||
@@ -0,0 +1,16 @@ | |||
1 | x='a]' | ||
2 | # | ||
3 | # \] is not a valid escape for ] in set glob expression. | ||
4 | # Glob sets have no escaping at all: | ||
5 | # ] can be in a set if it is the first char: []abc], | ||
6 | # dash can be in a set if it is first or last: [abc-], | ||
7 | # [ and \ need no protections at all: [a[b\c] is a valid set of 5 chars. | ||
8 | # | ||
9 | # bash-4.3.43 misinterprets [a\]] as "set of 'a' or ']'". | ||
10 | # Correct interpretation is "set of 'a' or '\', followed by ']'". | ||
11 | # | ||
12 | echo Nothing:${x#[a\]]} | ||
13 | echo Nothing:"${x#[a\]]}" | ||
14 | echo Nothing:${x%[a\]]} | ||
15 | echo Nothing:"${x%[a\]]}" | ||
16 | echo Ok:$? | ||
diff --git a/shell/ash_test/ash-quoting/bkslash_in_varexp1.right b/shell/ash_test/ash-quoting/bkslash_in_varexp1.right new file mode 100644 index 000000000..d03047024 --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_in_varexp1.right | |||
@@ -0,0 +1,5 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Nothing: | ||
4 | Nothing: | ||
5 | Ok:0 | ||
diff --git a/shell/ash_test/ash-quoting/bkslash_in_varexp1.tests b/shell/ash_test/ash-quoting/bkslash_in_varexp1.tests new file mode 100755 index 000000000..3c817eae1 --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_in_varexp1.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | x=a | ||
2 | echo Nothing:${x#[]a]} | ||
3 | echo Nothing:"${x#[]a]}" | ||
4 | echo Nothing:${x%[]a]} | ||
5 | echo Nothing:"${x%[]a]}" | ||
6 | echo Ok:$? | ||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp.right b/shell/ash_test/ash-quoting/squote_in_varexp.right new file mode 100644 index 000000000..a75c0bfd6 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp.right | |||
@@ -0,0 +1,5 @@ | |||
1 | z | ||
2 | z | ||
3 | y | ||
4 | y | ||
5 | Ok:0 | ||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp.tests b/shell/ash_test/ash-quoting/squote_in_varexp.tests new file mode 100755 index 000000000..a2d05a246 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | x=yz | ||
2 | echo ${x#'y'} | ||
3 | echo "${x#'y'}" | ||
4 | echo ${x%'z'} | ||
5 | echo "${x%'z'}" | ||
6 | echo Ok:$? | ||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp1.right b/shell/ash_test/ash-quoting/squote_in_varexp1.right new file mode 100644 index 000000000..9d0add3c5 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp1.right | |||
@@ -0,0 +1,3 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Ok:0 | ||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp1.tests b/shell/ash_test/ash-quoting/squote_in_varexp1.tests new file mode 100755 index 000000000..efb380db3 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp1.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | x='\\\\' | ||
2 | printf Nothing:'%s\n' ${x#\\\\\\\\} | ||
3 | printf Nothing:'%s\n' "${x#\\\\\\\\}" | ||
4 | echo Ok:$? | ||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp2.right b/shell/ash_test/ash-quoting/squote_in_varexp2.right new file mode 100644 index 000000000..9d0add3c5 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp2.right | |||
@@ -0,0 +1,3 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Ok:0 | ||
diff --git a/shell/ash_test/ash-quoting/squote_in_varexp2.tests b/shell/ash_test/ash-quoting/squote_in_varexp2.tests new file mode 100755 index 000000000..806ad12b9 --- /dev/null +++ b/shell/ash_test/ash-quoting/squote_in_varexp2.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | x='\\\\' | ||
2 | printf Nothing:'%s\n' ${x#'\\\\'} | ||
3 | printf Nothing:'%s\n' "${x#'\\\\'}" | ||
4 | echo Ok:$? | ||
diff --git a/shell/hush.c b/shell/hush.c index e005b0a20..6e64efb70 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -4488,7 +4488,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4488 | } | 4488 | } |
4489 | if (ch == end_ch | 4489 | if (ch == end_ch |
4490 | # if BASH_SUBSTR || BASH_PATTERN_SUBST | 4490 | # if BASH_SUBSTR || BASH_PATTERN_SUBST |
4491 | || ch == end_char2 | 4491 | || ch == end_char2 |
4492 | # endif | 4492 | # endif |
4493 | ) { | 4493 | ) { |
4494 | if (!dbl) | 4494 | if (!dbl) |
@@ -4500,6 +4500,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4500 | } | 4500 | } |
4501 | } | 4501 | } |
4502 | o_addchr(dest, ch); | 4502 | o_addchr(dest, ch); |
4503 | //bb_error_msg("%s:o_addchr('%c')", __func__, ch); | ||
4503 | if (ch == '(' || ch == '{') { | 4504 | if (ch == '(' || ch == '{') { |
4504 | ch = (ch == '(' ? ')' : '}'); | 4505 | ch = (ch == '(' ? ')' : '}'); |
4505 | if (!add_till_closing_bracket(dest, input, ch)) | 4506 | if (!add_till_closing_bracket(dest, input, ch)) |
@@ -4529,7 +4530,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4529 | /* \x. Copy verbatim. Important for \(, \) */ | 4530 | /* \x. Copy verbatim. Important for \(, \) */ |
4530 | ch = i_getch(input); | 4531 | ch = i_getch(input); |
4531 | if (ch == EOF) { | 4532 | if (ch == EOF) { |
4532 | syntax_error_unterm_ch(')'); | 4533 | syntax_error_unterm_ch(end_ch); |
4533 | return 0; | 4534 | return 0; |
4534 | } | 4535 | } |
4535 | #if 0 | 4536 | #if 0 |
@@ -4540,6 +4541,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4540 | } | 4541 | } |
4541 | #endif | 4542 | #endif |
4542 | o_addchr(dest, ch); | 4543 | o_addchr(dest, ch); |
4544 | //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch); | ||
4543 | continue; | 4545 | continue; |
4544 | } | 4546 | } |
4545 | } | 4547 | } |
@@ -5842,17 +5844,24 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5842 | unsigned scan_flags = pick_scan(exp_op, *exp_word); | 5844 | unsigned scan_flags = pick_scan(exp_op, *exp_word); |
5843 | if (exp_op == *exp_word) /* ## or %% */ | 5845 | if (exp_op == *exp_word) /* ## or %% */ |
5844 | exp_word++; | 5846 | exp_word++; |
5845 | exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 1, /*unbackslash:*/ 1); | 5847 | debug_printf_expand("expand: exp_word:'%s'\n", exp_word); |
5848 | /* | ||
5849 | * process_bkslash:1 unbackslash:1 breaks this: | ||
5850 | * a='a\\'; echo ${a%\\\\} # correct output is: a | ||
5851 | * process_bkslash:1 unbackslash:0 breaks this: | ||
5852 | * a='a}'; echo ${a%\}} # correct output is: a | ||
5853 | */ | ||
5854 | exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 0, /*unbackslash:*/ 0); | ||
5846 | if (exp_exp_word) | 5855 | if (exp_exp_word) |
5847 | exp_word = exp_exp_word; | 5856 | exp_word = exp_exp_word; |
5857 | debug_printf_expand("expand: exp_exp_word:'%s'\n", exp_word); | ||
5848 | /* HACK ALERT. We depend here on the fact that | 5858 | /* HACK ALERT. We depend here on the fact that |
5849 | * G.global_argv and results of utoa and get_local_var_value | 5859 | * G.global_argv and results of utoa and get_local_var_value |
5850 | * are actually in writable memory: | 5860 | * are actually in writable memory: |
5851 | * scan_and_match momentarily stores NULs there. */ | 5861 | * scan_and_match momentarily stores NULs there. */ |
5852 | t = (char*)val; | 5862 | t = (char*)val; |
5853 | loc = scan_and_match(t, exp_word, scan_flags); | 5863 | loc = scan_and_match(t, exp_word, scan_flags); |
5854 | //bb_error_msg("op:%c str:'%s' pat:'%s' res:'%s'", | 5864 | debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc); |
5855 | // exp_op, t, exp_word, loc); | ||
5856 | free(exp_exp_word); | 5865 | free(exp_exp_word); |
5857 | if (loc) { /* match was found */ | 5866 | if (loc) { /* match was found */ |
5858 | if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */ | 5867 | if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */ |
@@ -7172,21 +7181,22 @@ static const struct built_in_command *find_builtin(const char *name) | |||
7172 | #if ENABLE_HUSH_FUNCTIONS | 7181 | #if ENABLE_HUSH_FUNCTIONS |
7173 | static struct function **find_function_slot(const char *name) | 7182 | static struct function **find_function_slot(const char *name) |
7174 | { | 7183 | { |
7184 | struct function *funcp; | ||
7175 | struct function **funcpp = &G.top_func; | 7185 | struct function **funcpp = &G.top_func; |
7176 | while (*funcpp) { | 7186 | |
7177 | if (strcmp(name, (*funcpp)->name) == 0) { | 7187 | while ((funcp = *funcpp) != NULL) { |
7188 | if (strcmp(name, funcp->name) == 0) { | ||
7189 | debug_printf_exec("found function '%s'\n", name); | ||
7178 | break; | 7190 | break; |
7179 | } | 7191 | } |
7180 | funcpp = &(*funcpp)->next; | 7192 | funcpp = &funcp->next; |
7181 | } | 7193 | } |
7182 | return funcpp; | 7194 | return funcpp; |
7183 | } | 7195 | } |
7184 | 7196 | ||
7185 | static const struct function *find_function(const char *name) | 7197 | static ALWAYS_INLINE const struct function *find_function(const char *name) |
7186 | { | 7198 | { |
7187 | const struct function *funcp = *find_function_slot(name); | 7199 | const struct function *funcp = *find_function_slot(name); |
7188 | if (funcp) | ||
7189 | debug_printf_exec("found function '%s'\n", name); | ||
7190 | return funcp; | 7200 | return funcp; |
7191 | } | 7201 | } |
7192 | 7202 | ||
diff --git a/shell/hush_test/hush-quoting/bkslash_in_varexp.right b/shell/hush_test/hush-quoting/bkslash_in_varexp.right new file mode 100644 index 000000000..d03047024 --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_in_varexp.right | |||
@@ -0,0 +1,5 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Nothing: | ||
4 | Nothing: | ||
5 | Ok:0 | ||
diff --git a/shell/hush_test/hush-quoting/bkslash_in_varexp.tests b/shell/hush_test/hush-quoting/bkslash_in_varexp.tests new file mode 100755 index 000000000..6c7b4b0cc --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_in_varexp.tests | |||
@@ -0,0 +1,16 @@ | |||
1 | x='a]' | ||
2 | # | ||
3 | # \] is not a valid escape for ] in set glob expression. | ||
4 | # Glob sets have no escaping at all: | ||
5 | # ] can be in a set if it is the first char: []abc], | ||
6 | # dash can be in a set if it is first or last: [abc-], | ||
7 | # [ and \ need no protections at all: [a[b\c] is a valid set of 5 chars. | ||
8 | # | ||
9 | # bash-4.3.43 misinterprets [a\]] as "set of 'a' or ']'". | ||
10 | # Correct interpretation is "set of 'a' or '\', followed by ']'". | ||
11 | # | ||
12 | echo Nothing:${x#[a\]]} | ||
13 | echo Nothing:"${x#[a\]]}" | ||
14 | echo Nothing:${x%[a\]]} | ||
15 | echo Nothing:"${x%[a\]]}" | ||
16 | echo Ok:$? | ||
diff --git a/shell/hush_test/hush-quoting/bkslash_in_varexp1.right b/shell/hush_test/hush-quoting/bkslash_in_varexp1.right new file mode 100644 index 000000000..d03047024 --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_in_varexp1.right | |||
@@ -0,0 +1,5 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Nothing: | ||
4 | Nothing: | ||
5 | Ok:0 | ||
diff --git a/shell/hush_test/hush-quoting/bkslash_in_varexp1.tests b/shell/hush_test/hush-quoting/bkslash_in_varexp1.tests new file mode 100755 index 000000000..3c817eae1 --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_in_varexp1.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | x=a | ||
2 | echo Nothing:${x#[]a]} | ||
3 | echo Nothing:"${x#[]a]}" | ||
4 | echo Nothing:${x%[]a]} | ||
5 | echo Nothing:"${x%[]a]}" | ||
6 | echo Ok:$? | ||
diff --git a/shell/hush_test/hush-quoting/squote_in_varexp.right b/shell/hush_test/hush-quoting/squote_in_varexp.right new file mode 100644 index 000000000..a75c0bfd6 --- /dev/null +++ b/shell/hush_test/hush-quoting/squote_in_varexp.right | |||
@@ -0,0 +1,5 @@ | |||
1 | z | ||
2 | z | ||
3 | y | ||
4 | y | ||
5 | Ok:0 | ||
diff --git a/shell/hush_test/hush-quoting/squote_in_varexp.tests b/shell/hush_test/hush-quoting/squote_in_varexp.tests new file mode 100755 index 000000000..a2d05a246 --- /dev/null +++ b/shell/hush_test/hush-quoting/squote_in_varexp.tests | |||
@@ -0,0 +1,6 @@ | |||
1 | x=yz | ||
2 | echo ${x#'y'} | ||
3 | echo "${x#'y'}" | ||
4 | echo ${x%'z'} | ||
5 | echo "${x%'z'}" | ||
6 | echo Ok:$? | ||
diff --git a/shell/hush_test/hush-quoting/squote_in_varexp1.right b/shell/hush_test/hush-quoting/squote_in_varexp1.right new file mode 100644 index 000000000..9d0add3c5 --- /dev/null +++ b/shell/hush_test/hush-quoting/squote_in_varexp1.right | |||
@@ -0,0 +1,3 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Ok:0 | ||
diff --git a/shell/hush_test/hush-quoting/squote_in_varexp1.tests b/shell/hush_test/hush-quoting/squote_in_varexp1.tests new file mode 100755 index 000000000..efb380db3 --- /dev/null +++ b/shell/hush_test/hush-quoting/squote_in_varexp1.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | x='\\\\' | ||
2 | printf Nothing:'%s\n' ${x#\\\\\\\\} | ||
3 | printf Nothing:'%s\n' "${x#\\\\\\\\}" | ||
4 | echo Ok:$? | ||
diff --git a/shell/hush_test/hush-quoting/squote_in_varexp2.right b/shell/hush_test/hush-quoting/squote_in_varexp2.right new file mode 100644 index 000000000..9d0add3c5 --- /dev/null +++ b/shell/hush_test/hush-quoting/squote_in_varexp2.right | |||
@@ -0,0 +1,3 @@ | |||
1 | Nothing: | ||
2 | Nothing: | ||
3 | Ok:0 | ||
diff --git a/shell/hush_test/hush-quoting/squote_in_varexp2.tests b/shell/hush_test/hush-quoting/squote_in_varexp2.tests new file mode 100755 index 000000000..806ad12b9 --- /dev/null +++ b/shell/hush_test/hush-quoting/squote_in_varexp2.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | x='\\\\' | ||
2 | printf Nothing:'%s\n' ${x#'\\\\'} | ||
3 | printf Nothing:'%s\n' "${x#'\\\\'}" | ||
4 | echo Ok:$? | ||
diff --git a/shell/match.c b/shell/match.c index fee3cf2a8..ee8abb2db 100644 --- a/shell/match.c +++ b/shell/match.c | |||
@@ -71,9 +71,11 @@ char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags | |||
71 | if (flags & SCAN_MATCH_LEFT_HALF) { | 71 | if (flags & SCAN_MATCH_LEFT_HALF) { |
72 | *loc = '\0'; | 72 | *loc = '\0'; |
73 | r = fnmatch(pattern, string, 0); | 73 | r = fnmatch(pattern, string, 0); |
74 | //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); | ||
74 | *loc = c; | 75 | *loc = c; |
75 | } else { | 76 | } else { |
76 | r = fnmatch(pattern, loc, 0); | 77 | r = fnmatch(pattern, loc, 0); |
78 | //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, loc, r); | ||
77 | } | 79 | } |
78 | if (r == 0) /* match found */ | 80 | if (r == 0) /* match found */ |
79 | return loc; | 81 | return loc; |