From acd5bc8f649fad335d80c5289512b404f08ac8e2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 12 Sep 2010 15:05:39 +0200 Subject: hush: fix handling of \" in quoted/unquoted `cmd` Signed-off-by: Denys Vlasenko --- shell/hush.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'shell/hush.c') diff --git a/shell/hush.c b/shell/hush.c index 76737a234..b01f90370 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -234,6 +234,10 @@ //usage:#define hush_full_usage "" //usage:#define msh_trivial_usage NOUSAGE_STR //usage:#define msh_full_usage "" +//usage:#define sh_trivial_usage NOUSAGE_STR +//usage:#define sh_full_usage "" +//usage:#define bash_trivial_usage NOUSAGE_STR +//usage:#define bash_full_usage "" /* Build knobs */ @@ -1367,9 +1371,15 @@ static void hush_exit(int exitcode) #endif } + static int check_and_run_traps(int sig) { - static const struct timespec zero_timespec; + /* I want it in rodata, not in bss. + * gcc 4.2.1 puts it in rodata only if it has { 0, 0 } + * initializer. But other compilers may still use bss. + * TODO: find more portable solution. + */ + static const struct timespec zero_timespec = { 0, 0 }; smalluint save_rcode; int last_sig = 0; @@ -3367,7 +3377,7 @@ static int parse_group(o_string *dest, struct parse_context *ctx, #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS /* Subroutines for copying $(...) and `...` things */ -static void add_till_backquote(o_string *dest, struct in_str *input); +static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); /* '...' */ static void add_till_single_quote(o_string *dest, struct in_str *input) { @@ -3399,7 +3409,7 @@ static void add_till_double_quote(o_string *dest, struct in_str *input) } o_addchr(dest, ch); if (ch == '`') { - add_till_backquote(dest, input); + add_till_backquote(dest, input, /*in_dquote:*/ 1); o_addchr(dest, ch); continue; } @@ -3420,26 +3430,26 @@ static void add_till_double_quote(o_string *dest, struct in_str *input) * Example Output * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST */ -static void add_till_backquote(o_string *dest, struct in_str *input) +static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote) { while (1) { int ch = i_getch(input); - if (ch == EOF) { - syntax_error_unterm_ch('`'); - /*xfunc_die(); - redundant */ - } if (ch == '`') return; if (ch == '\\') { - /* \x. Copy both chars unless it is \` */ - int ch2 = i_getch(input); - if (ch2 == EOF) { - syntax_error_unterm_ch('`'); - /*xfunc_die(); - redundant */ + /* \x. Copy both unless it is \`, \$, \\ and maybe \" */ + ch = i_getch(input); + if (ch != '`' + && ch != '$' + && ch != '\\' + && (!in_dquote || ch != '"') + ) { + o_addchr(dest, '\\'); } - if (ch2 != '`' && ch2 != '$' && ch2 != '\\') - o_addchr(dest, ch); - ch = ch2; + } + if (ch == EOF) { + syntax_error_unterm_ch('`'); + /*xfunc_die(); - redundant */ } o_addchr(dest, ch); } @@ -3504,7 +3514,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign continue; } if (ch == '`') { - add_till_backquote(dest, input); + add_till_backquote(dest, input, /*in_dquote:*/ 0); o_addchr(dest, ch); continue; } @@ -3818,7 +3828,7 @@ static int encode_string(o_string *as_string, //unsigned pos = dest->length; o_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, 0x80 | '`'); - add_till_backquote(dest, input); + add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'); o_addchr(dest, SPECIAL_VAR_SYMBOL); //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); goto again; @@ -4191,7 +4201,7 @@ static struct pipe *parse_stream(char **pstring, o_addchr(&dest, SPECIAL_VAR_SYMBOL); o_addchr(&dest, '`'); pos = dest.length; - add_till_backquote(&dest, input); + add_till_backquote(&dest, input, /*in_dquote:*/ 0); # if !BB_MMU o_addstr(&ctx.as_string, dest.data + pos); o_addchr(&ctx.as_string, '`'); -- cgit v1.2.3