From 116b50a5c1ea9d80d60641f2df2b61473b57fe47 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 19 Jul 2018 11:16:53 +0200 Subject: [PATCH] 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 --- shell/hush.c | 60 ++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 92c79b8b6..b738d2fd8 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 varname... 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 '`': /* `cmd */ + case '`': { /* `cmd */ + o_string subst_result = NULL_O_STRING; + *p = '\0'; /* replace trailing */ 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 '+': { /* +cmd */ @@ -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 ) */ 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) ..." */