aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/hush.c59
1 files changed, 33 insertions, 26 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 821a7a77f..1bed72159 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -400,8 +400,7 @@ typedef struct o_string {
smallint o_glob;
/* At least some part of the string was inside '' or "",
* possibly empty one: word"", wo''rd etc. */
-//TODO: rename to no_empty_expansion?
- smallint o_quoted;
+ smallint has_quoted_part;
smallint has_empty_slot;
smallint o_assignment; /* 0:maybe, 1:yes, 2:no */
} o_string;
@@ -1964,7 +1963,7 @@ static void setup_string_in_str(struct in_str *i, const char *s)
static void o_reset_to_empty_unquoted(o_string *o)
{
o->length = 0;
- o->o_quoted = 0;
+ o->has_quoted_part = 0;
if (o->data)
o->data[0] = '\0';
}
@@ -2088,7 +2087,7 @@ static void o_addQchr(o_string *o, int ch)
o->data[o->length] = '\0';
}
-static void o_addQstr(o_string *o, const char *str, int len)
+static void o_addQblock(o_string *o, const char *str, int len)
{
if (!o->o_escape) {
o_addblock(o, str, len);
@@ -2120,6 +2119,11 @@ static void o_addQstr(o_string *o, const char *str, int len)
}
}
+static void o_addQstr(o_string *o, const char *str)
+{
+ o_addQblock(o, str, strlen(str));
+}
+
/* A special kind of o_string for $VAR and `cmd` expansion.
* It contains char* list[] at the beginning, which is grown in 16 element
* increments. Actual string data starts at the next multiple of 16 * (char*).
@@ -2139,7 +2143,7 @@ static void debug_print_list(const char *prefix, o_string *o, int n)
indent();
fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
- prefix, list, n, string_start, o->length, o->maxlen, o->o_glob, o->o_quoted, o->o_escape);
+ prefix, list, n, string_start, o->length, o->maxlen, o->o_glob, o->has_quoted_part, o->o_escape);
while (i < n) {
indent();
fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i],
@@ -2544,7 +2548,7 @@ static int expand_on_ifs(o_string *output, int n, const char *str)
int word_len = strcspn(str, G.ifs);
if (word_len) {
if (output->o_escape || !output->o_glob)
- o_addQstr(output, str, word_len);
+ o_addQblock(output, str, word_len);
else /* protect backslashes against globbing up :) */
o_addblock_duplicate_backslash(output, str, word_len);
str += word_len;
@@ -2994,7 +2998,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
* and in this case should treat it like '$*' - see 'else...' below */
if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
while (1) {
- o_addQstr(output, G.global_argv[i], strlen(G.global_argv[i]));
+ o_addQstr(output, G.global_argv[i]);
if (++i >= G.global_argc)
break;
o_addchr(output, '\0');
@@ -3003,7 +3007,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
}
} else { /* quoted $*: add as one word */
while (1) {
- o_addQstr(output, G.global_argv[i], strlen(G.global_argv[i]));
+ o_addQstr(output, G.global_argv[i]);
if (!G.global_argv[++i])
break;
if (G.ifs[0])
@@ -3081,7 +3085,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
} /* switch (char after <SPECIAL_VAR_SYMBOL>) */
if (val && val[0]) {
- o_addQstr(output, val, strlen(val));
+ o_addQstr(output, val);
}
free(to_be_freed);
/* Do the check to avoid writing to a const string */
@@ -3109,6 +3113,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
} else {
o_addchr(output, '\0');
}
+
return n;
}
@@ -5485,7 +5490,7 @@ static int reserved_word(o_string *word, struct parse_context *ctx)
# endif
const struct reserved_combo *r;
- if (word->o_quoted)
+ if (word->has_quoted_part)
return 0;
r = match_reserved_word(word);
if (!r)
@@ -5561,7 +5566,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
struct command *command = ctx->command;
debug_printf_parse("done_word entered: '%s' %p\n", word->data, command);
- if (word->length == 0 && word->o_quoted == 0) {
+ if (word->length == 0 && !word->has_quoted_part) {
debug_printf_parse("done_word return 0: true null, ignored\n");
return 0;
}
@@ -5588,7 +5593,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
unbackslash(ctx->pending_redirect->rd_filename);
/* Is it <<"HEREDOC"? */
- if (word->o_quoted) {
+ if (word->has_quoted_part) {
ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
}
}
@@ -5657,7 +5662,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
"groups and arglists don't mix\n");
return 1;
}
- if (word->o_quoted /* word had "xx" or 'xx' at least as part of it. */
+ if (word->has_quoted_part
/* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
&& (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL)
/* (otherwise it's known to be not empty and is already safe) */
@@ -5685,7 +5690,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
#if ENABLE_HUSH_LOOPS
if (ctx->ctx_res_w == RES_FOR) {
- if (word->o_quoted
+ if (word->has_quoted_part
|| !is_well_formed_var_name(command->argv[0], '\0')
) {
/* bash says just "not a valid identifier" */
@@ -5842,7 +5847,7 @@ static int parse_redirect(struct parse_context *ctx,
* the redirection expression. For example:
* echo \2>a
* writes the character 2 into file a"
- * We are getting it right by setting ->o_quoted on any \<char>
+ * We are getting it right by setting ->has_quoted_part on any \<char>
*
* A -1 return means no valid number was found,
* the caller should use the appropriate default for this redirection.
@@ -6042,7 +6047,9 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
*pid_p = pid;
# if ENABLE_HUSH_FAST
G.count_SIGCHLD++;
-//bb_error_msg("[%d] fork in generate_stream_from_string: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
+//bb_error_msg("[%d] fork in generate_stream_from_string:"
+// " G.count_SIGCHLD:%d G.handled_SIGCHLD:%d",
+// getpid(), G.count_SIGCHLD, G.handled_SIGCHLD);
# endif
enable_restore_tty_pgrp_on_exit();
# if !BB_MMU
@@ -6105,7 +6112,7 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
debug_printf_parse("parse_group entered\n");
#if ENABLE_HUSH_FUNCTIONS
- if (ch == '(' && !dest->o_quoted) {
+ if (ch == '(' && !dest->has_quoted_part) {
if (dest->length)
if (done_word(dest, ctx))
return 1;
@@ -6140,7 +6147,7 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
#if 0 /* Prevented by caller */
if (command->argv /* word [word]{... */
|| dest->length /* word{... */
- || dest->o_quoted /* ""{... */
+ || dest->has_quoted_part /* ""{... */
) {
syntax_error(NULL);
debug_printf_parse("parse_group return 1: "
@@ -6705,7 +6712,7 @@ static struct pipe *parse_stream(char **pstring,
redir_type redir_style;
if (is_in_dquote) {
- /* dest.o_quoted = 1; - already is (see below) */
+ /* dest.has_quoted_part = 1; - already is (see below) */
if (parse_stream_dquoted(&ctx.as_string, &dest, input, '"')) {
goto parse_error;
}
@@ -6766,7 +6773,7 @@ static struct pipe *parse_stream(char **pstring,
/* Are { and } special here? */
if (ctx.command->argv /* word [word]{... - non-special */
|| dest.length /* word{... - non-special */
- || dest.o_quoted /* ""{... - non-special */
+ || dest.has_quoted_part /* ""{... - non-special */
|| (next != ';' /* }; - special */
&& next != ')' /* }) - special */
&& next != '&' /* }& and }&& ... - special */
@@ -6830,7 +6837,7 @@ static struct pipe *parse_stream(char **pstring,
if (ch == '}') {
if (!IS_NULL_CMD(ctx.command) /* cmd } */
|| dest.length != 0 /* word} */
- || dest.o_quoted /* ""} */
+ || dest.has_quoted_part /* ""} */
) {
goto ordinary_char;
}
@@ -6844,7 +6851,7 @@ static struct pipe *parse_stream(char **pstring,
#if ENABLE_HUSH_CASE
&& (ch != ')'
|| ctx.ctx_res_w != RES_MATCH
- || (!dest.o_quoted && strcmp(dest.data, "esac") == 0)
+ || (!dest.has_quoted_part && strcmp(dest.data, "esac") == 0)
)
#endif
) {
@@ -6979,7 +6986,7 @@ static struct pipe *parse_stream(char **pstring,
nommu_addchr(&ctx.as_string, ch);
/* Example: echo Hello \2>file
* we need to know that word 2 is quoted */
- dest.o_quoted = 1;
+ dest.has_quoted_part = 1;
}
#if !BB_MMU
else {
@@ -6996,7 +7003,7 @@ static struct pipe *parse_stream(char **pstring,
}
break;
case '\'':
- dest.o_quoted = 1;
+ dest.has_quoted_part = 1;
while (1) {
ch = i_getch(input);
if (ch == EOF) {
@@ -7010,7 +7017,7 @@ static struct pipe *parse_stream(char **pstring,
}
break;
case '"':
- dest.o_quoted = 1;
+ dest.has_quoted_part = 1;
is_in_dquote ^= 1; /* invert */
if (dest.o_assignment == NOT_ASSIGNMENT)
dest.o_escape ^= 1;
@@ -7101,7 +7108,7 @@ static struct pipe *parse_stream(char **pstring,
if (ctx.ctx_res_w == RES_MATCH
&& ctx.command->argv == NULL /* not (word|(... */
&& dest.length == 0 /* not word(... */
- && dest.o_quoted == 0 /* not ""(... */
+ && dest.has_quoted_part == 0 /* not ""(... */
) {
continue;
}