summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko2018-04-04 21:14:28 +0200
committerDenys Vlasenko2018-04-04 21:14:28 +0200
commit61407807ab6b9505041a74ad96ffb4aeab937d36 (patch)
treeeda659ec46e2d275d91ac9784dbd2095fb96da57 /shell
parent759ca8a4cb57f797e92e02db84673057ce447125 (diff)
downloadbusybox-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>
Diffstat (limited to 'shell')
-rw-r--r--shell/hush.c26
-rw-r--r--shell/hush_test/hush-vars/readonly3.right4
-rwxr-xr-xshell/hush_test/hush-vars/readonly3.tests4
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