aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-04-03 08:20:58 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-04-03 08:20:58 +0200
commit11752d46d18ff4a04a9f6736d129a82756a65a22 (patch)
treee75c6ab590a106d9933f135f4f8ea2c9dd40e44b
parentf50e14632f7be56da7a38937c887f77812803f70 (diff)
downloadbusybox-w32-11752d46d18ff4a04a9f6736d129a82756a65a22.tar.gz
busybox-w32-11752d46d18ff4a04a9f6736d129a82756a65a22.tar.bz2
busybox-w32-11752d46d18ff4a04a9f6736d129a82756a65a22.zip
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>
-rw-r--r--shell/hush.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 867a921ec..184d720f5 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -79,20 +79,6 @@
79 * Some builtins mandated by standards: 79 * Some builtins mandated by standards:
80 * newgrp [GRP]: not a builtin in bash but a suid binary 80 * newgrp [GRP]: not a builtin in bash but a suid binary
81 * which spawns a new shell with new group ID 81 * which spawns a new shell with new group ID
82 * In bash, export builtin is special, its arguments are assignments
83 * and therefore expansion of them should be "one-word" expansion:
84 * $ export i=`echo 'a b'` # export has one arg: "i=a b"
85 * compare with:
86 * $ ls i=`echo 'a b'` # ls has two args: "i=a" and "b"
87 * ls: cannot access i=a: No such file or directory
88 * ls: cannot access b: No such file or directory
89 * Note1: same applies to local builtin.
90 * Note2: bash 3.2.33(1) does this only if export word itself
91 * is not quoted:
92 * $ export i=`echo 'aaa bbb'`; echo "$i"
93 * aaa bbb
94 * $ "export" i=`echo 'aaa bbb'`; echo "$i"
95 * aaa
96 */ 82 */
97//config:config HUSH 83//config:config HUSH
98//config: bool "hush (64 kb)" 84//config: bool "hush (64 kb)"
@@ -630,8 +616,10 @@ struct command {
630 smallint cmd_type; /* CMD_xxx */ 616 smallint cmd_type; /* CMD_xxx */
631#define CMD_NORMAL 0 617#define CMD_NORMAL 0
632#define CMD_SUBSHELL 1 618#define CMD_SUBSHELL 1
633#if BASH_TEST2 619#if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
634/* used for "[[ EXPR ]]" */ 620/* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
621 * "export v=t*"
622 */
635# define CMD_SINGLEWORD_NOGLOB 2 623# define CMD_SINGLEWORD_NOGLOB 2
636#endif 624#endif
637#if ENABLE_HUSH_FUNCTIONS 625#if ENABLE_HUSH_FUNCTIONS
@@ -3933,14 +3921,37 @@ static int done_word(o_string *word, struct parse_context *ctx)
3933 (ctx->ctx_res_w == RES_SNTX)); 3921 (ctx->ctx_res_w == RES_SNTX));
3934 return (ctx->ctx_res_w == RES_SNTX); 3922 return (ctx->ctx_res_w == RES_SNTX);
3935 } 3923 }
3936# if BASH_TEST2 3924# if defined(CMD_SINGLEWORD_NOGLOB)
3937 if (strcmp(word->data, "[[") == 0) { 3925 if (0
3926# if BASH_TEST2
3927 || strcmp(word->data, "[[") == 0
3928# endif
3929 /* In bash, local/export/readonly are special, args
3930 * are assignments and therefore expansion of them
3931 * should be "one-word" expansion:
3932 * $ export i=`echo 'a b'` # one arg: "i=a b"
3933 * compare with:
3934 * $ ls i=`echo 'a b'` # two args: "i=a" and "b"
3935 * ls: cannot access i=a: No such file or directory
3936 * ls: cannot access b: No such file or directory
3937 * Note: bash 3.2.33(1) does this only if export word
3938 * itself is not quoted:
3939 * $ export i=`echo 'aaa bbb'`; echo "$i"
3940 * aaa bbb
3941 * $ "export" i=`echo 'aaa bbb'`; echo "$i"
3942 * aaa
3943 */
3944 IF_HUSH_LOCAL( || strcmp(word->data, "local") == 0)
3945 IF_HUSH_EXPORT( || strcmp(word->data, "export") == 0)
3946 IF_HUSH_READONLY( || strcmp(word->data, "readonly") == 0)
3947 ) {
3938 command->cmd_type = CMD_SINGLEWORD_NOGLOB; 3948 command->cmd_type = CMD_SINGLEWORD_NOGLOB;
3939 } 3949 }
3940 /* fall through */ 3950 /* fall through */
3941# endif 3951# endif
3942 } 3952 }
3943#endif 3953#endif /* HAS_KEYWORDS */
3954
3944 if (command->group) { 3955 if (command->group) {
3945 /* "{ echo foo; } echo bar" - bad */ 3956 /* "{ echo foo; } echo bar" - bad */
3946 syntax_error_at(word->data); 3957 syntax_error_at(word->data);
@@ -6299,7 +6310,7 @@ static char **expand_strvec_to_strvec(char **argv)
6299 return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS); 6310 return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS);
6300} 6311}
6301 6312
6302#if BASH_TEST2 6313#if defined(CMD_SINGLEWORD_NOGLOB)
6303static char **expand_strvec_to_strvec_singleword_noglob(char **argv) 6314static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
6304{ 6315{
6305 return expand_variables(argv, EXP_FLAG_SINGLEWORD); 6316 return expand_variables(argv, EXP_FLAG_SINGLEWORD);
@@ -8292,7 +8303,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
8292 } 8303 }
8293 8304
8294 /* Expand the rest into (possibly) many strings each */ 8305 /* Expand the rest into (possibly) many strings each */
8295#if BASH_TEST2 8306#if defined(CMD_SINGLEWORD_NOGLOB)
8296 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { 8307 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
8297 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); 8308 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
8298 } else 8309 } else