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-11752d46d18ff4a04a9f6736d129a82756a65a22.tar.gz
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 @@
* Some builtins mandated by standards:
* newgrp [GRP]: not a builtin in bash but a suid binary
* 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: bool "hush (64 kb)"
@@ -630,8 +616,10 @@ struct command {
smallint cmd_type; /* CMD_xxx */
#define CMD_NORMAL 0
#define CMD_SUBSHELL 1
-#if BASH_TEST2
-/* used for "[[ EXPR ]]" */
+#if BASH_TEST2 || ENABLE_HUSH_LOCAL || ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY
+/* used for "[[ EXPR ]]", and to prevent word splitting and globbing in
+ * "export v=t*"
+ */
# define CMD_SINGLEWORD_NOGLOB 2
#endif
#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));
return (ctx->ctx_res_w == RES_SNTX);
}
-# if BASH_TEST2
- if (strcmp(word->data, "[[") == 0) {
+# if defined(CMD_SINGLEWORD_NOGLOB)
+ if (0
+# if BASH_TEST2
+ || 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;
}
/* fall through */
# endif
}
-#endif
+#endif /* HAS_KEYWORDS */
+
if (command->group) {
/* "{ echo foo; } echo bar" - bad */
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);
}
-#if BASH_TEST2
+#if defined(CMD_SINGLEWORD_NOGLOB)
static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
{
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 */
-#if BASH_TEST2
+#if defined(CMD_SINGLEWORD_NOGLOB)
if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
} else