diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-11 13:47:59 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-11 13:47:59 +0200 |
commit | 34179956f96370f5a53e73073d984d62135cd037 (patch) | |
tree | fb203652077aca11c41f69a66b948bc64873a126 /shell | |
parent | 680c3016a2dddc3edb4d79868a728e899638e2c4 (diff) | |
download | busybox-w32-34179956f96370f5a53e73073d984d62135cd037.tar.gz busybox-w32-34179956f96370f5a53e73073d984d62135cd037.tar.bz2 busybox-w32-34179956f96370f5a53e73073d984d62135cd037.zip |
hush: fix "$v" expansion in case patterns when v='[a]'
function old new delta
run_list 1053 1063 +10
setup_redirects 311 320 +9
encode_then_expand_string 135 142 +7
run_pipe 1784 1789 +5
expand_assignments 81 86 +5
expand_string_to_string 124 125 +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/0 up/down: 37/0) Total: 37 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash_test/ash-quoting/case_glob1.right | 1 | ||||
-rwxr-xr-x | shell/ash_test/ash-quoting/case_glob1.tests | 8 | ||||
-rw-r--r-- | shell/hush.c | 50 | ||||
-rw-r--r-- | shell/hush_test/hush-quoting/case_glob1.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-quoting/case_glob1.tests | 8 |
5 files changed, 52 insertions, 16 deletions
diff --git a/shell/ash_test/ash-quoting/case_glob1.right b/shell/ash_test/ash-quoting/case_glob1.right new file mode 100644 index 000000000..b4785957b --- /dev/null +++ b/shell/ash_test/ash-quoting/case_glob1.right | |||
@@ -0,0 +1 @@ | |||
s | |||
diff --git a/shell/ash_test/ash-quoting/case_glob1.tests b/shell/ash_test/ash-quoting/case_glob1.tests new file mode 100755 index 000000000..8dbbc0fb1 --- /dev/null +++ b/shell/ash_test/ash-quoting/case_glob1.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | g='[3](a)(b)(c)' | ||
2 | s='[3](a)(b)(c)' | ||
3 | case $g in | ||
4 | "$s") echo s | ||
5 | ;; | ||
6 | *) echo "*" | ||
7 | ;; | ||
8 | esac | ||
diff --git a/shell/hush.c b/shell/hush.c index 735fbef27..248364be2 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -5610,11 +5610,10 @@ static struct pipe *parse_stream(char **pstring, | |||
5610 | 5610 | ||
5611 | /* Expansion can recurse, need forward decls: */ | 5611 | /* Expansion can recurse, need forward decls: */ |
5612 | #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE | 5612 | #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE |
5613 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ | 5613 | #define expand_string_to_string(str, EXP_flags, do_unbackslash) \ |
5614 | #define expand_string_to_string(str, do_unbackslash) \ | ||
5615 | expand_string_to_string(str) | 5614 | expand_string_to_string(str) |
5616 | #endif | 5615 | #endif |
5617 | static char *expand_string_to_string(const char *str, int do_unbackslash); | 5616 | static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash); |
5618 | #if ENABLE_HUSH_TICK | 5617 | #if ENABLE_HUSH_TICK |
5619 | static int process_command_subs(o_string *dest, const char *s); | 5618 | static int process_command_subs(o_string *dest, const char *s); |
5620 | #endif | 5619 | #endif |
@@ -5760,7 +5759,10 @@ static char *encode_then_expand_string(const char *str, int process_bkslash, int | |||
5760 | encode_string(NULL, &dest, &input, EOF, process_bkslash); | 5759 | encode_string(NULL, &dest, &input, EOF, process_bkslash); |
5761 | //TODO: error check (encode_string returns 0 on error)? | 5760 | //TODO: error check (encode_string returns 0 on error)? |
5762 | //bb_error_msg("'%s' -> '%s'", str, dest.data); | 5761 | //bb_error_msg("'%s' -> '%s'", str, dest.data); |
5763 | exp_str = expand_string_to_string(dest.data, /*unbackslash:*/ do_unbackslash); | 5762 | exp_str = expand_string_to_string(dest.data, |
5763 | do_unbackslash ? EXP_FLAG_ESC_GLOB_CHARS : 0, | ||
5764 | do_unbackslash | ||
5765 | ); | ||
5764 | //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); | 5766 | //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); |
5765 | o_free_unsafe(&dest); | 5767 | o_free_unsafe(&dest); |
5766 | return exp_str; | 5768 | return exp_str; |
@@ -6393,10 +6395,11 @@ static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | |||
6393 | * NB: should NOT do globbing! | 6395 | * NB: should NOT do globbing! |
6394 | * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*" | 6396 | * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*" |
6395 | */ | 6397 | */ |
6396 | static char *expand_string_to_string(const char *str, int do_unbackslash) | 6398 | static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash) |
6397 | { | 6399 | { |
6398 | #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE | 6400 | #if !BASH_PATTERN_SUBST && !ENABLE_HUSH_CASE |
6399 | const int do_unbackslash = 1; | 6401 | const int do_unbackslash = 1; |
6402 | const int EXP_flags = EXP_FLAG_ESC_GLOB_CHARS; | ||
6400 | #endif | 6403 | #endif |
6401 | char *argv[2], **list; | 6404 | char *argv[2], **list; |
6402 | 6405 | ||
@@ -6413,10 +6416,7 @@ static char *expand_string_to_string(const char *str, int do_unbackslash) | |||
6413 | 6416 | ||
6414 | argv[0] = (char*)str; | 6417 | argv[0] = (char*)str; |
6415 | argv[1] = NULL; | 6418 | argv[1] = NULL; |
6416 | list = expand_variables(argv, do_unbackslash | 6419 | list = expand_variables(argv, EXP_flags | EXP_FLAG_SINGLEWORD); |
6417 | ? EXP_FLAG_ESC_GLOB_CHARS | EXP_FLAG_SINGLEWORD | ||
6418 | : EXP_FLAG_SINGLEWORD | ||
6419 | ); | ||
6420 | if (HUSH_DEBUG) | 6420 | if (HUSH_DEBUG) |
6421 | if (!list[0] || list[1]) | 6421 | if (!list[0] || list[1]) |
6422 | bb_error_msg_and_die("BUG in varexp2"); | 6422 | bb_error_msg_and_die("BUG in varexp2"); |
@@ -6460,7 +6460,13 @@ static char **expand_assignments(char **argv, int count) | |||
6460 | G.expanded_assignments = p = NULL; | 6460 | G.expanded_assignments = p = NULL; |
6461 | /* Expand assignments into one string each */ | 6461 | /* Expand assignments into one string each */ |
6462 | for (i = 0; i < count; i++) { | 6462 | for (i = 0; i < count; i++) { |
6463 | G.expanded_assignments = p = add_string_to_strings(p, expand_string_to_string(argv[i], /*unbackslash:*/ 1)); | 6463 | p = add_string_to_strings(p, |
6464 | expand_string_to_string(argv[i], | ||
6465 | EXP_FLAG_ESC_GLOB_CHARS, | ||
6466 | /*unbackslash:*/ 1 | ||
6467 | ) | ||
6468 | ); | ||
6469 | G.expanded_assignments = p; | ||
6464 | } | 6470 | } |
6465 | G.expanded_assignments = NULL; | 6471 | G.expanded_assignments = NULL; |
6466 | return p; | 6472 | return p; |
@@ -7172,7 +7178,8 @@ static int setup_redirects(struct command *prog, struct squirrel **sqp) | |||
7172 | continue; | 7178 | continue; |
7173 | } | 7179 | } |
7174 | mode = redir_table[redir->rd_type].mode; | 7180 | mode = redir_table[redir->rd_type].mode; |
7175 | p = expand_string_to_string(redir->rd_filename, /*unbackslash:*/ 1); | 7181 | p = expand_string_to_string(redir->rd_filename, |
7182 | EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1); | ||
7176 | newfd = open_or_warn(p, mode); | 7183 | newfd = open_or_warn(p, mode); |
7177 | free(p); | 7184 | free(p); |
7178 | if (newfd < 0) { | 7185 | if (newfd < 0) { |
@@ -8370,7 +8377,10 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8370 | bb_putchar_stderr('+'); | 8377 | bb_putchar_stderr('+'); |
8371 | i = 0; | 8378 | i = 0; |
8372 | while (i < command->assignment_cnt) { | 8379 | while (i < command->assignment_cnt) { |
8373 | char *p = expand_string_to_string(argv[i], /*unbackslash:*/ 1); | 8380 | char *p = expand_string_to_string(argv[i], |
8381 | EXP_FLAG_ESC_GLOB_CHARS, | ||
8382 | /*unbackslash:*/ 1 | ||
8383 | ); | ||
8374 | if (G_x_mode) | 8384 | if (G_x_mode) |
8375 | fprintf(stderr, " %s", p); | 8385 | fprintf(stderr, " %s", p); |
8376 | debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); | 8386 | debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); |
@@ -8865,7 +8875,8 @@ static int run_list(struct pipe *pi) | |||
8865 | #if ENABLE_HUSH_CASE | 8875 | #if ENABLE_HUSH_CASE |
8866 | if (rword == RES_CASE) { | 8876 | if (rword == RES_CASE) { |
8867 | debug_printf_exec("CASE cond_code:%d\n", cond_code); | 8877 | debug_printf_exec("CASE cond_code:%d\n", cond_code); |
8868 | case_word = expand_string_to_string(pi->cmds->argv[0], 1); | 8878 | case_word = expand_string_to_string(pi->cmds->argv[0], |
8879 | EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1); | ||
8869 | debug_printf_exec("CASE word1:'%s'\n", case_word); | 8880 | debug_printf_exec("CASE word1:'%s'\n", case_word); |
8870 | //unbackslash(case_word); | 8881 | //unbackslash(case_word); |
8871 | //debug_printf_exec("CASE word2:'%s'\n", case_word); | 8882 | //debug_printf_exec("CASE word2:'%s'\n", case_word); |
@@ -8880,12 +8891,19 @@ static int run_list(struct pipe *pi) | |||
8880 | /* all prev words didn't match, does this one match? */ | 8891 | /* all prev words didn't match, does this one match? */ |
8881 | argv = pi->cmds->argv; | 8892 | argv = pi->cmds->argv; |
8882 | while (*argv) { | 8893 | while (*argv) { |
8883 | char *pattern = expand_string_to_string(*argv, /*unbackslash:*/ 0); | 8894 | char *pattern; |
8895 | debug_printf_exec("expand_string_to_string('%s')\n", *argv); | ||
8896 | pattern = expand_string_to_string(*argv, | ||
8897 | EXP_FLAG_ESC_GLOB_CHARS, | ||
8898 | /*unbackslash:*/ 0 | ||
8899 | ); | ||
8884 | /* TODO: which FNM_xxx flags to use? */ | 8900 | /* TODO: which FNM_xxx flags to use? */ |
8885 | cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); | 8901 | cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); |
8886 | debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n", pattern, case_word, cond_code); | 8902 | debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n", |
8903 | pattern, case_word, cond_code); | ||
8887 | free(pattern); | 8904 | free(pattern); |
8888 | if (cond_code == 0) { /* match! we will execute this branch */ | 8905 | if (cond_code == 0) { |
8906 | /* match! we will execute this branch */ | ||
8889 | free(case_word); | 8907 | free(case_word); |
8890 | case_word = NULL; /* make future "word)" stop */ | 8908 | case_word = NULL; /* make future "word)" stop */ |
8891 | break; | 8909 | break; |
diff --git a/shell/hush_test/hush-quoting/case_glob1.right b/shell/hush_test/hush-quoting/case_glob1.right new file mode 100644 index 000000000..b4785957b --- /dev/null +++ b/shell/hush_test/hush-quoting/case_glob1.right | |||
@@ -0,0 +1 @@ | |||
s | |||
diff --git a/shell/hush_test/hush-quoting/case_glob1.tests b/shell/hush_test/hush-quoting/case_glob1.tests new file mode 100755 index 000000000..8dbbc0fb1 --- /dev/null +++ b/shell/hush_test/hush-quoting/case_glob1.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | g='[3](a)(b)(c)' | ||
2 | s='[3](a)(b)(c)' | ||
3 | case $g in | ||
4 | "$s") echo s | ||
5 | ;; | ||
6 | *) echo "*" | ||
7 | ;; | ||
8 | esac | ||