summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-08 21:51:33 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-08 21:51:33 +0000
commit5c090a96f98f5a70af792945aa41ea53f82f39e2 (patch)
tree1a95c51f459436ca1e66157a708dbb34506e732c /shell/hush.c
parentffe6f8085170ed6a9780906374ca781e9c4291cb (diff)
downloadbusybox-w32-5c090a96f98f5a70af792945aa41ea53f82f39e2.tar.gz
busybox-w32-5c090a96f98f5a70af792945aa41ea53f82f39e2.tar.bz2
busybox-w32-5c090a96f98f5a70af792945aa41ea53f82f39e2.zip
hush: more rodust detection of unterminated strings etc;
fix a case where we forget to copy `cmd` text; optimize nommu heredoc helper by not passing environment to it; add several tests function old new delta add_till_closing_paren 256 308 +52 parse_stream 2337 2378 +41 add_till_backquote 82 111 +29 re_execute_shell 269 284 +15 handle_dollar 802 812 +10 parse_stream_dquoted 316 320 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 6/0 up/down: 151/0) Total: 151 bytes
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c96
1 files changed, 65 insertions, 31 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 4641dca11..9920e98c6 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2241,7 +2241,10 @@ static void re_execute_shell(const char *s, int is_heredoc)
2241 2241
2242 debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s); 2242 debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
2243 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL); 2243 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
2244 execv(bb_busybox_exec_path, G.argv_from_re_execing); 2244 execve(bb_busybox_exec_path,
2245 G.argv_from_re_execing,
2246 (is_heredoc ? pp /* points to NULL ptr */ : environ)
2247 );
2245 /* Fallback. Useful for init=/bin/hush usage etc */ 2248 /* Fallback. Useful for init=/bin/hush usage etc */
2246 if (G.argv0_for_re_execing[0] == '/') 2249 if (G.argv0_for_re_execing[0] == '/')
2247 execv(G.argv0_for_re_execing, G.argv_from_re_execing); 2250 execv(G.argv0_for_re_execing, G.argv_from_re_execing);
@@ -4402,35 +4405,40 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
4402 4405
4403#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT 4406#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT
4404/* Subroutines for copying $(...) and `...` things */ 4407/* Subroutines for copying $(...) and `...` things */
4405static void add_till_backquote(o_string *dest, struct in_str *input); 4408static int add_till_backquote(o_string *dest, struct in_str *input);
4406/* '...' */ 4409/* '...' */
4407static void add_till_single_quote(o_string *dest, struct in_str *input) 4410static int add_till_single_quote(o_string *dest, struct in_str *input)
4408{ 4411{
4409 while (1) { 4412 while (1) {
4410 int ch = i_getch(input); 4413 int ch = i_getch(input);
4411 if (ch == EOF) 4414 if (ch == EOF) {
4412 break; 4415 syntax("unterminated '");
4416 return 1;
4417 }
4413 if (ch == '\'') 4418 if (ch == '\'')
4414 break; 4419 return 0;
4415 o_addchr(dest, ch); 4420 o_addchr(dest, ch);
4416 } 4421 }
4417} 4422}
4418/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ 4423/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
4419static void add_till_double_quote(o_string *dest, struct in_str *input) 4424static int add_till_double_quote(o_string *dest, struct in_str *input)
4420{ 4425{
4421 while (1) { 4426 while (1) {
4422 int ch = i_getch(input); 4427 int ch = i_getch(input);
4428 if (ch == EOF) {
4429 syntax("unterminated \"");
4430 return 1;
4431 }
4423 if (ch == '"') 4432 if (ch == '"')
4424 break; 4433 return 0;
4425 if (ch == '\\') { /* \x. Copy both chars. */ 4434 if (ch == '\\') { /* \x. Copy both chars. */
4426 o_addchr(dest, ch); 4435 o_addchr(dest, ch);
4427 ch = i_getch(input); 4436 ch = i_getch(input);
4428 } 4437 }
4429 if (ch == EOF)
4430 break;
4431 o_addchr(dest, ch); 4438 o_addchr(dest, ch);
4432 if (ch == '`') { 4439 if (ch == '`') {
4433 add_till_backquote(dest, input); 4440 if (add_till_backquote(dest, input))
4441 return 1;
4434 o_addchr(dest, ch); 4442 o_addchr(dest, ch);
4435 continue; 4443 continue;
4436 } 4444 }
@@ -4451,20 +4459,27 @@ static void add_till_double_quote(o_string *dest, struct in_str *input)
4451 * Example Output 4459 * Example Output
4452 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST 4460 * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST
4453 */ 4461 */
4454static void add_till_backquote(o_string *dest, struct in_str *input) 4462static int add_till_backquote(o_string *dest, struct in_str *input)
4455{ 4463{
4456 while (1) { 4464 while (1) {
4457 int ch = i_getch(input); 4465 int ch = i_getch(input);
4466 if (ch == EOF) {
4467 syntax("unterminated `");
4468 return 1;
4469 }
4458 if (ch == '`') 4470 if (ch == '`')
4459 break; 4471 return 0;
4460 if (ch == '\\') { /* \x. Copy both chars unless it is \` */ 4472 if (ch == '\\') {
4473 /* \x. Copy both chars unless it is \` */
4461 int ch2 = i_getch(input); 4474 int ch2 = i_getch(input);
4475 if (ch2 == EOF) {
4476 syntax("unterminated `");
4477 return 1;
4478 }
4462 if (ch2 != '`' && ch2 != '$' && ch2 != '\\') 4479 if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
4463 o_addchr(dest, ch); 4480 o_addchr(dest, ch);
4464 ch = ch2; 4481 ch = ch2;
4465 } 4482 }
4466 if (ch == EOF)
4467 break;
4468 o_addchr(dest, ch); 4483 o_addchr(dest, ch);
4469 } 4484 }
4470} 4485}
@@ -4480,13 +4495,15 @@ static void add_till_backquote(o_string *dest, struct in_str *input)
4480 * echo $(echo 'TEST)' BEST) TEST) BEST 4495 * echo $(echo 'TEST)' BEST) TEST) BEST
4481 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST 4496 * echo $(echo \(\(TEST\) BEST) ((TEST) BEST
4482 */ 4497 */
4483static void add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl) 4498static int add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl)
4484{ 4499{
4485 int count = 0; 4500 int count = 0;
4486 while (1) { 4501 while (1) {
4487 int ch = i_getch(input); 4502 int ch = i_getch(input);
4488 if (ch == EOF) 4503 if (ch == EOF) {
4489 break; 4504 syntax("unterminated )");
4505 return 1;
4506 }
4490 if (ch == '(') 4507 if (ch == '(')
4491 count++; 4508 count++;
4492 if (ch == ')') { 4509 if (ch == ')') {
@@ -4501,23 +4518,29 @@ static void add_till_closing_paren(o_string *dest, struct in_str *input, bool db
4501 } 4518 }
4502 o_addchr(dest, ch); 4519 o_addchr(dest, ch);
4503 if (ch == '\'') { 4520 if (ch == '\'') {
4504 add_till_single_quote(dest, input); 4521 if (add_till_single_quote(dest, input))
4522 return 1;
4505 o_addchr(dest, ch); 4523 o_addchr(dest, ch);
4506 continue; 4524 continue;
4507 } 4525 }
4508 if (ch == '"') { 4526 if (ch == '"') {
4509 add_till_double_quote(dest, input); 4527 if (add_till_double_quote(dest, input))
4528 return 1;
4510 o_addchr(dest, ch); 4529 o_addchr(dest, ch);
4511 continue; 4530 continue;
4512 } 4531 }
4513 if (ch == '\\') { /* \x. Copy verbatim. Important for \(, \) */ 4532 if (ch == '\\') {
4533 /* \x. Copy verbatim. Important for \(, \) */
4514 ch = i_getch(input); 4534 ch = i_getch(input);
4515 if (ch == EOF) 4535 if (ch == EOF) {
4516 break; 4536 syntax("unterminated )");
4537 return 1;
4538 }
4517 o_addchr(dest, ch); 4539 o_addchr(dest, ch);
4518 continue; 4540 continue;
4519 } 4541 }
4520 } 4542 }
4543 return 0;
4521} 4544}
4522#endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT */ 4545#endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT */
4523 4546
@@ -4658,7 +4681,8 @@ static int handle_dollar(o_string *as_string,
4658# if !BB_MMU 4681# if !BB_MMU
4659 pos = dest->length; 4682 pos = dest->length;
4660# endif 4683# endif
4661 add_till_closing_paren(dest, input, true); 4684 if (add_till_closing_paren(dest, input, true))
4685 return 1;
4662# if !BB_MMU 4686# if !BB_MMU
4663 if (as_string) { 4687 if (as_string) {
4664 o_addstr(as_string, dest->data + pos); 4688 o_addstr(as_string, dest->data + pos);
@@ -4671,20 +4695,19 @@ static int handle_dollar(o_string *as_string,
4671 } 4695 }
4672# endif 4696# endif
4673# if ENABLE_HUSH_TICK 4697# if ENABLE_HUSH_TICK
4674 //int pos = dest->length;
4675 o_addchr(dest, SPECIAL_VAR_SYMBOL); 4698 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4676 o_addchr(dest, quote_mask | '`'); 4699 o_addchr(dest, quote_mask | '`');
4677# if !BB_MMU 4700# if !BB_MMU
4678 pos = dest->length; 4701 pos = dest->length;
4679# endif 4702# endif
4680 add_till_closing_paren(dest, input, false); 4703 if (add_till_closing_paren(dest, input, false))
4704 return 1;
4681# if !BB_MMU 4705# if !BB_MMU
4682 if (as_string) { 4706 if (as_string) {
4683 o_addstr(as_string, dest->data + pos); 4707 o_addstr(as_string, dest->data + pos);
4684 o_addchr(as_string, '`'); 4708 o_addchr(as_string, '`');
4685 } 4709 }
4686# endif 4710# endif
4687 //debug_printf_subst("SUBST RES2 '%s'\n", dest->data + pos);
4688 o_addchr(dest, SPECIAL_VAR_SYMBOL); 4711 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4689# endif 4712# endif
4690 break; 4713 break;
@@ -4778,7 +4801,8 @@ static int parse_stream_dquoted(o_string *as_string,
4778 //int pos = dest->length; 4801 //int pos = dest->length;
4779 o_addchr(dest, SPECIAL_VAR_SYMBOL); 4802 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4780 o_addchr(dest, 0x80 | '`'); 4803 o_addchr(dest, 0x80 | '`');
4781 add_till_backquote(dest, input); 4804 if (add_till_backquote(dest, input))
4805 return 1;
4782 o_addchr(dest, SPECIAL_VAR_SYMBOL); 4806 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4783 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); 4807 //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
4784 goto again; 4808 goto again;
@@ -5043,10 +5067,20 @@ static struct pipe *parse_stream(char **pstring,
5043 break; 5067 break;
5044#if ENABLE_HUSH_TICK 5068#if ENABLE_HUSH_TICK
5045 case '`': { 5069 case '`': {
5046 //int pos = dest.length; 5070#if !BB_MMU
5071 int pos;
5072#endif
5047 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 5073 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
5048 o_addchr(&dest, '`'); 5074 o_addchr(&dest, '`');
5049 add_till_backquote(&dest, input); 5075#if !BB_MMU
5076 pos = dest.length;
5077#endif
5078 if (add_till_backquote(&dest, input))
5079 goto parse_error;
5080#if !BB_MMU
5081 o_addstr(&ctx.as_string, dest.data + pos);
5082 o_addchr(&ctx.as_string, '`');
5083#endif
5050 o_addchr(&dest, SPECIAL_VAR_SYMBOL); 5084 o_addchr(&dest, SPECIAL_VAR_SYMBOL);
5051 //debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos); 5085 //debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos);
5052 break; 5086 break;