hush: add readonly testcase, fix fallout

function                                             old     new   delta
helper_export_local                                  185     214     +29
run_pipe                                            1549    1560     +11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 40/0)               Total: 40 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2017-07-18 01:40:01 +02:00
parent 3bab36b18b
commit 38ef39a1ab
3 changed files with 53 additions and 9 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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