aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-06-26 15:36:58 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-06-26 15:36:58 +0200
commit99496dc7160552824d6146ec951b2f7b03a51759 (patch)
tree26f501d395d80450eaed690c13442651d202bd94
parent817a20296fd9e4e8eed095836d7dc28183794247 (diff)
downloadbusybox-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.c104
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
7317static 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
7344static 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
7359static 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
7318static struct function **find_function_slot(const char *name) 7370static 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
7403static 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
7430static 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
7445static 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)