svn commit: trunk/busybox/shell: hush_test/hush-parsing

vda at busybox.net vda at busybox.net
Sat Jul 5 17:40:05 UTC 2008


Author: vda
Date: 2008-07-05 10:40:04 -0700 (Sat, 05 Jul 2008)
New Revision: 22655

Log:
hush: fix a case where "$@" must expand to no word at all



Added:
   trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right
   trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests

Modified:
   trunk/busybox/shell/hush.c


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2008-07-05 15:14:11 UTC (rev 22654)
+++ trunk/busybox/shell/hush.c	2008-07-05 17:40:04 UTC (rev 22655)
@@ -2380,7 +2380,10 @@
 		p = strchr(p, SPECIAL_VAR_SYMBOL);
 
 		first_ch = arg[0] | or_mask; /* forced to "quoted" if or_mask = 0x80 */
-		ored_ch |= first_ch;
+		/* "$@" is special. Even if quoted, it can still
+		 * expand to nothing (not even an empty string) */
+		if ((first_ch & 0x7f) != '@')
+			ored_ch |= first_ch;
 		val = NULL;
 		switch (first_ch & 0x7f) {
 		/* Highest bit in first_ch indicates that var is double-quoted */
@@ -2401,6 +2404,7 @@
 			i = 1;
 			if (!global_argv[i])
 				break;
+			ored_ch |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
 			if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
 				smallint sv = output->o_quote;
 				/* unquoted var's contents should be globbed, so don't quote */
@@ -2932,15 +2936,25 @@
 			}
 		}
 #endif
-		if (word->nonnull /* we saw "xx" or 'xx' */
+		if (word->nonnull /* word had "xx" or 'xx' at least as part of it */
 		 /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
 		 && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL)
 		 /* (otherwise it's "abc".... and is already safe) */
 		) {
-			/* Insert "empty variable" reference, this makes
-			 * e.g. "", $empty"" etc to not disappear */
-			o_addchr(word, SPECIAL_VAR_SYMBOL);
-			o_addchr(word, SPECIAL_VAR_SYMBOL);
+			/* but exclude "$@"! it expands to no word despite "" */
+			char *p = word->data;
+			while (p[0] == SPECIAL_VAR_SYMBOL
+			    && (p[1] & 0x7f) == '@'
+			    && p[2] == SPECIAL_VAR_SYMBOL
+			) {
+				p += 3;
+			}
+			if (p == word->data || p[0] != '\0') {
+				/* Insert "empty variable" reference, this makes
+				 * e.g. "", $empty"" etc to not disappear */
+				o_addchr(word, SPECIAL_VAR_SYMBOL);
+				o_addchr(word, SPECIAL_VAR_SYMBOL);
+			}
 		}
 		child->argv = add_malloced_string_to_strings(child->argv, xstrdup(word->data));
 		debug_print_strings("word appended to argv", child->argv);

Added: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-parsing/starquoted2.right	2008-07-05 17:40:04 UTC (rev 22655)
@@ -0,0 +1,2 @@
+Should be printed
+Should be printed

Added: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests	2008-07-05 17:40:04 UTC (rev 22655)
@@ -0,0 +1,14 @@
+if test $# != 0; then
+    exec "$THIS_SH" "$0"
+fi
+
+# No params!
+for a in "$*"; do echo Should be printed; done
+for a in "$@"; do echo Should not be printed; done
+# Yes, believe it or not, bash is mesmerized by "$@" and stops
+# treating "" as "this word cannot be expanded to nothing,
+# but must be at least null string". Now it can be expanded to nothing.
+for a in "$@"""; do echo Should not be printed; done
+for a in """$@"; do echo Should not be printed; done
+for a in """$@"''"$@"''; do echo Should not be printed; done
+for a in ""; do echo Should be printed; done


Property changes on: trunk/busybox/shell/hush_test/hush-parsing/starquoted2.tests
___________________________________________________________________
Name: svn:executable
   + *




More information about the busybox-cvs mailing list