aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-08-07 22:24:36 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-08-07 22:24:36 +0200
commit33bbb27e45c7c6a0fecb40b3a5aa36aef69825f9 (patch)
treeb1038e6280788218428409acf45158bf0013c5d0
parent58a15cd9d2765e9b9bca6b71ad9713bcc3784821 (diff)
downloadbusybox-w32-33bbb27e45c7c6a0fecb40b3a5aa36aef69825f9.tar.gz
busybox-w32-33bbb27e45c7c6a0fecb40b3a5aa36aef69825f9.tar.bz2
busybox-w32-33bbb27e45c7c6a0fecb40b3a5aa36aef69825f9.zip
ash: fix another bit of var_bash4 bug
But it _still_ doesn't pass! quoted case is a tough nut to crack function old new delta redirect 1281 1286 +5 subevalvar 1141 1142 +1 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-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)
6234 unsigned char c; 6234 unsigned char c;
6235 6235
6236 //char *org_arg = arg; 6236 //char *org_arg = arg;
6237 //bb_error_msg("arg:'%s'", arg); 6237 //bb_error_msg("arg:'%s' varflags:%x", arg, varflags);
6238 idx = arg; 6238 idx = arg;
6239 while (1) { 6239 while (1) {
6240 c = *arg; 6240 c = *arg;
@@ -6248,9 +6248,20 @@ parse_sub_pattern(char *arg, int varflags)
6248 } 6248 }
6249 } 6249 }
6250 *idx++ = c; 6250 *idx++ = c;
6251 if (!(varflags & VSQUOTE) && c == '\\' && arg[1] == '\\')
6252 arg++; /* skip both \\, not just first one */
6253 arg++; 6251 arg++;
6252 /*
6253 * Example: v='ab\c'; echo ${v/\\b/_\\_\z_}
6254 * The result is a_\_z_c (not a\_\_z_c)!
6255 *
6256 * Enable debug prints in this function and you'll see:
6257 * ash: arg:'\\b/_\\_z_' varflags:d
6258 * ash: pattern:'\\b' repl:'_\_z_'
6259 * That is, \\b is interpreted as \\b, but \\_ as \_!
6260 * IOW: search pattern and replace string treat backslashes
6261 * differently! That is the reason why we check repl below:
6262 */
6263 if (c == '\\' && *arg == '\\' && repl && !(varflags & VSQUOTE))
6264 arg++; /* skip both '\', not just first one */
6254 } 6265 }
6255 *idx = c; /* NUL */ 6266 *idx = c; /* NUL */
6256 //bb_error_msg("pattern:'%s' repl:'%s'", org_arg, repl); 6267 //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_
11 11
12Source: a\bc 12Source: a\bc
13Replace str: _\\_\z_ 13Replace str: _\\_\z_
14Pattern: single backslash and b: "replace literal b" 14Pattern: single backslash and b: "replace b"
15In assignment: a\_\_z_c 15In assignment: a\_\_z_c
16Unquoted: a\_\_z_c 16Unquoted: a\_\_z_c
17Quoted: a\_\_\z_c 17Quoted: 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'
30echo 'Source: ' "$v" 30echo 'Source: ' "$v"
31echo 'Replace str: ' '_\\_\z_' 31echo 'Replace str: ' '_\\_\z_'
32 32
33echo 'Pattern: ' 'single backslash and b: "replace literal b"' 33echo 'Pattern: ' 'single backslash and b: "replace b"'
34r=${v/\b/_\\_\z_} 34r=${v/\b/_\\_\z_}
35echo 'In assignment:' "$r" 35echo 'In assignment:' "$r"
36echo 'Unquoted: ' ${v/\b/_\\_\z_} 36echo 'Unquoted: ' ${v/\b/_\\_\z_}