svn commit: [26210] trunk/busybox/shell: hush_test/hush-arith hush_test/hush-var etc...

vda at busybox.net vda at busybox.net
Sun Apr 26 11:25:20 UTC 2009


Author: vda
Date: 2009-04-26 11:25:19 +0000 (Sun, 26 Apr 2009)
New Revision: 26210

Log:
hush: fix SEGV in % expansion

function                                             old     new   delta
expand_variables                                    2203    2217     +14



Modified:
   trunk/busybox/shell/hush.c
   trunk/busybox/shell/hush_test/hush-arith/arith.right
   trunk/busybox/shell/hush_test/hush-vars/var_posix1.right
   trunk/busybox/shell/hush_test/hush-vars/var_posix1.tests
   trunk/busybox/shell/match.c
   trunk/busybox/shell/match.h


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2009-04-26 01:43:36 UTC (rev 26209)
+++ trunk/busybox/shell/hush.c	2009-04-26 11:25:19 UTC (rev 26210)
@@ -1990,12 +1990,9 @@
 	 * (expansion of right-hand side of assignment == 1-element expand.
 	 * It will also do no globbing, and thus we must not backslash-quote!) */
 
-	char first_ch, ored_ch;
-	int i;
-	const char *val;
-	char *dyn_val, *p;
+	char ored_ch;
+	char *p;
 
-	dyn_val = NULL;
 	ored_ch = 0;
 
 	debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg);
@@ -2004,6 +2001,10 @@
 	debug_print_list("expand_vars_to_list[0]", output, n);
 
 	while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
+		char first_ch;
+		int i;
+		char *dyn_val = NULL;
+		const char *val = NULL;
 #if ENABLE_HUSH_TICK
 		o_string subst_result = NULL_O_STRING;
 #endif
@@ -2021,7 +2022,6 @@
 		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 */
 		case '$': /* pid */
@@ -2194,16 +2194,16 @@
 				if (exp_op == '%' || exp_op == '#') {
 					if (val) {
 						/* we need to do a pattern match */
-						bool zero;
+						bool match_at_left;
 						char *loc;
-						scan_t scan = pick_scan(exp_op, *exp_word, &zero);
+						scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left);
 						if (exp_op == *exp_word)	/* ## or %% */
 							++exp_word;
 						val = dyn_val = xstrdup(val);
-						loc = scan(dyn_val, exp_word, zero);
-						if (zero)
+						loc = scan(dyn_val, exp_word, match_at_left);
+						if (match_at_left) /* # or ## */
 							val = loc;
-						else
+						else if (loc) /* % or %% and match was found */
 							*loc = '\0';
 					}
 				} else {
@@ -2263,11 +2263,11 @@
 			}
 		} /* default: */
 		} /* switch (char after <SPECIAL_VAR_SYMBOL>) */
+
 		if (val) {
 			o_addQstr(output, val, strlen(val));
 		}
 		free(dyn_val);
-		dyn_val = NULL;
 		/* Do the check to avoid writing to a const string */
 		if (*p != SPECIAL_VAR_SYMBOL)
 			*p = SPECIAL_VAR_SYMBOL;

Modified: trunk/busybox/shell/hush_test/hush-arith/arith.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-arith/arith.right	2009-04-26 01:43:36 UTC (rev 26209)
+++ trunk/busybox/shell/hush_test/hush-arith/arith.right	2009-04-26 11:25:19 UTC (rev 26210)
@@ -63,9 +63,9 @@
 40 40
 hush: error in arithmetic
 hush: divide by 0
-hush: can't exec 'let': No such file or directory
+hush: can't execute 'let': No such file or directory
 hush: error in arithmetic
-hush: can't exec 'let': No such file or directory
+hush: can't execute 'let': No such file or directory
 abc
 def
 ghi
@@ -135,4 +135,4 @@
 42
 42
 42
-hush: can't exec 'a[b[c]d]=e': No such file or directory
+hush: can't execute 'a[b[c]d]=e': No such file or directory

Modified: trunk/busybox/shell/hush_test/hush-vars/var_posix1.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-vars/var_posix1.right	2009-04-26 01:43:36 UTC (rev 26209)
+++ trunk/busybox/shell/hush_test/hush-vars/var_posix1.right	2009-04-26 11:25:19 UTC (rev 26210)
@@ -32,4 +32,5 @@
 ababcdcd
 Empty:
 ababcdcd}_tail
