hush: one-word, no-globbing handling of local/export/readonly args
function old new delta done_word 738 790 +52 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
f50e14632f
commit
11752d46d1
51
shell/hush.c
51
shell/hush.c
@ -79,20 +79,6 @@
|
|||||||
* Some builtins mandated by standards:
|
* Some builtins mandated by standards:
|
||||||
* newgrp [GRP]: not a builtin in bash but a suid binary
|
* newgrp [GRP]: not a builtin in bash but a suid binary
|
||||||
* which spawns a new shell with new group ID
|
* which spawns a new shell with new group ID
|
||||||
* In bash, export builtin is special, its arguments are assignments
|
|
||||||
* and therefore expansion of them should be "one-word" expansion:
|
|
||||||
* $ export i=`echo 'a b'` # export has one arg: "i=a b"
|
|
||||||
* compare with:
|
|
||||||
* $ ls i=`echo 'a b'` # ls has two args: "i=a" and "b"
|
|
||||||
* ls: cannot access i=a: No such file or directory
|
|
||||||
* ls: cannot access b: No such file or directory
|
|
||||||
* Note1: same applies to local builtin.
|
|
||||||
* Note2: bash 3.2.33(1) does this only if export word itself
|
|
||||||
* is not quoted:
|
|
||||||
* $ export i=`echo 'aaa bbb'`; echo "$i"
|
|
||||||
* aaa bbb
|
|
||||||
* $ "export" i=`echo 'aaa bbb'`; echo "$i"
|
|
||||||
* aaa
|
|
||||||
*/
|
*/
|
||||||
//config:config HUSH
|
//config:config HUSH
|
||||||
//config: bool "hush (64 kb)"
|
//config: bool "hush (64 kb)"
|
||||||
@ -630,8 +616,10 @@ struct command {
|
|||||||
smallint cmd_type; /* CMD_xxx */
|
smallint cmd_type; /* CMD_xxx */
|
||||||
#define CMD_NORMAL 0
|
#define CMD_NORMAL 0
|
||||||
#define CMD_SUBSHELL 1
|
#define CMD_SUBSHELL 1
|
||||||
#if BASH_TEST2
|
#if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
|
||||||
/* used for "[[ EXPR ]]" */
|
/* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
|
||||||
|
* "export v=t*"
|
||||||
|
*/
|
||||||
# define CMD_SINGLEWORD_NOGLOB 2
|
# define CMD_SINGLEWORD_NOGLOB 2
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_HUSH_FUNCTIONS
|
#if ENABLE_HUSH_FUNCTIONS
|
||||||
@ -3933,14 +3921,37 @@ static int done_word(o_string *word, struct parse_context *ctx)
|
|||||||
(ctx->ctx_res_w == RES_SNTX));
|
(ctx->ctx_res_w == RES_SNTX));
|
||||||
return (ctx->ctx_res_w == RES_SNTX);
|
return (ctx->ctx_res_w == RES_SNTX);
|
||||||
}
|
}
|
||||||
|
# if defined(CMD_SINGLEWORD_NOGLOB)
|
||||||
|
if (0
|
||||||
# if BASH_TEST2
|
# if BASH_TEST2
|
||||||
if (strcmp(word->data, "[[") == 0) {
|
|| strcmp(word->data, "[[") == 0
|
||||||
|
# endif
|
||||||
|
/* In bash, local/export/readonly are special, args
|
||||||
|
* are assignments and therefore expansion of them
|
||||||
|
* should be "one-word" expansion:
|
||||||
|
* $ export i=`echo 'a b'` # one arg: "i=a b"
|
||||||
|
* compare with:
|
||||||
|
* $ ls i=`echo 'a b'` # two args: "i=a" and "b"
|
||||||
|
* ls: cannot access i=a: No such file or directory
|
||||||
|
* ls: cannot access b: No such file or directory
|
||||||
|
* Note: bash 3.2.33(1) does this only if export word
|
||||||
|
* itself is not quoted:
|
||||||
|
* $ export i=`echo 'aaa bbb'`; echo "$i"
|
||||||
|
* aaa bbb
|
||||||
|
* $ "export" i=`echo 'aaa bbb'`; echo "$i"
|
||||||
|
* aaa
|
||||||
|
*/
|
||||||
|
IF_HUSH_LOCAL( || strcmp(word->data, "local") == 0)
|
||||||
|
IF_HUSH_EXPORT( || strcmp(word->data, "export") == 0)
|
||||||
|
IF_HUSH_READONLY( || strcmp(word->data, "readonly") == 0)
|
||||||
|
) {
|
||||||
command->cmd_type = CMD_SINGLEWORD_NOGLOB;
|
command->cmd_type = CMD_SINGLEWORD_NOGLOB;
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* HAS_KEYWORDS */
|
||||||
|
|
||||||
if (command->group) {
|
if (command->group) {
|
||||||
/* "{ echo foo; } echo bar" - bad */
|
/* "{ echo foo; } echo bar" - bad */
|
||||||
syntax_error_at(word->data);
|
syntax_error_at(word->data);
|
||||||
@ -6299,7 +6310,7 @@ static char **expand_strvec_to_strvec(char **argv)
|
|||||||
return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
|
return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BASH_TEST2
|
#if defined(CMD_SINGLEWORD_NOGLOB)
|
||||||
static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
|
static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
|
||||||
{
|
{
|
||||||
return expand_variables(argv, EXP_FLAG_SINGLEWORD);
|
return expand_variables(argv, EXP_FLAG_SINGLEWORD);
|
||||||
@ -8292,7 +8303,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Expand the rest into (possibly) many strings each */
|
/* Expand the rest into (possibly) many strings each */
|
||||||
#if BASH_TEST2
|
#if defined(CMD_SINGLEWORD_NOGLOB)
|
||||||
if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
|
if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
|
||||||
argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
|
argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
|
||||||
} else
|
} else
|
||||||
|
Loading…
Reference in New Issue
Block a user