hush: do not assign to readonly VAR in "VAR=VAL CMD" syntax too
No binary (build failed)
—
(log yok)
| @@ -2089,6 +2089,8 @@ static int set_local_var(char *str, unsigned flags) | |
| if (cur->flg_read_only) { | |
| bb_error_msg("%s: readonly variable", str); | |
| free(str); | |
| + | //NOTE: in bash, assignment in "export READONLY_VAR=Z" fails, and sets $?=1, |
| + | //but export per se succeeds (does put the var in env). We don't mimic that. |
| return -1; | |
| } | |
| if (flags & SETFLAG_UNEXPORT) { // && cur->flg_export ? | |
| @@ -2283,8 +2285,12 @@ static struct variable *set_vars_and_save_old(char **strings) | |
| if (eq) { | |
| var_pp = get_ptr_to_local_var(*s, eq - *s); | |
| if (var_pp) { | |
| - | /* Remove variable from global linked list */ |
| var_p = *var_pp; | |
| + | if (var_p->flg_read_only) { |
| + | bb_error_msg("%s: readonly variable", *s); |
| + | goto next; |
| + | } |
| + | /* Remove variable from global linked list */ |
| debug_printf_env("%s: removing '%s'\n", __func__, var_p->varstr); | |
| *var_pp = var_p->next; | |
| /* Add it to returned list */ | |
| @@ -2293,6 +2299,7 @@ static struct variable *set_vars_and_save_old(char **strings) | |
| } | |
| set_local_var(*s, SETFLAG_EXPORT); | |
| } | |
| + | next: |
| s++; | |
| } | |
| return old; | |
| @@ -5,8 +5,10 @@ hush: a=A: readonly variable | |
| Fail:1 | |
| hush: a=A: readonly variable | |
| Fail:1 | |
| - | hush: a=A: readonly variable |
| + | hush: a=Z: readonly variable |
| Fail:1 | |
| - | Visible:0 |
| + | hush: a=Z: readonly variable |
| + | b=B |
| + | ^^^a is not exported |
| hush: a: readonly variable | |
| Fail:1 | |
| @@ -1,10 +1,12 @@ | |
| + | unset a b |
| + | |
| readonly a=A | |
| b=B | |
| readonly b | |
| - | # readonly on already readonly var is harmless |
| + | # readonly on already readonly var is harmless: |
| readonly b a | |
| readonly | grep '^readonly [ab]=' | |
| - | # this should work |
| + | # this should work: |
| export a b | |
| export -n a b | |
| echo Ok:$? | |
| @@ -12,13 +14,23 @@ env | grep -e^a= -e^b= # shows nothing | |
| # these should all fail (despite the same value being assigned) | |
| # bash does not abort even in non-interactive more (in script) | |
| - | true |
| - | a=A |
| - | echo Fail:$?; true |
| - | readonly a=A |
| - | echo Fail:$?; true |
| - | export a=A |
| + | true; a=A |
| + | echo Fail:$? |
| + | true; readonly a=A |
| + | echo Fail:$? |
| + | |
| + | # in bash, assignment in export fails, but export succeeds! :) |
| + | # we don't mimic that! |
| + | true; export a=Z |
| echo Fail:$?; true | |
| - | a=A echo Visible:$? # command still runs |
| + | #env | grep '^a=' |
| + | #echo "^^^a is exported" |
| + | export -n a # undo that bashism, if it happens |
| + | |
| + | export b |
| + | # this fails to both set and export a: |
| + | a=Z env | grep '^[ab]=' # command still runs |
| + | echo "^^^a is not exported" |
| + | |
| unset a | |
| echo Fail:$?; true | |