diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-06-26 15:36:58 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-06-26 15:36:58 +0200 |
commit | 99496dc7160552824d6146ec951b2f7b03a51759 (patch) | |
tree | 26f501d395d80450eaed690c13442651d202bd94 | |
parent | 817a20296fd9e4e8eed095836d7dc28183794247 (diff) | |
download | busybox-w32-99496dc7160552824d6146ec951b2f7b03a51759.tar.gz busybox-w32-99496dc7160552824d6146ec951b2f7b03a51759.tar.bz2 busybox-w32-99496dc7160552824d6146ec951b2f7b03a51759.zip |
hush: variable nesting code is used also if HUSH_FUNCTIONS is not enabled
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 104 |
1 files changed, 52 insertions, 52 deletions
diff --git a/shell/hush.c b/shell/hush.c index 0b36dad80..738a6b286 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -7314,6 +7314,58 @@ static const struct built_in_command *find_builtin(const char *name) | |||
7314 | return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); | 7314 | return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); |
7315 | } | 7315 | } |
7316 | 7316 | ||
7317 | static void remove_nested_vars(void) | ||
7318 | { | ||
7319 | struct variable *cur; | ||
7320 | struct variable **cur_pp; | ||
7321 | |||
7322 | cur_pp = &G.top_var; | ||
7323 | while ((cur = *cur_pp) != NULL) { | ||
7324 | if (cur->var_nest_level <= G.var_nest_level) { | ||
7325 | cur_pp = &cur->next; | ||
7326 | continue; | ||
7327 | } | ||
7328 | /* Unexport */ | ||
7329 | if (cur->flg_export) { | ||
7330 | debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level); | ||
7331 | bb_unsetenv(cur->varstr); | ||
7332 | } | ||
7333 | /* Remove from global list */ | ||
7334 | *cur_pp = cur->next; | ||
7335 | /* Free */ | ||
7336 | if (!cur->max_len) { | ||
7337 | debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level); | ||
7338 | free(cur->varstr); | ||
7339 | } | ||
7340 | free(cur); | ||
7341 | } | ||
7342 | } | ||
7343 | |||
7344 | static void enter_var_nest_level(void) | ||
7345 | { | ||
7346 | G.var_nest_level++; | ||
7347 | debug_printf_env("var_nest_level++ %u\n", G.var_nest_level); | ||
7348 | |||
7349 | /* Try: f() { echo -n .; f; }; f | ||
7350 | * struct variable::var_nest_level is uint16_t, | ||
7351 | * thus limiting recursion to < 2^16. | ||
7352 | * In any case, with 8 Mbyte stack SEGV happens | ||
7353 | * not too long after 2^16 recursions anyway. | ||
7354 | */ | ||
7355 | if (G.var_nest_level > 0xff00) | ||
7356 | bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level); | ||
7357 | } | ||
7358 | |||
7359 | static void leave_var_nest_level(void) | ||
7360 | { | ||
7361 | G.var_nest_level--; | ||
7362 | debug_printf_env("var_nest_level-- %u\n", G.var_nest_level); | ||
7363 | if (HUSH_DEBUG && (int)G.var_nest_level < 0) | ||
7364 | bb_error_msg_and_die("BUG: nesting underflow"); | ||
7365 | |||
7366 | remove_nested_vars(); | ||
7367 | } | ||
7368 | |||
7317 | #if ENABLE_HUSH_FUNCTIONS | 7369 | #if ENABLE_HUSH_FUNCTIONS |
7318 | static struct function **find_function_slot(const char *name) | 7370 | static struct function **find_function_slot(const char *name) |
7319 | { | 7371 | { |
@@ -7400,58 +7452,6 @@ static void unset_func(const char *name) | |||
7400 | } | 7452 | } |
7401 | # endif | 7453 | # endif |
7402 | 7454 | ||
7403 | static void remove_nested_vars(void) | ||
7404 | { | ||
7405 | struct variable *cur; | ||
7406 | struct variable **cur_pp; | ||
7407 | |||
7408 | cur_pp = &G.top_var; | ||
7409 | while ((cur = *cur_pp) != NULL) { | ||
7410 | if (cur->var_nest_level <= G.var_nest_level) { | ||
7411 | cur_pp = &cur->next; | ||
7412 | continue; | ||
7413 | } | ||
7414 | /* Unexport */ | ||
7415 | if (cur->flg_export) { | ||
7416 | debug_printf_env("unexporting nested '%s'/%u\n", cur->varstr, cur->var_nest_level); | ||
7417 | bb_unsetenv(cur->varstr); | ||
7418 | } | ||
7419 | /* Remove from global list */ | ||
7420 | *cur_pp = cur->next; | ||
7421 | /* Free */ | ||
7422 | if (!cur->max_len) { | ||
7423 | debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level); | ||
7424 | free(cur->varstr); | ||
7425 | } | ||
7426 | free(cur); | ||
7427 | } | ||
7428 | } | ||
7429 | |||
7430 | static void enter_var_nest_level(void) | ||
7431 | { | ||
7432 | G.var_nest_level++; | ||
7433 | debug_printf_env("var_nest_level++ %u\n", G.var_nest_level); | ||
7434 | |||
7435 | /* Try: f() { echo -n .; f; }; f | ||
7436 | * struct variable::var_nest_level is uint16_t, | ||
7437 | * thus limiting recursion to < 2^16. | ||
7438 | * In any case, with 8 Mbyte stack SEGV happens | ||
7439 | * not too long after 2^16 recursions anyway. | ||
7440 | */ | ||
7441 | if (G.var_nest_level > 0xff00) | ||
7442 | bb_error_msg_and_die("fatal recursion (depth %u)", G.var_nest_level); | ||
7443 | } | ||
7444 | |||
7445 | static void leave_var_nest_level(void) | ||
7446 | { | ||
7447 | G.var_nest_level--; | ||
7448 | debug_printf_env("var_nest_level-- %u\n", G.var_nest_level); | ||
7449 | if (HUSH_DEBUG && (int)G.var_nest_level < 0) | ||
7450 | bb_error_msg_and_die("BUG: nesting underflow"); | ||
7451 | |||
7452 | remove_nested_vars(); | ||
7453 | } | ||
7454 | |||
7455 | # if BB_MMU | 7455 | # if BB_MMU |
7456 | #define exec_function(to_free, funcp, argv) \ | 7456 | #define exec_function(to_free, funcp, argv) \ |
7457 | exec_function(funcp, argv) | 7457 | exec_function(funcp, argv) |