From 744a20d8f9b1baf7c8cc1ed33ec744a52c89768f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 2 Mar 2018 17:13:22 +0100 Subject: shell: two new tests, both fail for ash and hush Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-quoting/bkslash_in_varexp.right | 5 +++++ shell/ash_test/ash-quoting/bkslash_in_varexp.tests | 6 ++++++ shell/ash_test/ash-quoting/squote_in_varexp.right | 5 +++++ shell/ash_test/ash-quoting/squote_in_varexp.tests | 6 ++++++ shell/hush_test/hush-quoting/bkslash_in_varexp.right | 5 +++++ shell/hush_test/hush-quoting/bkslash_in_varexp.tests | 6 ++++++ shell/hush_test/hush-quoting/squote_in_varexp.right | 5 +++++ shell/hush_test/hush-quoting/squote_in_varexp.tests | 6 ++++++ 8 files changed, 44 insertions(+) create mode 100644 shell/ash_test/ash-quoting/bkslash_in_varexp.right create mode 100755 shell/ash_test/ash-quoting/bkslash_in_varexp.tests create mode 100644 shell/ash_test/ash-quoting/squote_in_varexp.right create mode 100755 shell/ash_test/ash-quoting/squote_in_varexp.tests create mode 100644 shell/hush_test/hush-quoting/bkslash_in_varexp.right create mode 100755 shell/hush_test/hush-quoting/bkslash_in_varexp.tests create mode 100644 shell/hush_test/hush-quoting/squote_in_varexp.right create mode 100755 shell/hush_test/hush-quoting/squote_in_varexp.tests (limited to 'shell') 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 @@ +Nothing: +Nothing: +Nothing: +Nothing: +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..41b31ab54 --- /dev/null +++ b/shell/ash_test/ash-quoting/bkslash_in_varexp.tests @@ -0,0 +1,6 @@ +x=a +echo Nothing:${x#[a\]]} +echo Nothing:"${x#[a\]]}" +echo Nothing:${x%[a\]]} +echo Nothing:"${x%[a\]]}" +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 @@ +z +z +y +y +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 @@ +x=yz +echo ${x#'y'} +echo "${x#'y'}" +echo ${x%'z'} +echo "${x%'z'}" +echo Ok:$? 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 @@ +Nothing: +Nothing: +Nothing: +Nothing: +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..41b31ab54 --- /dev/null +++ b/shell/hush_test/hush-quoting/bkslash_in_varexp.tests @@ -0,0 +1,6 @@ +x=a +echo Nothing:${x#[a\]]} +echo Nothing:"${x#[a\]]}" +echo Nothing:${x%[a\]]} +echo Nothing:"${x%[a\]]}" +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 @@ +z +z +y +y +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 @@ +x=yz +echo ${x#'y'} +echo "${x#'y'}" +echo ${x%'z'} +echo "${x%'z'}" +echo Ok:$? -- cgit v1.2.3-55-g6feb From 55f8133a4fb207d6fecd02f43c36809d3c2f6672 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 2 Mar 2018 18:12:12 +0100 Subject: shell: tweak bkslash_in_varexp.tests, add bkslash_in_varexp1.tests It turns out bkslash_in_varexp.tests was a bash bug :] ash and hush fail "corrected" bkslash_in_varexp.tests as well, just not as badly as I thought (hush gets half of the cases right). Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-quoting/bkslash_in_varexp.tests | 12 +++++++++++- shell/ash_test/ash-quoting/bkslash_in_varexp1.right | 5 +++++ shell/ash_test/ash-quoting/bkslash_in_varexp1.tests | 6 ++++++ shell/hush.c | 7 ++++--- shell/hush_test/hush-quoting/bkslash_in_varexp.tests | 12 +++++++++++- shell/hush_test/hush-quoting/bkslash_in_varexp1.right | 5 +++++ shell/hush_test/hush-quoting/bkslash_in_varexp1.tests | 6 ++++++ shell/match.c | 2 ++ 8 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 shell/ash_test/ash-quoting/bkslash_in_varexp1.right create mode 100755 shell/ash_test/ash-quoting/bkslash_in_varexp1.tests create mode 100644 shell/hush_test/hush-quoting/bkslash_in_varexp1.right create mode 100755 shell/hush_test/hush-quoting/bkslash_in_varexp1.tests (limited to 'shell') diff --git a/shell/ash_test/ash-quoting/bkslash_in_varexp.tests b/shell/ash_test/ash-quoting/bkslash_in_varexp.tests index 41b31ab54..6c7b4b0cc 100755 --- a/shell/ash_test/ash-quoting/bkslash_in_varexp.tests +++ b/shell/ash_test/ash-quoting/bkslash_in_varexp.tests @@ -1,4 +1,14 @@ -x=a +x='a]' +# +# \] is not a valid escape for ] in set glob expression. +# Glob sets have no escaping at all: +# ] can be in a set if it is the first char: []abc], +# dash can be in a set if it is first or last: [abc-], +# [ and \ need no protections at all: [a[b\c] is a valid set of 5 chars. +# +# bash-4.3.43 misinterprets [a\]] as "set of 'a' or ']'". +# Correct interpretation is "set of 'a' or '\', followed by ']'". +# echo Nothing:${x#[a\]]} echo Nothing:"${x#[a\]]}" echo Nothing:${x%[a\]]} 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 @@ +Nothing: +Nothing: +Nothing: +Nothing: +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 @@ +x=a +echo Nothing:${x#[]a]} +echo Nothing:"${x#[]a]}" +echo Nothing:${x%[]a]} +echo Nothing:"${x%[]a]}" +echo Ok:$? diff --git a/shell/hush.c b/shell/hush.c index e005b0a20..da4967a8a 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 } if (ch == end_ch # if BASH_SUBSTR || BASH_PATTERN_SUBST - || ch == end_char2 + || ch == end_char2 # endif ) { if (!dbl) @@ -5842,17 +5842,18 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha unsigned scan_flags = pick_scan(exp_op, *exp_word); if (exp_op == *exp_word) /* ## or %% */ exp_word++; + debug_printf_expand("expand: exp_word:'%s'\n", exp_word); exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 1, /*unbackslash:*/ 1); if (exp_exp_word) exp_word = exp_exp_word; + debug_printf_expand("expand: exp_exp_word:'%s'\n", exp_word); /* HACK ALERT. We depend here on the fact that * G.global_argv and results of utoa and get_local_var_value * are actually in writable memory: * scan_and_match momentarily stores NULs there. */ t = (char*)val; loc = scan_and_match(t, exp_word, scan_flags); - //bb_error_msg("op:%c str:'%s' pat:'%s' res:'%s'", - // exp_op, t, exp_word, loc); + debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc); free(exp_exp_word); if (loc) { /* match was found */ if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */ diff --git a/shell/hush_test/hush-quoting/bkslash_in_varexp.tests b/shell/hush_test/hush-quoting/bkslash_in_varexp.tests index 41b31ab54..6c7b4b0cc 100755 --- a/shell/hush_test/hush-quoting/bkslash_in_varexp.tests +++ b/shell/hush_test/hush-quoting/bkslash_in_varexp.tests @@ -1,4 +1,14 @@ -x=a +x='a]' +# +# \] is not a valid escape for ] in set glob expression. +# Glob sets have no escaping at all: +# ] can be in a set if it is the first char: []abc], +# dash can be in a set if it is first or last: [abc-], +# [ and \ need no protections at all: [a[b\c] is a valid set of 5 chars. +# +# bash-4.3.43 misinterprets [a\]] as "set of 'a' or ']'". +# Correct interpretation is "set of 'a' or '\', followed by ']'". +# echo Nothing:${x#[a\]]} echo Nothing:"${x#[a\]]}" echo Nothing:${x%[a\]]} 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 @@ +Nothing: +Nothing: +Nothing: +Nothing: +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 @@ +x=a +echo Nothing:${x#[]a]} +echo Nothing:"${x#[]a]}" +echo Nothing:${x%[]a]} +echo Nothing:"${x%[]a]}" +echo Ok:$? diff --git a/shell/match.c b/shell/match.c index fee3cf2a8..8f2a2fb38 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 if (flags & SCAN_MATCH_LEFT_HALF) { *loc = '\0'; r = fnmatch(pattern, string, 0); + //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); *loc = c; } else { r = fnmatch(pattern, loc, 0); + //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); } if (r == 0) /* match found */ return loc; -- cgit v1.2.3-55-g6feb From d4802c6243e64e28690577bc0bb4f030581c496b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 2 Mar 2018 20:48:36 +0100 Subject: hush: fix a='a\\'; echo "${a%\\\\}" Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-quoting/squote_in_varexp1.right | 3 +++ shell/ash_test/ash-quoting/squote_in_varexp1.tests | 4 ++++ shell/ash_test/ash-quoting/squote_in_varexp2.right | 3 +++ shell/ash_test/ash-quoting/squote_in_varexp2.tests | 4 ++++ shell/hush.c | 12 ++++++++++-- shell/hush_test/hush-quoting/squote_in_varexp1.right | 3 +++ shell/hush_test/hush-quoting/squote_in_varexp1.tests | 4 ++++ shell/hush_test/hush-quoting/squote_in_varexp2.right | 3 +++ shell/hush_test/hush-quoting/squote_in_varexp2.tests | 4 ++++ shell/match.c | 2 +- 10 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 shell/ash_test/ash-quoting/squote_in_varexp1.right create mode 100755 shell/ash_test/ash-quoting/squote_in_varexp1.tests create mode 100644 shell/ash_test/ash-quoting/squote_in_varexp2.right create mode 100755 shell/ash_test/ash-quoting/squote_in_varexp2.tests create mode 100644 shell/hush_test/hush-quoting/squote_in_varexp1.right create mode 100755 shell/hush_test/hush-quoting/squote_in_varexp1.tests create mode 100644 shell/hush_test/hush-quoting/squote_in_varexp2.right create mode 100755 shell/hush_test/hush-quoting/squote_in_varexp2.tests (limited to 'shell') 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 @@ +Nothing: +Nothing: +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 @@ +x='\\\\' +printf Nothing:'%s\n' ${x#\\\\\\\\} +printf Nothing:'%s\n' "${x#\\\\\\\\}" +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 @@ +Nothing: +Nothing: +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 @@ +x='\\\\' +printf Nothing:'%s\n' ${x#'\\\\'} +printf Nothing:'%s\n' "${x#'\\\\'}" +echo Ok:$? diff --git a/shell/hush.c b/shell/hush.c index da4967a8a..762cc3fe4 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -4500,6 +4500,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign } } o_addchr(dest, ch); + //bb_error_msg("%s:o_addchr('%c')", __func__, ch); if (ch == '(' || ch == '{') { ch = (ch == '(' ? ')' : '}'); 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 /* \x. Copy verbatim. Important for \(, \) */ ch = i_getch(input); if (ch == EOF) { - syntax_error_unterm_ch(')'); + syntax_error_unterm_ch(end_ch); return 0; } #if 0 @@ -4540,6 +4541,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign } #endif o_addchr(dest, ch); + //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch); continue; } } @@ -5843,7 +5845,13 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha if (exp_op == *exp_word) /* ## or %% */ exp_word++; debug_printf_expand("expand: exp_word:'%s'\n", exp_word); - exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 1, /*unbackslash:*/ 1); + /* + * process_bkslash:1 unbackslash:1 breaks this: + * a='a\\'; echo ${a%\\\\} # correct output is: a + * process_bkslash:1 unbackslash:0 breaks this: + * a='a}'; echo ${a%\}} # correct output is: a + */ + exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 0, /*unbackslash:*/ 0); if (exp_exp_word) exp_word = exp_exp_word; debug_printf_expand("expand: exp_exp_word:'%s'\n", exp_word); 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 @@ +Nothing: +Nothing: +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 @@ +x='\\\\' +printf Nothing:'%s\n' ${x#\\\\\\\\} +printf Nothing:'%s\n' "${x#\\\\\\\\}" +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 @@ +Nothing: +Nothing: +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 @@ +x='\\\\' +printf Nothing:'%s\n' ${x#'\\\\'} +printf Nothing:'%s\n' "${x#'\\\\'}" +echo Ok:$? diff --git a/shell/match.c b/shell/match.c index 8f2a2fb38..ee8abb2db 100644 --- a/shell/match.c +++ b/shell/match.c @@ -75,7 +75,7 @@ char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags *loc = c; } else { r = fnmatch(pattern, loc, 0); - //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); + //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, loc, r); } if (r == 0) /* match found */ return loc; -- cgit v1.2.3-55-g6feb From 33f7c8f200b6c3f7163dc89723ab67462688dccd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Mar 2018 17:21:57 +0100 Subject: hush: code shrink function old new delta run_pipe 1589 1591 +2 pseudo_exec_argv 374 375 +1 builtin_type 114 115 +1 find_function 8 - -8 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 3/0 up/down: 4/-8) Total: -4 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 762cc3fe4..6e64efb70 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -7181,21 +7181,22 @@ static const struct built_in_command *find_builtin(const char *name) #if ENABLE_HUSH_FUNCTIONS static struct function **find_function_slot(const char *name) { + struct function *funcp; struct function **funcpp = &G.top_func; - while (*funcpp) { - if (strcmp(name, (*funcpp)->name) == 0) { + + while ((funcp = *funcpp) != NULL) { + if (strcmp(name, funcp->name) == 0) { + debug_printf_exec("found function '%s'\n", name); break; } - funcpp = &(*funcpp)->next; + funcpp = &funcp->next; } return funcpp; } -static const struct function *find_function(const char *name) +static ALWAYS_INLINE const struct function *find_function(const char *name) { const struct function *funcp = *find_function_slot(name); - if (funcp) - debug_printf_exec("found function '%s'\n", name); return funcp; } -- cgit v1.2.3-55-g6feb