hush: fix handling of \" in quoted/unquoted cmd
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
parent
958581a8d9
commit
acd5bc8f64
46
shell/hush.c
46
shell/hush.c
@ -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, '`');
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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:$?
|
||||||
|
Loading…
Reference in New Issue
Block a user