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
This commit is contained in:
96
shell/hush.c
96
shell/hush.c
@@ -2241,7 +2241,10 @@ static void re_execute_shell(const char *s, int is_heredoc)
|
||||
|
||||
debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
|
||||
sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
|
||||
execv(bb_busybox_exec_path, G.argv_from_re_execing);
|
||||
execve(bb_busybox_exec_path,
|
||||
G.argv_from_re_execing,
|
||||
(is_heredoc ? pp /* points to NULL ptr */ : environ)
|
||||
);
|
||||
/* Fallback. Useful for init=/bin/hush usage etc */
|
||||
if (G.argv0_for_re_execing[0] == '/')
|
||||
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,
|
||||
|
||||
#if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT
|
||||
/* Subroutines for copying $(...) and `...` things */
|
||||
static void add_till_backquote(o_string *dest, struct in_str *input);
|
||||
static int add_till_backquote(o_string *dest, struct in_str *input);
|
||||
/* '...' */
|
||||
static void add_till_single_quote(o_string *dest, struct in_str *input)
|
||||
static int add_till_single_quote(o_string *dest, struct in_str *input)
|
||||
{
|
||||
while (1) {
|
||||
int ch = i_getch(input);
|
||||
if (ch == EOF)
|
||||
break;
|
||||
if (ch == EOF) {
|
||||
syntax("unterminated '");
|
||||
return 1;
|
||||
}
|
||||
if (ch == '\'')
|
||||
break;
|
||||
return 0;
|
||||
o_addchr(dest, ch);
|
||||
}
|
||||
}
|
||||
/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
|
||||
static void add_till_double_quote(o_string *dest, struct in_str *input)
|
||||
static int add_till_double_quote(o_string *dest, struct in_str *input)
|
||||
{
|
||||
while (1) {
|
||||
int ch = i_getch(input);
|
||||
if (ch == EOF) {
|
||||
syntax("unterminated \"");
|
||||
return 1;
|
||||
}
|
||||
if (ch == '"')
|
||||
break;
|
||||
return 0;
|
||||
if (ch == '\\') { /* \x. Copy both chars. */
|
||||
o_addchr(dest, ch);
|
||||
ch = i_getch(input);
|
||||
}
|
||||
if (ch == EOF)
|
||||
break;
|
||||
o_addchr(dest, ch);
|
||||
if (ch == '`') {
|
||||
add_till_backquote(dest, input);
|
||||
if (add_till_backquote(dest, input))
|
||||
return 1;
|
||||
o_addchr(dest, ch);
|
||||
continue;
|
||||
}
|
||||
@@ -4451,20 +4459,27 @@ 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 int add_till_backquote(o_string *dest, struct in_str *input)
|
||||
{
|
||||
while (1) {
|
||||
int ch = i_getch(input);
|
||||
if (ch == EOF) {
|
||||
syntax("unterminated `");
|
||||
return 1;
|
||||
}
|
||||
if (ch == '`')
|
||||
break;
|
||||
if (ch == '\\') { /* \x. Copy both chars unless it is \` */
|
||||
return 0;
|
||||
if (ch == '\\') {
|
||||
/* \x. Copy both chars unless it is \` */
|
||||
int ch2 = i_getch(input);
|
||||
if (ch2 == EOF) {
|
||||
syntax("unterminated `");
|
||||
return 1;
|
||||
}
|
||||
if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
|
||||
o_addchr(dest, ch);
|
||||
ch = ch2;
|
||||
}
|
||||
if (ch == EOF)
|
||||
break;
|
||||
o_addchr(dest, ch);
|
||||
}
|
||||
}
|
||||
@@ -4480,13 +4495,15 @@ static void add_till_backquote(o_string *dest, struct in_str *input)
|
||||
* echo $(echo 'TEST)' BEST) TEST) BEST
|
||||
* echo $(echo \(\(TEST\) BEST) ((TEST) BEST
|
||||
*/
|
||||
static void add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl)
|
||||
static int add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl)
|
||||
{
|
||||
int count = 0;
|
||||
while (1) {
|
||||
int ch = i_getch(input);
|
||||
if (ch == EOF)
|
||||
break;
|
||||
if (ch == EOF) {
|
||||
syntax("unterminated )");
|
||||
return 1;
|
||||
}
|
||||
if (ch == '(')
|
||||
count++;
|
||||
if (ch == ')') {
|
||||
@@ -4501,23 +4518,29 @@ static void add_till_closing_paren(o_string *dest, struct in_str *input, bool db
|
||||
}
|
||||
o_addchr(dest, ch);
|
||||
if (ch == '\'') {
|
||||
add_till_single_quote(dest, input);
|
||||
if (add_till_single_quote(dest, input))
|
||||
return 1;
|
||||
o_addchr(dest, ch);
|
||||
continue;
|
||||
}
|
||||
if (ch == '"') {
|
||||
add_till_double_quote(dest, input);
|
||||
if (add_till_double_quote(dest, input))
|
||||
return 1;
|
||||
o_addchr(dest, ch);
|
||||
continue;
|
||||
}
|
||||
if (ch == '\\') { /* \x. Copy verbatim. Important for \(, \) */
|
||||
if (ch == '\\') {
|
||||
/* \x. Copy verbatim. Important for \(, \) */
|
||||
ch = i_getch(input);
|
||||
if (ch == EOF)
|
||||
break;
|
||||
if (ch == EOF) {
|
||||
syntax("unterminated )");
|
||||
return 1;
|
||||
}
|
||||
o_addchr(dest, ch);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT */
|
||||
|
||||
@@ -4658,7 +4681,8 @@ static int handle_dollar(o_string *as_string,
|
||||
# if !BB_MMU
|
||||
pos = dest->length;
|
||||
# endif
|
||||
add_till_closing_paren(dest, input, true);
|
||||
if (add_till_closing_paren(dest, input, true))
|
||||
return 1;
|
||||
# if !BB_MMU
|
||||
if (as_string) {
|
||||
o_addstr(as_string, dest->data + pos);
|
||||
@@ -4671,20 +4695,19 @@ static int handle_dollar(o_string *as_string,
|
||||
}
|
||||
# endif
|
||||
# if ENABLE_HUSH_TICK
|
||||
//int pos = dest->length;
|
||||
o_addchr(dest, SPECIAL_VAR_SYMBOL);
|
||||
o_addchr(dest, quote_mask | '`');
|
||||
# if !BB_MMU
|
||||
pos = dest->length;
|
||||
# endif
|
||||
add_till_closing_paren(dest, input, false);
|
||||
if (add_till_closing_paren(dest, input, false))
|
||||
return 1;
|
||||
# if !BB_MMU
|
||||
if (as_string) {
|
||||
o_addstr(as_string, dest->data + pos);
|
||||
o_addchr(as_string, '`');
|
||||
}
|
||||
# endif
|
||||
//debug_printf_subst("SUBST RES2 '%s'\n", dest->data + pos);
|
||||
o_addchr(dest, SPECIAL_VAR_SYMBOL);
|
||||
# endif
|
||||
break;
|
||||
@@ -4778,7 +4801,8 @@ static int parse_stream_dquoted(o_string *as_string,
|
||||
//int pos = dest->length;
|
||||
o_addchr(dest, SPECIAL_VAR_SYMBOL);
|
||||
o_addchr(dest, 0x80 | '`');
|
||||
add_till_backquote(dest, input);
|
||||
if (add_till_backquote(dest, input))
|
||||
return 1;
|
||||
o_addchr(dest, SPECIAL_VAR_SYMBOL);
|
||||
//debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos);
|
||||
goto again;
|
||||
@@ -5043,10 +5067,20 @@ static struct pipe *parse_stream(char **pstring,
|
||||
break;
|
||||
#if ENABLE_HUSH_TICK
|
||||
case '`': {
|
||||
//int pos = dest.length;
|
||||
#if !BB_MMU
|
||||
int pos;
|
||||
#endif
|
||||
o_addchr(&dest, SPECIAL_VAR_SYMBOL);
|
||||
o_addchr(&dest, '`');
|
||||
add_till_backquote(&dest, input);
|
||||
#if !BB_MMU
|
||||
pos = dest.length;
|
||||
#endif
|
||||
if (add_till_backquote(&dest, input))
|
||||
goto parse_error;
|
||||
#if !BB_MMU
|
||||
o_addstr(&ctx.as_string, dest.data + pos);
|
||||
o_addchr(&ctx.as_string, '`');
|
||||
#endif
|
||||
o_addchr(&dest, SPECIAL_VAR_SYMBOL);
|
||||
//debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user