shell: tweak bkslash_in_varexp.tests, add bkslash_in_varexp1.tests
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 2 Mar 2018 17:12:12 +0000 (18:12 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 2 Mar 2018 17:12:12 +0000 (18:12 +0100)
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 <vda.linux@googlemail.com>
shell/ash_test/ash-quoting/bkslash_in_varexp.tests
shell/ash_test/ash-quoting/bkslash_in_varexp1.right [new file with mode: 0644]
shell/ash_test/ash-quoting/bkslash_in_varexp1.tests [new file with mode: 0755]
shell/hush.c
shell/hush_test/hush-quoting/bkslash_in_varexp.tests
shell/hush_test/hush-quoting/bkslash_in_varexp1.right [new file with mode: 0644]
shell/hush_test/hush-quoting/bkslash_in_varexp1.tests [new file with mode: 0755]
shell/match.c

index 41b31ab541da665ccdad8e2d4b2a946694ed03c2..6c7b4b0cc339c46585a72bc351de4caed8ea8414 100755 (executable)
@@ -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 (file)
index 0000000..d030470
--- /dev/null
@@ -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 (executable)
index 0000000..3c817ea
--- /dev/null
@@ -0,0 +1,6 @@
+x=a
+echo Nothing:${x#[]a]}
+echo Nothing:"${x#[]a]}"
+echo Nothing:${x%[]a]}
+echo Nothing:"${x%[]a]}"
+echo Ok:$?
index e005b0a209fcc361e65866f6dca0a3b4d36c097d..da4967a8ad15c878e0e4857b7e476e4ada87faf9 100644 (file)
@@ -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) /* #[#] */
index 41b31ab541da665ccdad8e2d4b2a946694ed03c2..6c7b4b0cc339c46585a72bc351de4caed8ea8414 100755 (executable)
@@ -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 (file)
index 0000000..d030470
--- /dev/null
@@ -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 (executable)
index 0000000..3c817ea
--- /dev/null
@@ -0,0 +1,6 @@
+x=a
+echo Nothing:${x#[]a]}
+echo Nothing:"${x#[]a]}"
+echo Nothing:${x%[]a]}
+echo Nothing:"${x%[]a]}"
+echo Ok:$?
index fee3cf2a80d432dbd2423d1060cfd4cda1548c3f..8f2a2fb3824b11f72d719de2641b94a886421094 100644 (file)
@@ -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;