aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-04-11 13:47:59 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-04-11 13:47:59 +0200
commit34179956f96370f5a53e73073d984d62135cd037 (patch)
treefb203652077aca11c41f69a66b948bc64873a126 /shell
parent680c3016a2dddc3edb4d79868a728e899638e2c4 (diff)
downloadbusybox-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.right1
-rwxr-xr-xshell/ash_test/ash-quoting/case_glob1.tests8
-rw-r--r--shell/hush.c50
-rw-r--r--shell/hush_test/hush-quoting/case_glob1.right1
-rwxr-xr-xshell/hush_test/hush-quoting/case_glob1.tests8
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 @@
1g='[3](a)(b)(c)'
2s='[3](a)(b)(c)'
3case $g in
4"$s") echo s
5 ;;
6*) echo "*"
7 ;;
8esac
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
5617static char *expand_string_to_string(const char *str, int do_unbackslash); 5616static char *expand_string_to_string(const char *str, int EXP_flags, int do_unbackslash);
5618#if ENABLE_HUSH_TICK 5617#if ENABLE_HUSH_TICK
5619static int process_command_subs(o_string *dest, const char *s); 5618static 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 */
6396static char *expand_string_to_string(const char *str, int do_unbackslash) 6398static 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 @@
1g='[3](a)(b)(c)'
2s='[3](a)(b)(c)'
3case $g in
4"$s") echo s
5 ;;
6*) echo "*"
7 ;;
8esac