+ababcdcd
 end

Modified: trunk/busybox/shell/hush_test/hush-vars/var_posix1.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-vars/var_posix1.tests	2009-04-26 01:43:36 UTC (rev 26209)
+++ trunk/busybox/shell/hush_test/hush-vars/var_posix1.tests	2009-04-26 11:25:19 UTC (rev 26210)
@@ -43,5 +43,6 @@
 echo Empty:${var%%*}
 echo ${var#}}_tail
 # UNFIXED BUG: echo ${var#\}}_tail
+echo ${var%\\*}
 
 echo end

Modified: trunk/busybox/shell/match.c
===================================================================
--- trunk/busybox/shell/match.c	2009-04-26 01:43:36 UTC (rev 26209)
+++ trunk/busybox/shell/match.c	2009-04-26 11:25:19 UTC (rev 26210)
@@ -11,8 +11,6 @@
  * Kenneth Almquist.
  *
  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
- *
- * Original BSD copyright notice is retained at the end of this file.
  */
 #ifdef STANDALONE
 # include <stdbool.h>
@@ -28,7 +26,7 @@
 
 #define pmatch(a, b) !fnmatch((a), (b), 0)
 
-char *scanleft(char *string, char *pattern, bool zero)
+char *scanleft(char *string, char *pattern, bool match_at_left)
 {
 	char c;
 	char *loc = string;
@@ -38,7 +36,7 @@
 		const char *s;
 
 		c = *loc;
-		if (zero) {
+		if (match_at_left) {
 			*loc = '\0';
 			s = string;
 		} else
@@ -55,7 +53,7 @@
 	return NULL;
 }
 
-char *scanright(char *string, char *pattern, bool zero)
+char *scanright(char *string, char *pattern, bool match_at_left)
 {
 	char c;
 	char *loc = string + strlen(string);
@@ -65,7 +63,7 @@
 		const char *s;
 
 		c = *loc;
-		if (zero) {
+		if (match_at_left) {
 			*loc = '\0';
 			s = string;
 		} else
@@ -88,7 +86,7 @@
 	char *string;
 	char *op;
 	char *pattern;
-	bool zero;
+	bool match_at_left;
 	char *loc;
 
 	int i;
@@ -117,15 +115,15 @@
 			continue;
 		}
 		op = string + off;
-		scan = pick_scan(op[0], op[1], &zero);
+		scan = pick_scan(op[0], op[1], &match_at_left);
 		pattern = op + 1;
 		if (op[0] == op[1])
 			op[1] = '\0', ++pattern;
 		op[0] = '\0';
 
-		loc = scan(string, pattern, zero);
+		loc = scan(string, pattern, match_at_left);
 
-		if (zero) {
+		if (match_at_left) {
 			printf("'%s'\n", loc);
 		} else {
 			*loc = '\0';

Modified: trunk/busybox/shell/match.h
===================================================================
--- trunk/busybox/shell/match.h	2009-04-26 01:43:36 UTC (rev 26209)
+++ trunk/busybox/shell/match.h	2009-04-26 11:25:19 UTC (rev 26210)
@@ -2,12 +2,12 @@
 
 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
 
-typedef char *(*scan_t)(char *string, char *match, bool zero);
+typedef char *(*scan_t)(char *string, char *match, bool match_at_left);
 
-char *scanleft(char *string, char *match, bool zero);
-char *scanright(char *string, char *match, bool zero);
+char *scanleft(char *string, char *match, bool match_at_left);
+char *scanright(char *string, char *match, bool match_at_left);
 
-static inline scan_t pick_scan(char op1, char op2, bool *zero)
+static inline scan_t pick_scan(char op1, char op2, bool *match_at_left)
 {
 	/* #  - scanleft
 	 * ## - scanright
@@ -15,10 +15,10 @@
 	 * %% - scanleft
 	 */
 	if (op1 == '#') {
-		*zero = true;
+		*match_at_left = true;
 		return op1 == op2 ? scanright : scanleft;
 	} else {
-		*zero = false;
+		*match_at_left = false;
 		return op1 == op2 ? scanleft : scanright;
 	}
 }



More information about the busybox-cvs mailing list