~vcs-imports/busybox/main

« back to all changes in this revision

Viewing changes to shell/hush.c

  • Committer: vda
  • Date: 2009-04-26 11:25:19 UTC
  • Revision ID: vcs-imports@canonical.com-20090426112519-d75fs35iwdp7yx67
hush: fix SEGV in % expansion

function                                             old     new   delta
expand_variables                                    2203    2217     +14

Show diffs side-by-side

added added

removed removed

Lines of Context:
1990
1990
         * (expansion of right-hand side of assignment == 1-element expand.
1991
1991
         * It will also do no globbing, and thus we must not backslash-quote!) */
1992
1992
 
1993
 
        char first_ch, ored_ch;
1994
 
        int i;
1995
 
        const char *val;
1996
 
        char *dyn_val, *p;
 
1993
        char ored_ch;
 
1994
        char *p;
1997
1995
 
1998
 
        dyn_val = NULL;
1999
1996
        ored_ch = 0;
2000
1997
 
2001
1998
        debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg);
2004
2001
        debug_print_list("expand_vars_to_list[0]", output, n);
2005
2002
 
2006
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
2008
#if ENABLE_HUSH_TICK
2008
2009
                o_string subst_result = NULL_O_STRING;
2009
2010
#endif
2021
2022
                if ((first_ch & 0x7f) != '@')
2022
2023
                        ored_ch |= first_ch;
2023
2024
 
2024
 
                val = NULL;
2025
2025
                switch (first_ch & 0x7f) {
2026
2026
                /* Highest bit in first_ch indicates that var is double-quoted */
2027
2027
                case '$': /* pid */
2194
2194
                                if (exp_op == '%' || exp_op == '#') {
2195
2195
                                        if (val) {
2196
2196
                                                /* we need to do a pattern match */
2197
 
                                                bool zero;
 
2197
                                                bool match_at_left;
2198
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
2200
                                                if (exp_op == *exp_word)        /* ## or %% */
2201
2201
                                                        ++exp_word;
2202
2202
                                                val = dyn_val = xstrdup(val);
2203
 
                                                loc = scan(dyn_val, exp_word, zero);
2204
 
                                                if (zero)
 
2203
                                                loc = scan(dyn_val, exp_word, match_at_left);
 
2204
                                                if (match_at_left) /* # or ## */
2205
2205
                                                        val = loc;
2206
 
                                                else
 
2206
                                                else if (loc) /* % or %% and match was found */
2207
2207
                                                        *loc = '\0';
2208
2208
                                        }
2209
2209
                                } else {
2263
2263
                        }
2264
2264
                } /* default: */
2265
2265
                } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
 
2266
 
2266
2267
                if (val) {
2267
2268
                        o_addQstr(output, val, strlen(val));
2268
2269
                }
2269
2270
                free(dyn_val);
2270
 
                dyn_val = NULL;
2271
2271
                /* Do the check to avoid writing to a const string */
2272
2272
                if (*p != SPECIAL_VAR_SYMBOL)
2273
2273
                        *p = SPECIAL_VAR_SYMBOL;