hush: fix handling of \" in quoted/unquoted cmd

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
Denys Vlasenko 2010-09-12 15:05:39 +02:00
parent 958581a8d9
commit acd5bc8f64
5 changed files with 50 additions and 22 deletions

View File

@ -234,6 +234,10 @@
//usage:#define hush_full_usage "" //usage:#define hush_full_usage ""
//usage:#define msh_trivial_usage NOUSAGE_STR //usage:#define msh_trivial_usage NOUSAGE_STR
//usage:#define msh_full_usage "" //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 */ /* Build knobs */
@ -1367,9 +1371,15 @@ static void hush_exit(int exitcode)
#endif #endif
} }
static int check_and_run_traps(int sig) 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; smalluint save_rcode;
int last_sig = 0; 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 #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS
/* Subroutines for copying $(...) and `...` things */ /* 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) 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); o_addchr(dest, ch);
if (ch == '`') { if (ch == '`') {
add_till_backquote(dest, input); add_till_backquote(dest, input, /*in_dquote:*/ 1);
o_addchr(dest, ch); o_addchr(dest, ch);
continue; continue;
} }
@ -3420,27 +3430,27 @@ static void add_till_double_quote(o_string *dest, struct in_str *input)
* Example Output * Example Output
* echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST * 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) { while (1) {
int ch = i_getch(input); int ch = i_getch(input);
if (ch == EOF) {
syntax_error_unterm_ch('`');
/*xfunc_die(); - redundant */
}
if (ch == '`') if (ch == '`')
return; return;
if (ch == '\\') { if (ch == '\\') {
/* \x. Copy both chars unless it is \` */ /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
int ch2 = i_getch(input); ch = i_getch(input);
if (ch2 == EOF) { if (ch != '`'
&& ch != '$'
&& ch != '\\'
&& (!in_dquote || ch != '"')
) {
o_addchr(dest, '\\');
}
}
if (ch == EOF) {
syntax_error_unterm_ch('`'); syntax_error_unterm_ch('`');
/*xfunc_die(); - redundant */ /*xfunc_die(); - redundant */
} }
if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
o_addchr(dest, ch);
ch = ch2;
}
o_addchr(dest, ch); o_addchr(dest, ch);
} }
} }
@ -3504,7 +3514,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
continue; continue;
} }
if (ch == '`') { if (ch == '`') {
add_till_backquote(dest, input); add_till_backquote(dest, input, /*in_dquote:*/ 0);
o_addchr(dest, ch); o_addchr(dest, ch);
continue; continue;
} }
@ -3818,7 +3828,7 @@ static int encode_string(o_string *as_string,
//unsigned pos = dest->length; //unsigned pos = dest->length;
o_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
o_addchr(dest, 0x80 | '`'); o_addchr(dest, 0x80 | '`');
add_till_backquote(dest, input); add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"');
o_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
//debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
goto again; goto again;
@ -4191,7 +4201,7 @@ static struct pipe *parse_stream(char **pstring,
o_addchr(&dest, SPECIAL_VAR_SYMBOL); o_addchr(&dest, SPECIAL_VAR_SYMBOL);
o_addchr(&dest, '`'); o_addchr(&dest, '`');
pos = dest.length; pos = dest.length;
add_till_backquote(&dest, input); add_till_backquote(&dest, input, /*in_dquote:*/ 0);
# if !BB_MMU # if !BB_MMU
o_addstr(&ctx.as_string, dest.data + pos); o_addstr(&ctx.as_string, dest.data + pos);
o_addchr(&ctx.as_string, '`'); o_addchr(&ctx.as_string, '`');

View File

@ -5,6 +5,8 @@ a\\
b b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?- 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?- -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\ c\
Unquoted heredoc: Unquoted heredoc:
@ -13,6 +15,8 @@ a\
b b
123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?- 123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
-qwerty-\t-\-\"-\'-`-\--\z-\*-\?- -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
123456 v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
123456 v-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-
cEOF2 cEOF2
Quoted -heredoc: Quoted -heredoc:
@ -22,6 +26,8 @@ a\\
b b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?- 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?- -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\ c\
Unquoted -heredoc: Unquoted -heredoc:
@ -30,6 +36,8 @@ a\
b b
123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?- 123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
-qwerty-\t-\-\"-\'-`-\--\z-\*-\?- -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
123456 v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
123456 v-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-
cEOF4 cEOF4
Done: 0 Done: 0

View File

@ -11,6 +11,8 @@ a\\
b b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?- 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?- -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\ c\
EOF1 EOF1
echo echo
@ -23,6 +25,8 @@ a\\
b b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?- 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?- -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-')
c\ c\
EOF2 EOF2
EOF2 EOF2
@ -36,6 +40,8 @@ a\\
b b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?- 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?- -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\ c\
EOF3 EOF3
# In -heredoc case the marker is detected even if it is indented. # In -heredoc case the marker is detected even if it is indented.
@ -49,6 +55,8 @@ a\\
b b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?- 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?- -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-')
c\ c\
EOF4 EOF4
EOF4 EOF4

View File

@ -2,5 +2,5 @@
$TEST $TEST
Q Q
a\bc a\bc
a"c 11-$a-\t-\-\"-`-\--\z-\*-\?-22 33-$a-\t-\-"-`-\--\z-\*-\?-44
done:0 done:0

View File

@ -7,6 +7,8 @@ echo `echo '\'TEST\`echo ZZ\`BEST`
echo `echo \\$TEST` echo `echo \\$TEST`
echo `echo \$TEST` echo `echo \$TEST`
echo a`echo \\\\b`c echo a`echo \\\\b`c
# \" etc are NOT special (passed verbatim WITH \)!
echo a`echo \"`c # \" is not special if in unquoted `cmd` (passed verbatim WITH \),
# but is special in quoted one
echo `echo 11'-$a-\t-\\-\"-\`-\--\z-\*-\?-'22` "`echo 33'-$a-\t-\\-\"-\`-\--\z-\*-\?-'44`"
echo done:$? echo done:$?