aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-26 11:25:19 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-26 11:25:19 +0000
commit5b7589eb27e748a3d281c0341219cf7435e8b4f1 (patch)
treeb9565d8d331207ed37a3b9c0f654b500839d8ef6
parent80e57eb7d525803bb776e8294483141756b2b2ef (diff)
downloadbusybox-w32-5b7589eb27e748a3d281c0341219cf7435e8b4f1.tar.gz
busybox-w32-5b7589eb27e748a3d281c0341219cf7435e8b4f1.tar.bz2
busybox-w32-5b7589eb27e748a3d281c0341219cf7435e8b4f1.zip
hush: fix SEGV in % expansion
function old new delta expand_variables 2203 2217 +14
-rw-r--r--shell/hush.c24
-rw-r--r--shell/hush_test/hush-arith/arith.right6
-rw-r--r--shell/hush_test/hush-vars/var_posix1.right1
-rwxr-xr-xshell/hush_test/hush-vars/var_posix1.tests1
-rw-r--r--shell/match.c18
-rw-r--r--shell/match.h12
6 files changed, 31 insertions, 31 deletions
diff --git a/shell/hush.c b/shell/hush.c
index fcbd96c4d..2ad8ebacb 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1990,12 +1990,9 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
1990 * (expansion of right-hand side of assignment == 1-element expand. 1990 * (expansion of right-hand side of assignment == 1-element expand.
1991 * It will also do no globbing, and thus we must not backslash-quote!) */ 1991 * It will also do no globbing, and thus we must not backslash-quote!) */
1992 1992
1993 char first_ch, ored_ch; 1993 char ored_ch;
1994 int i; 1994 char *p;
1995 const char *val;
1996 char *dyn_val, *p;
1997 1995
1998 dyn_val = NULL;
1999 ored_ch = 0; 1996 ored_ch = 0;
2000 1997
2001 debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg); 1998 debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg);
@@ -2004,6 +2001,10 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2004 debug_print_list("expand_vars_to_list[0]", output, n); 2001 debug_print_list("expand_vars_to_list[0]", output, n);
2005 2002
2006 while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { 2003 while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
2004 char first_ch;
2005 int i;
2006 char *dyn_val = NULL;
2007 const char *val = NULL;
2007#if ENABLE_HUSH_TICK 2008#if ENABLE_HUSH_TICK
2008 o_string subst_result = NULL_O_STRING; 2009 o_string subst_result = NULL_O_STRING;
2009#endif 2010#endif
@@ -2021,7 +2022,6 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2021 if ((first_ch & 0x7f) != '@') 2022 if ((first_ch & 0x7f) != '@')
2022 ored_ch |= first_ch; 2023 ored_ch |= first_ch;
2023 2024
2024 val = NULL;
2025 switch (first_ch & 0x7f) { 2025 switch (first_ch & 0x7f) {
2026 /* Highest bit in first_ch indicates that var is double-quoted */ 2026 /* Highest bit in first_ch indicates that var is double-quoted */
2027 case '$': /* pid */ 2027 case '$': /* pid */
@@ -2194,16 +2194,16 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2194 if (exp_op == '%' || exp_op == '#') { 2194 if (exp_op == '%' || exp_op == '#') {
2195 if (val) { 2195 if (val) {
2196 /* we need to do a pattern match */ 2196 /* we need to do a pattern match */
2197 bool zero; 2197 bool match_at_left;
2198 char *loc; 2198 char *loc;
2199 scan_t scan = pick_scan(exp_op, *exp_word, &zero); 2199 scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left);
2200 if (exp_op == *exp_word) /* ## or %% */ 2200 if (exp_op == *exp_word) /* ## or %% */
2201 ++exp_word; 2201 ++exp_word;
2202 val = dyn_val = xstrdup(val); 2202 val = dyn_val = xstrdup(val);
2203 loc = scan(dyn_val, exp_word, zero); 2203 loc = scan(dyn_val, exp_word, match_at_left);
2204 if (zero) 2204 if (match_at_left) /* # or ## */
2205 val = loc; 2205 val = loc;
2206 else 2206 else if (loc) /* % or %% and match was found */
2207 *loc = '\0'; 2207 *loc = '\0';
2208 } 2208 }
2209 } else { 2209 } else {
@@ -2263,11 +2263,11 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2263 } 2263 }
2264 } /* default: */ 2264 } /* default: */
2265 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ 2265 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
2266
2266 if (val) { 2267 if (val) {
2267 o_addQstr(output, val, strlen(val)); 2268 o_addQstr(output, val, strlen(val));
2268 } 2269 }
2269 free(dyn_val); 2270 free(dyn_val);
2270 dyn_val = NULL;
2271 /* Do the check to avoid writing to a const string */ 2271 /* Do the check to avoid writing to a const string */
2272 if (*p != SPECIAL_VAR_SYMBOL) 2272 if (*p != SPECIAL_VAR_SYMBOL)
2273 *p = SPECIAL_VAR_SYMBOL; 2273 *p = SPECIAL_VAR_SYMBOL;
diff --git a/shell/hush_test/hush-arith/arith.right b/shell/hush_test/hush-arith/arith.right
index 8cde0ee53..83155fb03 100644
--- a/shell/hush_test/hush-arith/arith.right
+++ b/shell/hush_test/hush-arith/arith.right
@@ -63,9 +63,9 @@ hush: error in arithmetic
6340 40 6340 40
64hush: error in arithmetic 64hush: error in arithmetic
65hush: divide by 0 65hush: divide by 0
66hush: can't exec 'let': No such file or directory 66hush: can't execute 'let': No such file or directory
67hush: error in arithmetic 67hush: error in arithmetic
68hush: can't exec 'let': No such file or directory 68hush: can't execute 'let': No such file or directory
69abc 69abc
70def 70def
71ghi 71ghi
@@ -135,4 +135,4 @@ hush: error in arithmetic
13542 13542
13642 13642
13742 13742
138hush: can't exec 'a[b[c]d]=e': No such file or directory 138hush: can't execute 'a[b[c]d]=e': No such file or directory
diff --git a/shell/hush_test/hush-vars/var_posix1.right b/shell/hush_test/hush-vars/var_posix1.right
index 47d52a6c2..e6cba2758 100644
--- a/shell/hush_test/hush-vars/var_posix1.right
+++ b/shell/hush_test/hush-vars/var_posix1.right
@@ -32,4 +32,5 @@ ababcdc
32ababcdcd 32ababcdcd
33Empty: 33Empty:
34ababcdcd}_tail 34ababcdcd}_tail
35ababcdcd
35end 36end
diff --git a/shell/hush_test/hush-vars/var_posix1.tests b/shell/hush_test/hush-vars/var_posix1.tests
index 3069360e1..c1f64094d 100755
--- a/shell/hush_test/hush-vars/var_posix1.tests
+++ b/shell/hush_test/hush-vars/var_posix1.tests
@@ -43,5 +43,6 @@ echo ${var%*}
43echo Empty:${var%%*} 43echo Empty:${var%%*}
44echo ${var#}}_tail 44echo ${var#}}_tail
45# UNFIXED BUG: echo ${var#\}}_tail 45# UNFIXED BUG: echo ${var#\}}_tail
46echo ${var%\\*}
46 47
47echo end 48echo end
diff --git a/shell/match.c b/shell/match.c
index 47038d667..a7101ef7e 100644
--- a/shell/match.c
+++ b/shell/match.c
@@ -11,8 +11,6 @@
11 * Kenneth Almquist. 11 * Kenneth Almquist.
12 * 12 *
13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
14 *
15 * Original BSD copyright notice is retained at the end of this file.
16 */ 14 */
17#ifdef STANDALONE 15#ifdef STANDALONE
18# include <stdbool.h> 16# include <stdbool.h>
@@ -28,7 +26,7 @@
28 26
29#define pmatch(a, b) !fnmatch((a), (b), 0) 27#define pmatch(a, b) !fnmatch((a), (b), 0)
30 28
31char *scanleft(char *string, char *pattern, bool zero) 29char *scanleft(char *string, char *pattern, bool match_at_left)
32{ 30{
33 char c; 31 char c;
34 char *loc = string; 32 char *loc = string;
@@ -38,7 +36,7 @@ char *scanleft(char *string, char *pattern, bool zero)
38 const char *s; 36 const char *s;
39 37
40 c = *loc; 38 c = *loc;
41 if (zero) { 39 if (match_at_left) {
42 *loc = '\0'; 40 *loc = '\0';
43 s = string; 41 s = string;
44 } else 42 } else
@@ -55,7 +53,7 @@ char *scanleft(char *string, char *pattern, bool zero)
55 return NULL; 53 return NULL;
56} 54}
57 55
58char *scanright(char *string, char *pattern, bool zero) 56char *scanright(char *string, char *pattern, bool match_at_left)
59{ 57{
60 char c; 58 char c;
61 char *loc = string + strlen(string); 59 char *loc = string + strlen(string);
@@ -65,7 +63,7 @@ char *scanright(char *string, char *pattern, bool zero)
65 const char *s; 63 const char *s;
66 64
67 c = *loc; 65 c = *loc;
68 if (zero) { 66 if (match_at_left) {
69 *loc = '\0'; 67 *loc = '\0';
70 s = string; 68 s = string;
71 } else 69 } else
@@ -88,7 +86,7 @@ int main(int argc, char *argv[])
88 char *string; 86 char *string;
89 char *op; 87 char *op;
90 char *pattern; 88 char *pattern;
91 bool zero; 89 bool match_at_left;
92 char *loc; 90 char *loc;
93 91
94 int i; 92 int i;
@@ -117,15 +115,15 @@ int main(int argc, char *argv[])
117 continue; 115 continue;
118 } 116 }
119 op = string + off; 117 op = string + off;
120 scan = pick_scan(op[0], op[1], &zero); 118 scan = pick_scan(op[0], op[1], &match_at_left);
121 pattern = op + 1; 119 pattern = op + 1;
122 if (op[0] == op[1]) 120 if (op[0] == op[1])
123 op[1] = '\0', ++pattern; 121 op[1] = '\0', ++pattern;
124 op[0] = '\0'; 122 op[0] = '\0';
125 123
126 loc = scan(string, pattern, zero); 124 loc = scan(string, pattern, match_at_left);
127 125
128 if (zero) { 126 if (match_at_left) {
129 printf("'%s'\n", loc); 127 printf("'%s'\n", loc);
130 } else { 128 } else {
131 *loc = '\0'; 129 *loc = '\0';
diff --git a/shell/match.h b/shell/match.h
index 3fc4de340..90597ee54 100644
--- a/shell/match.h
+++ b/shell/match.h
@@ -2,12 +2,12 @@
2 2
3PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 3PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
4 4
5typedef char *(*scan_t)(char *string, char *match, bool zero); 5typedef char *(*scan_t)(char *string, char *match, bool match_at_left);
6 6
7char *scanleft(char *string, char *match, bool zero); 7char *scanleft(char *string, char *match, bool match_at_left);
8char *scanright(char *string, char *match, bool zero); 8char *scanright(char *string, char *match, bool match_at_left);
9 9
10static inline scan_t pick_scan(char op1, char op2, bool *zero) 10static inline scan_t pick_scan(char op1, char op2, bool *match_at_left)
11{ 11{
12 /* # - scanleft 12 /* # - scanleft
13 * ## - scanright 13 * ## - scanright
@@ -15,10 +15,10 @@ static inline scan_t pick_scan(char op1, char op2, bool *zero)
15 * %% - scanleft 15 * %% - scanleft
16 */ 16 */
17 if (op1 == '#') { 17 if (op1 == '#') {
18 *zero = true; 18 *match_at_left = true;
19 return op1 == op2 ? scanright : scanleft; 19 return op1 == op2 ? scanright : scanleft;
20 } else { 20 } else {
21 *zero = false; 21 *match_at_left = false;
22 return op1 == op2 ? scanleft : scanright; 22 return op1 == op2 ? scanleft : scanright;
23 } 23 }
24} 24}