aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-09-12 15:05:39 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-09-12 15:05:39 +0200
commitacd5bc8f649fad335d80c5289512b404f08ac8e2 (patch)
tree56594a40d09e2032b7be039c3c1c567a3871dde1 /shell/hush.c
parent958581a8d9583da8b9df0b69123e0c3990f7b3ff (diff)
downloadbusybox-w32-acd5bc8f649fad335d80c5289512b404f08ac8e2.tar.gz
busybox-w32-acd5bc8f649fad335d80c5289512b404f08ac8e2.tar.bz2
busybox-w32-acd5bc8f649fad335d80c5289512b404f08ac8e2.zip
hush: fix handling of \" in quoted/unquoted `cmd`
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c48
1 files changed, 29 insertions, 19 deletions
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 @@
234//usage:#define hush_full_usage "" 234//usage:#define hush_full_usage ""
235//usage:#define msh_trivial_usage NOUSAGE_STR 235//usage:#define msh_trivial_usage NOUSAGE_STR
236//usage:#define msh_full_usage "" 236//usage:#define msh_full_usage ""
237//usage:#define sh_trivial_usage NOUSAGE_STR
238//usage:#define sh_full_usage ""
239//usage:#define bash_trivial_usage NOUSAGE_STR
240//usage:#define bash_full_usage ""
237 241
238 242
239/* Build knobs */ 243/* Build knobs */
@@ -1367,9 +1371,15 @@ static void hush_exit(int exitcode)
1367#endif 1371#endif
1368} 1372}
1369 1373
1374
1370static int check_and_run_traps(int sig) 1375static int check_and_run_traps(int sig)
1371{ 1376{
1372 static const struct timespec zero_timespec; 1377 /* I want it in rodata, not in bss.
1378 * gcc 4.2.1 puts it in rodata only if it has { 0, 0 }
1379 * initializer. But other compilers may still use bss.
1380 * TODO: find more portable solution.
1381 */
1382 static const struct timespec zero_timespec = { 0, 0 };
1373 smalluint save_rcode; 1383 smalluint save_rcode;
1374 int last_sig = 0; 1384 int last_sig = 0;
1375 1385
@@ -3367,7 +3377,7 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
3367 3377
3368#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS 3378#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS
3369/* Subroutines for copying $(...) and `...` things */ 3379/* Subroutines for copying $(...) and `...` things */
3370static void add_till_backquote(o_string *dest, struct in_str *input); 3380static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
3371/* '...' */ 3381/* '...' */
3372static void add_till_single_quote(o_string *dest, struct in_str *input) 3382static void add_till_single_quote(o_string *dest, struct in_str *input)
3373{ 3383{
@@ -3399,7 +3409,7 @@ static void add_till_double_quote(o_string *dest, struct in_str *input)
3399 } 3409 }
3400 o_addchr(dest, ch); 3410 o_addchr(dest, ch);
3401 if (ch == '`') { 3411 if (ch == '`') {
3402 add_till_backquote(dest, input); 3412 add_till_backquote(dest, input, /*in_dquote:*/ 1);
3403 o_addchr(dest, ch); 3413 o_addchr(dest, ch);
3404 continue; 3414 continue;
3405 } 3415 }
@@ -3420,26 +3430,26 @@ static void add_till_double_quote(o_string *dest, struct in_str *input)
3420 * Example Output 3430 * Example Output
3421 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST 3431 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST
3422 */ 3432 */
3423static void add_till_backquote(o_string *dest, struct in_str *input) 3433static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote)
3424{ 3434{
3425 while (1) { 3435 while (1) {
3426 int ch = i_getch(input); 3436 int ch = i_getch(input);
3427 if (ch == EOF) {
3428 syntax_error_unterm_ch('`');
3429 /*xfunc_die(); - redundant */
3430 }
3431 if (ch == '`') 3437 if (ch == '`')
3432 return; 3438 return;
3433 if (ch == '\\') { 3439 if (ch == '\\') {
3434 /* \x. Copy both chars unless it is \` */ 3440 /* \x. Copy both unless it is \`, \$, \\ and maybe \" */
3435 int ch2 = i_getch(input); 3441 ch = i_getch(input);
3436 if (ch2 == EOF) { 3442 if (ch != '`'
3437 syntax_error_unterm_ch('`'); 3443 && ch != '$'
3438 /*xfunc_die(); - redundant */ 3444 && ch != '\\'
3445 && (!in_dquote || ch != '"')
3446 ) {
3447 o_addchr(dest, '\\');
3439 } 3448 }
3440 if (ch2 != '`' && ch2 != '$' && ch2 != '\\') 3449 }
3441 o_addchr(dest, ch); 3450 if (ch == EOF) {
3442 ch = ch2; 3451 syntax_error_unterm_ch('`');
3452 /*xfunc_die(); - redundant */
3443 } 3453 }
3444 o_addchr(dest, ch); 3454 o_addchr(dest, ch);
3445 } 3455 }
@@ -3504,7 +3514,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
3504 continue; 3514 continue;
3505 } 3515 }
3506 if (ch == '`') { 3516 if (ch == '`') {
3507 add_till_backquote(dest, input); 3517 add_till_backquote(dest, input, /*in_dquote:*/ 0);
3508 o_addchr(dest, ch); 3518 o_addchr(dest, ch);
3509 continue; 3519 continue;
3510 } 3520 }
@@ -3818,7 +3828,7 @@ static int encode_string(o_string *as_string,
3818 //unsigned pos = dest->length; 3828 //unsigned pos = dest->length;
3819 o_addchr(dest, SPECIAL_VAR_SYMBOL); 3829 o_addchr(dest, SPECIAL_VAR_SYMBOL);
3820 o_addchr(dest, 0x80 | '`'); 3830 o_addchr(dest, 0x80 | '`');
3821 add_till_backquote(dest, input); 3831 add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"');
3822 o_addchr(dest, SPECIAL_VAR_SYMBOL); 3832 o_addchr(dest, SPECIAL_VAR_SYMBOL);
3823 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); 3833 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
3824 goto again; 3834 goto again;
@@ -4191,7 +4201,7 @@ static struct pipe *parse_stream(char **pstring,
4191 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 4201 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
4192 o_addchr(&dest, '`'); 4202 o_addchr(&dest, '`');
4193 pos = dest.length; 4203 pos = dest.length;
4194 add_till_backquote(&dest, input); 4204 add_till_backquote(&dest, input, /*in_dquote:*/ 0);
4195# if !BB_MMU 4205# if !BB_MMU
4196 o_addstr(&ctx.as_string, dest.data + pos); 4206 o_addstr(&ctx.as_string, dest.data + pos);
4197 o_addchr(&ctx.as_string, '`'); 4207 o_addchr(&ctx.as_string, '`');