diff options
author | Denys Vlasenko | 2018-07-19 11:16:53 +0200 |
---|---|---|
committer | Denys Vlasenko | 2018-07-20 16:27:26 +0200 |
commit | 116b50a5c1ea9d80d60641f2df2b61473b57fe47 (patch) | |
tree | 0ea47e24ab66d3708c3b85d13ad4dabbb0dfa7a6 | |
parent | e36a5894bd24a28b3529998bb7d0f87d7f5eb61b (diff) | |
download | busybox-116b50a5c1ea9d80d60641f2df2b61473b57fe47.zip busybox-116b50a5c1ea9d80d60641f2df2b61473b57fe47.tar.gz |
hush: make expand_vars_to_list() a bit more sane
function old new delta
append_str_maybe_ifs_split - 64 +64
expand_vars_to_list 1167 1139 -28
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 64/-28) Total: 36 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c index 92c79b8..b738d2f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -5955,6 +5955,24 @@ static char *replace_pattern(char *val, const char *pattern, const char *repl, c } #endif /* BASH_PATTERN_SUBST */ +static int append_str_maybe_ifs_split(o_string *output, int *ended_in_ifs, int n, + int first_ch, const char *val) +{ + if (!(first_ch & 0x80)) { /* unquoted $VAR */ + debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, + !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); + if (val && val[0]) + n = expand_on_ifs(ended_in_ifs, output, n, val); + } else { /* quoted "$VAR" */ + output->has_quoted_part = 1; + debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, + !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); + if (val && val[0]) + o_addQstr(output, val); + } + return n; +} + /* Helper: * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. */ @@ -6290,11 +6308,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { char first_ch; - char *to_be_freed = NULL; const char *val = NULL; -#if ENABLE_HUSH_TICK - o_string subst_result = NULL_O_STRING; -#endif #if ENABLE_FEATURE_SH_MATH char arith_buf[sizeof(arith_t)*3 + 2]; #endif @@ -6382,7 +6396,9 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) val = SPECIAL_VAR_SYMBOL_STR; break; #if ENABLE_HUSH_TICK - case '`': /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */ + case '`': { /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */ + o_string subst_result = NULL_O_STRING; + *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */ arg++; /* Can't just stuff it into output o_string, @@ -6392,8 +6408,10 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) G.last_exitcode = process_command_subs(&subst_result, arg); G.expand_exitcode = G.last_exitcode; debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); - val = subst_result.data; - goto store_val; + n = append_str_maybe_ifs_split(output, &ended_in_ifs, n, first_ch, subst_result.data); + o_free_unsafe(&subst_result); + goto restore; + } #endif #if ENABLE_FEATURE_SH_MATH case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */ @@ -6409,37 +6427,23 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) break; } #endif - default: + default: { + char *to_be_freed; val = expand_one_var(&to_be_freed, arg, &p); - IF_HUSH_TICK(store_val:) - if (!(first_ch & 0x80)) { /* unquoted $VAR */ - debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, - !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); - if (val && val[0]) { - n = expand_on_ifs(&ended_in_ifs, output, n, val); - val = NULL; - } - } else { /* quoted $VAR, val will be appended below */ - output->has_quoted_part = 1; - debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, - !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); - } - break; + n = append_str_maybe_ifs_split(output, &ended_in_ifs, n, first_ch, val); + free(to_be_freed); + goto restore; + } /* default: */ } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ if (val && val[0]) { o_addQstr(output, val); } - free(to_be_freed); - + restore: /* Restore NULL'ed SPECIAL_VAR_SYMBOL. * Do the check to avoid writing to a const string. */ if (*p != SPECIAL_VAR_SYMBOL) *p = SPECIAL_VAR_SYMBOL; - -#if ENABLE_HUSH_TICK - o_free(&subst_result); -#endif arg = ++p; } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */ |