[git commit master 1/1] ash: fix another bit of var_bash4 bug

Denys Vlasenko vda.linux at googlemail.com
Sat Aug 7 20:24:36 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=33bbb27e45c7c6a0fecb40b3a5aa36aef69825f9
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 shell/ash.c                             |   17 ++++++++++++++---
 shell/ash_test/ash-vars/var_bash4.right |    2 +-
 shell/ash_test/ash-vars/var_bash4.tests |    2 +-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index 6befe0f..4fbae24 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 2d4e45b..600e853 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 a6e98fd..d547061 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_}
-- 
1.7.1



More information about the busybox-cvs mailing list