aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c17
-rw-r--r--shell/ash_test/ash-vars/var_bash4.right2
-rwxr-xr-xshell/ash_test/ash-vars/var_bash4.tests2
3 files changed, 16 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 6befe0fd3..4fbae2498 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6234,7 +6234,7 @@ parse_sub_pattern(char *arg, int varflags)
unsigned char c;
//char *org_arg = arg;
- //bb_error_msg("arg:'%s'", arg);
+ //bb_error_msg("arg:'%s' varflags:%x", arg, varflags);
idx = arg;
while (1) {
c = *arg;
@@ -6248,9 +6248,20 @@ parse_sub_pattern(char *arg, int varflags)
}
}
*idx++ = c;
- if (!(varflags & VSQUOTE) && c == '\\' && arg[1] == '\\')
- arg++; /* skip both \\, not just first one */
arg++;
+ /*
+ * Example: v='ab\c'; echo ${v/\\b/_\\_\z_}
+ * The result is a_\_z_c (not a\_\_z_c)!
+ *
+ * Enable debug prints in this function and you'll see:
+ * ash: arg:'\\b/_\\_z_' varflags:d
+ * ash: pattern:'\\b' repl:'_\_z_'
+ * That is, \\b is interpreted as \\b, but \\_ as \_!
+ * IOW: search pattern and replace string treat backslashes
+ * differently! That is the reason why we check repl below:
+ */
+ if (c == '\\' && *arg == '\\' && repl && !(varflags & VSQUOTE))
+ arg++; /* skip both '\', not just first one */
}
*idx = c; /* NUL */
//bb_error_msg("pattern:'%s' repl:'%s'", org_arg, repl);
diff --git a/shell/ash_test/ash-vars/var_bash4.right b/shell/ash_test/ash-vars/var_bash4.right
index 2d4e45be8..600e8532f 100644
--- a/shell/ash_test/ash-vars/var_bash4.right
+++ b/shell/ash_test/ash-vars/var_bash4.right
@@ -11,7 +11,7 @@ Quoted: a*b_\_\z_
Source: a\bc
Replace str: _\\_\z_
-Pattern: single backslash and b: "replace literal b"
+Pattern: single backslash and b: "replace b"
In assignment: a\_\_z_c
Unquoted: a\_\_z_c
Quoted: a\_\_\z_c
diff --git a/shell/ash_test/ash-vars/var_bash4.tests b/shell/ash_test/ash-vars/var_bash4.tests
index a6e98fd86..d5470614b 100755
--- a/shell/ash_test/ash-vars/var_bash4.tests
+++ b/shell/ash_test/ash-vars/var_bash4.tests
@@ -30,7 +30,7 @@ v='a\bc'
echo 'Source: ' "$v"
echo 'Replace str: ' '_\\_\z_'
-echo 'Pattern: ' 'single backslash and b: "replace literal b"'
+echo 'Pattern: ' 'single backslash and b: "replace b"'
r=${v/\b/_\\_\z_}
echo 'In assignment:' "$r"
echo 'Unquoted: ' ${v/\b/_\\_\z_}