diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-19 11:16:53 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-20 16:27:26 +0200 |
commit | 116b50a5c1ea9d80d60641f2df2b61473b57fe47 (patch) | |
tree | 0ea47e24ab66d3708c3b85d13ad4dabbb0dfa7a6 | |
parent | e36a5894bd24a28b3529998bb7d0f87d7f5eb61b (diff) | |
download | busybox-w32-116b50a5c1ea9d80d60641f2df2b61473b57fe47.tar.gz busybox-w32-116b50a5c1ea9d80d60641f2df2b61473b57fe47.tar.bz2 busybox-w32-116b50a5c1ea9d80d60641f2df2b61473b57fe47.zip |
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 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 | |||
5955 | } | 5955 | } |
5956 | #endif /* BASH_PATTERN_SUBST */ | 5956 | #endif /* BASH_PATTERN_SUBST */ |
5957 | 5957 | ||
5958 | static int append_str_maybe_ifs_split(o_string *output, int *ended_in_ifs, int n, | ||
5959 | int first_ch, const char *val) | ||
5960 | { | ||
5961 | if (!(first_ch & 0x80)) { /* unquoted $VAR */ | ||
5962 | debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, | ||
5963 | !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); | ||
5964 | if (val && val[0]) | ||
5965 | n = expand_on_ifs(ended_in_ifs, output, n, val); | ||
5966 | } else { /* quoted "$VAR" */ | ||
5967 | output->has_quoted_part = 1; | ||
5968 | debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, | ||
5969 | !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); | ||
5970 | if (val && val[0]) | ||
5971 | o_addQstr(output, val); | ||
5972 | } | ||
5973 | return n; | ||
5974 | } | ||
5975 | |||
5958 | /* Helper: | 5976 | /* Helper: |
5959 | * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. | 5977 | * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. |
5960 | */ | 5978 | */ |
@@ -6290,11 +6308,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) | |||
6290 | 6308 | ||
6291 | while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { | 6309 | while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { |
6292 | char first_ch; | 6310 | char first_ch; |
6293 | char *to_be_freed = NULL; | ||
6294 | const char *val = NULL; | 6311 | const char *val = NULL; |
6295 | #if ENABLE_HUSH_TICK | ||
6296 | o_string subst_result = NULL_O_STRING; | ||
6297 | #endif | ||
6298 | #if ENABLE_FEATURE_SH_MATH | 6312 | #if ENABLE_FEATURE_SH_MATH |
6299 | char arith_buf[sizeof(arith_t)*3 + 2]; | 6313 | char arith_buf[sizeof(arith_t)*3 + 2]; |
6300 | #endif | 6314 | #endif |
@@ -6382,7 +6396,9 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) | |||
6382 | val = SPECIAL_VAR_SYMBOL_STR; | 6396 | val = SPECIAL_VAR_SYMBOL_STR; |
6383 | break; | 6397 | break; |
6384 | #if ENABLE_HUSH_TICK | 6398 | #if ENABLE_HUSH_TICK |
6385 | case '`': /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */ | 6399 | case '`': { /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */ |
6400 | o_string subst_result = NULL_O_STRING; | ||
6401 | |||
6386 | *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */ | 6402 | *p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */ |
6387 | arg++; | 6403 | arg++; |
6388 | /* Can't just stuff it into output o_string, | 6404 | /* 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) | |||
6392 | G.last_exitcode = process_command_subs(&subst_result, arg); | 6408 | G.last_exitcode = process_command_subs(&subst_result, arg); |
6393 | G.expand_exitcode = G.last_exitcode; | 6409 | G.expand_exitcode = G.last_exitcode; |
6394 | debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); | 6410 | debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); |
6395 | val = subst_result.data; | 6411 | n = append_str_maybe_ifs_split(output, &ended_in_ifs, n, first_ch, subst_result.data); |
6396 | goto store_val; | 6412 | o_free_unsafe(&subst_result); |
6413 | goto restore; | ||
6414 | } | ||
6397 | #endif | 6415 | #endif |
6398 | #if ENABLE_FEATURE_SH_MATH | 6416 | #if ENABLE_FEATURE_SH_MATH |
6399 | case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */ | 6417 | 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) | |||
6409 | break; | 6427 | break; |
6410 | } | 6428 | } |
6411 | #endif | 6429 | #endif |
6412 | default: | 6430 | default: { |
6431 | char *to_be_freed; | ||
6413 | val = expand_one_var(&to_be_freed, arg, &p); | 6432 | val = expand_one_var(&to_be_freed, arg, &p); |
6414 | IF_HUSH_TICK(store_val:) | 6433 | n = append_str_maybe_ifs_split(output, &ended_in_ifs, n, first_ch, val); |
6415 | if (!(first_ch & 0x80)) { /* unquoted $VAR */ | 6434 | free(to_be_freed); |
6416 | debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, | 6435 | goto restore; |
6417 | !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); | 6436 | } /* default: */ |
6418 | if (val && val[0]) { | ||
6419 | n = expand_on_ifs(&ended_in_ifs, output, n, val); | ||
6420 | val = NULL; | ||
6421 | } | ||
6422 | } else { /* quoted $VAR, val will be appended below */ | ||
6423 | output->has_quoted_part = 1; | ||
6424 | debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, | ||
6425 | !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); | ||
6426 | } | ||
6427 | break; | ||
6428 | } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ | 6437 | } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ |
6429 | 6438 | ||
6430 | if (val && val[0]) { | 6439 | if (val && val[0]) { |
6431 | o_addQstr(output, val); | 6440 | o_addQstr(output, val); |
6432 | } | 6441 | } |
6433 | free(to_be_freed); | 6442 | restore: |
6434 | |||
6435 | /* Restore NULL'ed SPECIAL_VAR_SYMBOL. | 6443 | /* Restore NULL'ed SPECIAL_VAR_SYMBOL. |
6436 | * Do the check to avoid writing to a const string. */ | 6444 | * Do the check to avoid writing to a const string. */ |
6437 | if (*p != SPECIAL_VAR_SYMBOL) | 6445 | if (*p != SPECIAL_VAR_SYMBOL) |
6438 | *p = SPECIAL_VAR_SYMBOL; | 6446 | *p = SPECIAL_VAR_SYMBOL; |
6439 | |||
6440 | #if ENABLE_HUSH_TICK | ||
6441 | o_free(&subst_result); | ||
6442 | #endif | ||
6443 | arg = ++p; | 6447 | arg = ++p; |
6444 | } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */ | 6448 | } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */ |
6445 | 6449 | ||