[git commit] ash, hush: properly handle ${v//pattern/repl} if pattern starts with /

Denys Vlasenko vda.linux at googlemail.com
Sat Aug 4 20:25:28 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=c2aa218f23a4e952746ebef7bb86668c6255471c
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Closes 2695

function                                             old     new   delta
parse_dollar                                         762     790     +28
subevalvar                                          1258    1267      +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 37/0)               Total: 37 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash.c                                                    | 10 +++++++++-
 .../ash-vars/var_bash_pattern_starting_with_slash.right        |  2 ++
 .../ash-vars/var_bash_pattern_starting_with_slash.tests        |  3 +++
 shell/hush.c                                                   |  9 +++++++++
 .../hush-vars/var_bash_pattern_starting_with_slash.right       |  2 ++
 .../hush-vars/var_bash_pattern_starting_with_slash.tests       |  3 +++
 6 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/shell/ash.c b/shell/ash.c
index 03fbbee53..5c431c9ff 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6854,8 +6854,15 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
 	if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
 		/* Find '/' and replace with NUL */
 		repl = p;
+		/* The pattern can't be empty.
+		 * IOW: if the first char after "${v//" is a slash,
+		 * it does not terminate the pattern - it's the first char of the pattern:
+		 *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
+		 *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
+		 */
+		if (*repl == '/')
+			repl++;
 		for (;;) {
-			/* Handle escaped slashes, e.g. "${v/\//_}" (they are CTLESC'ed by this point) */
 			if (*repl == '\0') {
 				repl = NULL;
 				break;
@@ -6864,6 +6871,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
 				*repl = '\0';
 				break;
 			}
+			/* Handle escaped slashes, e.g. "${v/\//_}" (they are CTLESC'ed by this point) */
 			if ((unsigned char)*repl == CTLESC && repl[1])
 				repl++;
 			repl++;
diff --git a/shell/ash_test/ash-vars/var_bash_pattern_starting_with_slash.right b/shell/ash_test/ash-vars/var_bash_pattern_starting_with_slash.right
new file mode 100644
index 000000000..439dca578
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_bash_pattern_starting_with_slash.right
@@ -0,0 +1,2 @@
+-dev-ram
+/dev-am
diff --git a/shell/ash_test/ash-vars/var_bash_pattern_starting_with_slash.tests b/shell/ash_test/ash-vars/var_bash_pattern_starting_with_slash.tests
new file mode 100755
index 000000000..b83fb8eeb
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_bash_pattern_starting_with_slash.tests
@@ -0,0 +1,3 @@
+v=/dev/ram
+echo ${v////-}
+echo ${v///r/-}
diff --git a/shell/hush.c b/shell/hush.c
index 6852b5f79..3407711cd 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4930,6 +4930,15 @@ static int parse_dollar(o_string *as_string,
 					end_ch = '}' * 0x100 + '/';
 				}
 				o_addchr(dest, ch);
+				/* The pattern can't be empty.
+				 * IOW: if the first char after "${v//" is a slash,
+				 * it does not terminate the pattern - it's the first char of the pattern:
+				 *  v=/dev/ram; echo ${v////-}  prints -dev-ram (pattern is "/")
+				 *  v=/dev/ram; echo ${v///r/-} prints /dev-am  (pattern is "/r")
+				 */
+				if (i_peek(input) == '/') {
+					o_addchr(dest, i_getch(input));
+				}
  again:
 				if (!BB_MMU)
 					pos = dest->length;
diff --git a/shell/hush_test/hush-vars/var_bash_pattern_starting_with_slash.right b/shell/hush_test/hush-vars/var_bash_pattern_starting_with_slash.right
new file mode 100644
index 000000000..439dca578
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash_pattern_starting_with_slash.right
@@ -0,0 +1,2 @@
+-dev-ram
+/dev-am
diff --git a/shell/hush_test/hush-vars/var_bash_pattern_starting_with_slash.tests b/shell/hush_test/hush-vars/var_bash_pattern_starting_with_slash.tests
new file mode 100755
index 000000000..b83fb8eeb
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash_pattern_starting_with_slash.tests
@@ -0,0 +1,3 @@
+v=/dev/ram
+echo ${v////-}
+echo ${v///r/-}


More information about the busybox-cvs mailing list