diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-04 21:14:28 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-04 21:14:28 +0200 |
commit | 61407807ab6b9505041a74ad96ffb4aeab937d36 (patch) | |
tree | eda659ec46e2d275d91ac9784dbd2095fb96da57 | |
parent | 759ca8a4cb57f797e92e02db84673057ce447125 (diff) | |
download | busybox-w32-61407807ab6b9505041a74ad96ffb4aeab937d36.tar.gz busybox-w32-61407807ab6b9505041a74ad96ffb4aeab937d36.tar.bz2 busybox-w32-61407807ab6b9505041a74ad96ffb4aeab937d36.zip |
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 335107283..641531209 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) | |||
2134 | #define SETFLAG_LOCAL_SHIFT 3 | 2134 | #define SETFLAG_LOCAL_SHIFT 3 |
2135 | static int set_local_var(char *str, unsigned flags) | 2135 | static int set_local_var(char *str, unsigned flags) |
2136 | { | 2136 | { |
2137 | struct variable **var_pp; | 2137 | struct variable **cur_pp; |
2138 | struct variable *cur; | 2138 | struct variable *cur; |
2139 | char *free_me = NULL; | 2139 | char *free_me = NULL; |
2140 | char *eq_sign; | 2140 | char *eq_sign; |
@@ -2155,10 +2155,10 @@ static int set_local_var(char *str, unsigned flags) | |||
2155 | } | 2155 | } |
2156 | #endif | 2156 | #endif |
2157 | 2157 | ||
2158 | var_pp = &G.top_var; | 2158 | cur_pp = &G.top_var; |
2159 | while ((cur = *var_pp) != NULL) { | 2159 | while ((cur = *cur_pp) != NULL) { |
2160 | if (strncmp(cur->varstr, str, name_len) != 0) { | 2160 | if (strncmp(cur->varstr, str, name_len) != 0) { |
2161 | var_pp = &cur->next; | 2161 | cur_pp = &cur->next; |
2162 | continue; | 2162 | continue; |
2163 | } | 2163 | } |
2164 | 2164 | ||
@@ -2182,7 +2182,7 @@ static int set_local_var(char *str, unsigned flags) | |||
2182 | * and existing one is global, or local | 2182 | * and existing one is global, or local |
2183 | * from enclosing function. | 2183 | * from enclosing function. |
2184 | * Remove and save old one: */ | 2184 | * Remove and save old one: */ |
2185 | *var_pp = cur->next; | 2185 | *cur_pp = cur->next; |
2186 | cur->next = *G.shadowed_vars_pp; | 2186 | cur->next = *G.shadowed_vars_pp; |
2187 | *G.shadowed_vars_pp = cur; | 2187 | *G.shadowed_vars_pp = cur; |
2188 | /* bash 3.2.33(1) and exported vars: | 2188 | /* bash 3.2.33(1) and exported vars: |
@@ -2226,8 +2226,8 @@ static int set_local_var(char *str, unsigned flags) | |||
2226 | /* Not found - create new variable struct */ | 2226 | /* Not found - create new variable struct */ |
2227 | cur = xzalloc(sizeof(*cur)); | 2227 | cur = xzalloc(sizeof(*cur)); |
2228 | IF_HUSH_LOCAL(cur->func_nest_level = local_lvl;) | 2228 | IF_HUSH_LOCAL(cur->func_nest_level = local_lvl;) |
2229 | cur->next = *var_pp; | 2229 | cur->next = *cur_pp; |
2230 | *var_pp = cur; | 2230 | *cur_pp = cur; |
2231 | 2231 | ||
2232 | set_str_and_exp: | 2232 | set_str_and_exp: |
2233 | cur->varstr = str; | 2233 | cur->varstr = str; |
@@ -2272,7 +2272,7 @@ static void set_pwd_var(unsigned flag) | |||
2272 | static int unset_local_var_len(const char *name, int name_len) | 2272 | static int unset_local_var_len(const char *name, int name_len) |
2273 | { | 2273 | { |
2274 | struct variable *cur; | 2274 | struct variable *cur; |
2275 | struct variable **var_pp; | 2275 | struct variable **cur_pp; |
2276 | 2276 | ||
2277 | if (!name) | 2277 | if (!name) |
2278 | return EXIT_SUCCESS; | 2278 | return EXIT_SUCCESS; |
@@ -2286,14 +2286,14 @@ static int unset_local_var_len(const char *name, int name_len) | |||
2286 | G.lineno_var = NULL; | 2286 | G.lineno_var = NULL; |
2287 | #endif | 2287 | #endif |
2288 | 2288 | ||
2289 | var_pp = &G.top_var; | 2289 | cur_pp = &G.top_var; |
2290 | while ((cur = *var_pp) != NULL) { | 2290 | while ((cur = *cur_pp) != NULL) { |
2291 | if (strncmp(cur->varstr, name, name_len) == 0 && cur->varstr[name_len] == '=') { | 2291 | if (strncmp(cur->varstr, name, name_len) == 0 && cur->varstr[name_len] == '=') { |
2292 | if (cur->flg_read_only) { | 2292 | if (cur->flg_read_only) { |
2293 | bb_error_msg("%s: readonly variable", name); | 2293 | bb_error_msg("%s: readonly variable", name); |
2294 | return EXIT_FAILURE; | 2294 | return EXIT_FAILURE; |
2295 | } | 2295 | } |
2296 | *var_pp = cur->next; | 2296 | *cur_pp = cur->next; |
2297 | debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr); | 2297 | debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr); |
2298 | bb_unsetenv(cur->varstr); | 2298 | bb_unsetenv(cur->varstr); |
2299 | if (name_len == 3 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S') | 2299 | 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) | |||
2303 | free(cur); | 2303 | free(cur); |
2304 | return EXIT_SUCCESS; | 2304 | return EXIT_SUCCESS; |
2305 | } | 2305 | } |
2306 | var_pp = &cur->next; | 2306 | cur_pp = &cur->next; |
2307 | } | 2307 | } |
2308 | return EXIT_SUCCESS; | 2308 | return EXIT_SUCCESS; |
2309 | } | 2309 | } |
@@ -2402,8 +2402,8 @@ static struct variable *set_vars_and_save_old(char **strings) | |||
2402 | } | 2402 | } |
2403 | set_local_var(*s, SETFLAG_EXPORT); | 2403 | set_local_var(*s, SETFLAG_EXPORT); |
2404 | } | 2404 | } |
2405 | next: | ||
2406 | s++; | 2405 | s++; |
2406 | next: ; | ||
2407 | } | 2407 | } |
2408 | return old; | 2408 | return old; |
2409 | } | 2409 | } |
diff --git a/shell/hush_test/hush-vars/readonly3.right b/shell/hush_test/hush-vars/readonly3.right new file mode 100644 index 000000000..acd931243 --- /dev/null +++ b/shell/hush_test/hush-vars/readonly3.right | |||
@@ -0,0 +1,4 @@ | |||
1 | hush: v=2: readonly variable | ||
2 | hush: v=3: readonly variable | ||
3 | 1 | ||
4 | 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 000000000..17780cfda --- /dev/null +++ b/shell/hush_test/hush-vars/readonly3.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | readonly v=1 | ||
2 | # there was a bug causing second assignment to be not checked | ||
3 | v=2 v=3 echo $v | ||
4 | echo Ok:$v | ||