diff options
author | Denys Vlasenko | 2018-04-04 21:14:28 +0200 |
---|---|---|
committer | Denys Vlasenko | 2018-04-04 21:14:28 +0200 |
commit | 61407807ab6b9505041a74ad96ffb4aeab937d36 (patch) | |
tree | eda659ec46e2d275d91ac9784dbd2095fb96da57 | |
parent | 759ca8a4cb57f797e92e02db84673057ce447125 (diff) | |
download | busybox-61407807ab6b9505041a74ad96ffb4aeab937d36.zip busybox-61407807ab6b9505041a74ad96ffb4aeab937d36.tar.gz |
hush: fix for readonly vars in "ro=A ro=B cmd" case
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 26 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/readonly3.right | 4 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/readonly3.tests | 4 |
3 files changed, 21 insertions, 13 deletions
diff --git a/shell/hush.c b/shell/hush.c index 3351072..6415312 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2134,7 +2134,7 @@ static const char* FAST_FUNC get_local_var_value(const char *name) #define SETFLAG_LOCAL_SHIFT 3 static int set_local_var(char *str, unsigned flags) { - struct variable **var_pp; + struct variable **cur_pp; struct variable *cur; char *free_me = NULL; char *eq_sign; @@ -2155,10 +2155,10 @@ static int set_local_var(char *str, unsigned flags) } #endif - var_pp = &G.top_var; - while ((cur = *var_pp) != NULL) { + cur_pp = &G.top_var; + while ((cur = *cur_pp) != NULL) { if (strncmp(cur->varstr, str, name_len) != 0) { - var_pp = &cur->next; + cur_pp = &cur->next; continue; } @@ -2182,7 +2182,7 @@ static int set_local_var(char *str, unsigned flags) * and existing one is global, or local * from enclosing function. * Remove and save old one: */ - *var_pp = cur->next; + *cur_pp = cur->next; cur->next = *G.shadowed_vars_pp; *G.shadowed_vars_pp = cur; /* bash 3.2.33(1) and exported vars: @@ -2226,8 +2226,8 @@ static int set_local_var(char *str, unsigned flags) /* Not found - create new variable struct */ cur = xzalloc(sizeof(*cur)); IF_HUSH_LOCAL(cur->func_nest_level = local_lvl;) - cur->next = *var_pp; - *var_pp = cur; + cur->next = *cur_pp; + *cur_pp = cur; set_str_and_exp: cur->varstr = str; @@ -2272,7 +2272,7 @@ static void set_pwd_var(unsigned flag) static int unset_local_var_len(const char *name, int name_len) { struct variable *cur; - struct variable **var_pp; + struct variable **cur_pp; if (!name) return EXIT_SUCCESS; @@ -2286,14 +2286,14 @@ static int unset_local_var_len(const char *name, int name_len) G.lineno_var = NULL; #endif - var_pp = &G.top_var; - while ((cur = *var_pp) != NULL) { + cur_pp = &G.top_var; + while ((cur = *cur_pp) != NULL) { if (strncmp(cur->varstr, name, name_len) == 0 && cur->varstr[name_len] == '=') { if (cur->flg_read_only) { bb_error_msg("%s: readonly variable", name); return EXIT_FAILURE; } - *var_pp = cur->next; + *cur_pp = cur->next; debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr); bb_unsetenv(cur->varstr); if (name_len == 3 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S') @@ -2303,7 +2303,7 @@ static int unset_local_var_len(const char *name, int name_len) free(cur); return EXIT_SUCCESS; } - var_pp = &cur->next; + cur_pp = &cur->next; } return EXIT_SUCCESS; } @@ -2402,8 +2402,8 @@ static struct variable *set_vars_and_save_old(char **strings) } set_local_var(*s, SETFLAG_EXPORT); } - next: s++; + next: ; } return old; } diff --git a/shell/hush_test/hush-vars/readonly3.right b/shell/hush_test/hush-vars/readonly3.right new file mode 100644 index 0000000..acd9312 --- /dev/null +++ b/shell/hush_test/hush-vars/readonly3.right @@ -0,0 +1,4 @@ +hush: v=2: readonly variable +hush: v=3: readonly variable +1 +Ok:1 diff --git a/shell/hush_test/hush-vars/readonly3.tests b/shell/hush_test/hush-vars/readonly3.tests new file mode 100755 index 0000000..17780cf --- /dev/null +++ b/shell/hush_test/hush-vars/readonly3.tests @@ -0,0 +1,4 @@ +readonly v=1 +# there was a bug causing second assignment to be not checked +v=2 v=3 echo $v +echo Ok:$v |