diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-18 02:44:06 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-18 02:44:06 +0200 |
commit | 5b2cc0aaee6985431d9bab1b49ceea7e1fa1d7af (patch) | |
tree | 456dfbf0232f7d0b0482bcc2eef96b6085fe98bd | |
parent | 38ef39a1abd46ca390b0259ebd0b35e9ea9ccb68 (diff) | |
download | busybox-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.c | 9 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/readonly0.right | 6 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/readonly0.tests | 30 |
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 | |||
5 | Fail:1 | 5 | Fail:1 |
6 | hush: a=A: readonly variable | 6 | hush: a=A: readonly variable |
7 | Fail:1 | 7 | Fail:1 |
8 | hush: a=A: readonly variable | 8 | hush: a=Z: readonly variable |
9 | Fail:1 | 9 | Fail:1 |
10 | Visible:0 | 10 | hush: a=Z: readonly variable |
11 | b=B | ||
12 | ^^^a is not exported | ||
11 | hush: a: readonly variable | 13 | hush: a: readonly variable |
12 | Fail:1 | 14 | Fail: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 @@ | |||
1 | unset a b | ||
2 | |||
1 | readonly a=A | 3 | readonly a=A |
2 | b=B | 4 | b=B |
3 | readonly b | 5 | readonly b |
4 | # readonly on already readonly var is harmless | 6 | # readonly on already readonly var is harmless: |
5 | readonly b a | 7 | readonly b a |
6 | readonly | grep '^readonly [ab]=' | 8 | readonly | grep '^readonly [ab]=' |
7 | # this should work | 9 | # this should work: |
8 | export a b | 10 | export a b |
9 | export -n a b | 11 | export -n a b |
10 | echo Ok:$? | 12 | echo 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) |
15 | true | 17 | true; a=A |
16 | a=A | 18 | echo Fail:$? |
17 | echo Fail:$?; true | 19 | true; readonly a=A |
18 | readonly a=A | 20 | echo Fail:$? |
19 | echo Fail:$?; true | 21 | |
20 | export a=A | 22 | # in bash, assignment in export fails, but export succeeds! :) |
23 | # we don't mimic that! | ||
24 | true; export a=Z | ||
21 | echo Fail:$?; true | 25 | echo Fail:$?; true |
22 | a=A echo Visible:$? # command still runs | 26 | #env | grep '^a=' |
27 | #echo "^^^a is exported" | ||
28 | export -n a # undo that bashism, if it happens | ||
29 | |||
30 | export b | ||
31 | # this fails to both set and export a: | ||
32 | a=Z env | grep '^[ab]=' # command still runs | ||
33 | echo "^^^a is not exported" | ||
34 | |||
23 | unset a | 35 | unset a |
24 | echo Fail:$?; true | 36 | echo Fail:$?; true |