diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-26 11:25:19 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-26 11:25:19 +0000 |
commit | 5b7589eb27e748a3d281c0341219cf7435e8b4f1 (patch) | |
tree | b9565d8d331207ed37a3b9c0f654b500839d8ef6 /shell/hush.c | |
parent | 80e57eb7d525803bb776e8294483141756b2b2ef (diff) | |
download | busybox-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
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 24 |
1 files changed, 12 insertions, 12 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; |