diff options
-rw-r--r-- | shell/hush.c | 26 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/readonly0.right | 12 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/readonly0.tests | 24 |
3 files changed, 53 insertions, 9 deletions
diff --git a/shell/hush.c b/shell/hush.c index 7771172..eab1284 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -7767,10 +7767,10 @@ static NOINLINE int run_pipe(struct pipe *pi) if (new_env) { argv = new_env; while (*argv) { - set_local_var(*argv, /*flag:*/ 0); - /* Do we need to flag set_local_var() errors? - * "assignment to readonly var" and "putenv error" - */ + if (set_local_var(*argv, /*flag:*/ 0)) { + /* assignment to readonly var / putenv error? */ + rcode = 1; + } argv++; } } @@ -7795,10 +7795,10 @@ static NOINLINE int run_pipe(struct pipe *pi) fprintf(stderr, " %s", p); debug_printf_exec("set shell var:'%s'->'%s'\n", *argv, p); - set_local_var(p, /*flag:*/ 0); - /* Do we need to flag set_local_var() errors? - * "assignment to readonly var" and "putenv error" - */ + if (set_local_var(p, /*flag:*/ 0)) { + /* assignment to readonly var / putenv error? */ + rcode = 1; + } argv++; } if (G_x_mode) @@ -9336,6 +9336,13 @@ static int helper_export_local(char **argv, unsigned flags) continue; } } + if (flags & SETFLAG_MAKE_RO) { + /* readonly NAME (without =VALUE) */ + if (var) { + var->flg_read_only = 1; + continue; + } + } # if ENABLE_HUSH_LOCAL /* Is this "local" bltin? */ if (!(flags & (SETFLAG_EXPORT|SETFLAG_UNEXPORT|SETFLAG_MAKE_RO))) { @@ -9364,7 +9371,8 @@ static int helper_export_local(char **argv, unsigned flags) /* (Un)exporting/making local NAME=VALUE */ name = xstrdup(name); } - set_local_var(name, flags); + if (set_local_var(name, flags)) + return EXIT_FAILURE; } while (*++argv); return EXIT_SUCCESS; } diff --git a/shell/hush_test/hush-vars/readonly0.right b/shell/hush_test/hush-vars/readonly0.right new file mode 100644 index 0000000..9688d2e --- /dev/null +++ b/shell/hush_test/hush-vars/readonly0.right @@ -0,0 +1,12 @@ +readonly a=A +readonly b=B +Ok:0 +hush: a=A: readonly variable +Fail:1 +hush: a=A: readonly variable +Fail:1 +hush: a=A: readonly variable +Fail:1 +Visible:0 +hush: a: readonly variable +Fail:1 diff --git a/shell/hush_test/hush-vars/readonly0.tests b/shell/hush_test/hush-vars/readonly0.tests new file mode 100755 index 0000000..3845f76 --- /dev/null +++ b/shell/hush_test/hush-vars/readonly0.tests @@ -0,0 +1,24 @@ +readonly a=A +b=B +readonly b +# readonly on already readonly var is harmless +readonly b a +readonly | grep '^readonly [ab]=' +# this should work +export a b +export -n a b +echo Ok:$? +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 +echo Fail:$?; true +a=A echo Visible:$? # command still runs +unset a +echo Fail:$?; true |