[git commit] hush: fix two corner cases in ${v/pattern/repl}. Closes 10686

Denys Vlasenko vda.linux at googlemail.com
Thu Jan 25 13:07:40 UTC 2018


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

function                                             old     new   delta
expand_one_var                                      1592    1618     +26

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/hush.c                                                | 13 +++++++++++--
 shell/hush_test/hush-vars/var_bash_repl_empty_pattern.right |  2 ++
 shell/hush_test/hush-vars/var_bash_repl_empty_pattern.tests |  3 +++
 shell/hush_test/hush-vars/var_bash_repl_empty_var.right     |  2 ++
 shell/hush_test/hush-vars/var_bash_repl_empty_var.tests     |  3 +++
 5 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index a9183c8..cf3c731 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5643,6 +5643,10 @@ static char *replace_pattern(char *val, const char *pattern, const char *repl, c
 	unsigned res_len = 0;
 	unsigned repl_len = strlen(repl);
 
+	/* Null pattern never matches, including if "var" is empty */
+	if (!pattern[0])
+		return result; /* NULL, no replaces happened */
+
 	while (1) {
 		int size;
 		char *s = strstr_pattern(val, pattern, &size);
@@ -5809,8 +5813,6 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
 			 * and if // is used, it is encoded as \:
 			 * var\pattern<SPECIAL_VAR_SYMBOL>repl<SPECIAL_VAR_SYMBOL>
 			 */
-			/* Empty variable always gives nothing: */
-			// "v=''; echo ${v/*/w}" prints "", not "w"
 			if (val && val[0]) {
 				/* pattern uses non-standard expansion.
 				 * repl should be unbackslashed and globbed
@@ -5846,6 +5848,13 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
 					val = to_be_freed;
 				free(pattern);
 				free(repl);
+			} else {
+				/* Empty variable always gives nothing */
+				// "v=''; echo ${v/*/w}" prints "", not "w"
+				/* Just skip "replace" part */
+				*p++ = SPECIAL_VAR_SYMBOL;
+				p = strchr(p, SPECIAL_VAR_SYMBOL);
+				*p = '\0';
 			}
 		}
 #endif /* BASH_PATTERN_SUBST */
diff --git a/shell/hush_test/hush-vars/var_bash_repl_empty_pattern.right b/shell/hush_test/hush-vars/var_bash_repl_empty_pattern.right
new file mode 100644
index 0000000..d400a7e
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash_repl_empty_pattern.right
@@ -0,0 +1,2 @@
+v
+Ok:0
diff --git a/shell/hush_test/hush-vars/var_bash_repl_empty_pattern.tests b/shell/hush_test/hush-vars/var_bash_repl_empty_pattern.tests
new file mode 100755
index 0000000..6e8aa2a
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash_repl_empty_pattern.tests
@@ -0,0 +1,3 @@
+v=v
+echo ${v//}
+echo Ok:$?
diff --git a/shell/hush_test/hush-vars/var_bash_repl_empty_var.right b/shell/hush_test/hush-vars/var_bash_repl_empty_var.right
new file mode 100644
index 0000000..8929167
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash_repl_empty_var.right
@@ -0,0 +1,2 @@
+
+Ok:0
diff --git a/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests b/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests
new file mode 100755
index 0000000..73a43d3
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash_repl_empty_var.tests
@@ -0,0 +1,3 @@
+v=''
+echo ${v/*/w}
+echo Ok:$?


More information about the busybox-cvs mailing list