diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-03 08:20:58 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-03 08:20:58 +0200 |
| commit | 11752d46d18ff4a04a9f6736d129a82756a65a22 (patch) | |
| tree | e75c6ab590a106d9933f135f4f8ea2c9dd40e44b /shell | |
| parent | f50e14632f7be56da7a38937c887f77812803f70 (diff) | |
| download | busybox-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>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 53 |
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) |
| 6303 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | 6314 | static 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 |
