aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-18 02:44:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-18 02:44:06 +0200
commit5b2cc0aaee6985431d9bab1b49ceea7e1fa1d7af (patch)
tree456dfbf0232f7d0b0482bcc2eef96b6085fe98bd
parent38ef39a1abd46ca390b0259ebd0b35e9ea9ccb68 (diff)
downloadbusybox-w32-5b2cc0aaee6985431d9bab1b49ceea7e1fa1d7af.tar.gz
busybox-w32-5b2cc0aaee6985431d9bab1b49ceea7e1fa1d7af.tar.bz2
busybox-w32-5b2cc0aaee6985431d9bab1b49ceea7e1fa1d7af.zip
hush: do not assign to readonly VAR in "VAR=VAL CMD" syntax too
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c9
-rw-r--r--shell/hush_test/hush-vars/readonly0.right6
-rwxr-xr-xshell/hush_test/hush-vars/readonly0.tests30
3 files changed, 33 insertions, 12 deletions
diff --git a/shell/hush.c b/shell/hush.c
index eab1284f6..55e581e16 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2089,6 +2089,8 @@ static int set_local_var(char *str, unsigned flags)
2089 if (cur->flg_read_only) { 2089 if (cur->flg_read_only) {
2090 bb_error_msg("%s: readonly variable", str); 2090 bb_error_msg("%s: readonly variable", str);
2091 free(str); 2091 free(str);
2092//NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1,
2093//but export per se succeeds (does put the var in env). We don't mimic that.
2092 return -1; 2094 return -1;
2093 } 2095 }
2094 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ? 2096 if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ?
@@ -2283,8 +2285,12 @@ static struct variable *set_vars_and_save_old(char **strings)
2283 if (eq) { 2285 if (eq) {
2284 var_pp = get_ptr_to_local_var(*s, eq - *s); 2286 var_pp = get_ptr_to_local_var(*s, eq - *s);
2285 if (var_pp) { 2287 if (var_pp) {
2286 /* Remove variable from global linked list */
2287 var_p = *var_pp; 2288 var_p = *var_pp;
2289 if (var_p->flg_read_only) {
2290 bb_error_msg("%s: readonly variable", *s);
2291 goto next;
2292 }
2293 /* Remove variable from global linked list */
2288 debug_printf_env("%s: removing '%s'\n", __func__, var_p->varstr); 2294 debug_printf_env("%s: removing '%s'\n", __func__, var_p->varstr);
2289 *var_pp = var_p->next; 2295 *var_pp = var_p->next;
2290 /* Add it to returned list */ 2296 /* Add it to returned list */
@@ -2293,6 +2299,7 @@ static struct variable *set_vars_and_save_old(char **strings)
2293 } 2299 }
2294 set_local_var(*s, SETFLAG_EXPORT); 2300 set_local_var(*s, SETFLAG_EXPORT);
2295 } 2301 }
2302 next:
2296 s++; 2303 s++;
2297 } 2304 }
2298 return old; 2305 return old;
diff --git a/shell/hush_test/hush-vars/readonly0.right b/shell/hush_test/hush-vars/readonly0.right
index 9688d2e5f..07ca6e07f 100644
--- a/shell/hush_test/hush-vars/readonly0.right
+++ b/shell/hush_test/hush-vars/readonly0.right
@@ -5,8 +5,10 @@ hush: a=A: readonly variable
5Fail:1 5Fail:1
6hush: a=A: readonly variable 6hush: a=A: readonly variable
7Fail:1 7Fail:1
8hush: a=A: readonly variable 8hush: a=Z: readonly variable
9Fail:1 9Fail:1
10Visible:0 10hush: a=Z: readonly variable
11b=B
12^^^a is not exported
11hush: a: readonly variable 13hush: a: readonly variable
12Fail:1 14Fail:1
diff --git a/shell/hush_test/hush-vars/readonly0.tests b/shell/hush_test/hush-vars/readonly0.tests
index 3845f76ac..3ace9b767 100755
--- a/shell/hush_test/hush-vars/readonly0.tests
+++ b/shell/hush_test/hush-vars/readonly0.tests
@@ -1,10 +1,12 @@
1unset a b
2
1readonly a=A 3readonly a=A
2b=B 4b=B
3readonly b 5readonly b
4# readonly on already readonly var is harmless 6# readonly on already readonly var is harmless:
5readonly b a 7readonly b a
6readonly | grep '^readonly [ab]=' 8readonly | grep '^readonly [ab]='
7# this should work 9# this should work:
8export a b 10export a b
9export -n a b 11export -n a b
10echo Ok:$? 12echo Ok:$?
@@ -12,13 +14,23 @@ env | grep -e^a= -e^b= # shows nothing
12 14
13# these should all fail (despite the same value being assigned) 15# these should all fail (despite the same value being assigned)
14# bash does not abort even in non-interactive more (in script) 16# bash does not abort even in non-interactive more (in script)
15true 17true; a=A
16a=A 18echo Fail:$?
17echo Fail:$?; true 19true; readonly a=A
18readonly a=A 20echo Fail:$?
19echo Fail:$?; true 21
20export a=A 22# in bash, assignment in export fails, but export succeeds! :)
23# we don't mimic that!
24true; export a=Z
21echo Fail:$?; true 25echo Fail:$?; true
22a=A echo Visible:$? # command still runs 26#env | grep '^a='
27#echo "^^^a is exported"
28export -n a # undo that bashism, if it happens
29
30export b
31# this fails to both set and export a:
32a=Z env | grep '^[ab]=' # command still runs
33echo "^^^a is not exported"
34
23unset a 35unset a
24echo Fail:$?; true 36echo Fail:$?; true