hush: fix handling of unmatched ${name (without closing '}') -
was eating all remaining input, potentially megabytes. nofork: save/restore die_jmp too nofork: use -2222 instead of -111 as "special" return valur for zero (-111 is used by some applets. -2222 won't fit in exitcode and thus safer)
This commit is contained in:
parent
90e485ce79
commit
b055001b6a
@ -512,6 +512,7 @@ int wait_nohang(int *wstat);
|
|||||||
/* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */
|
/* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */
|
||||||
int spawn_and_wait(char **argv);
|
int spawn_and_wait(char **argv);
|
||||||
struct nofork_save_area {
|
struct nofork_save_area {
|
||||||
|
jmp_buf die_jmp;
|
||||||
const struct bb_applet *current_applet;
|
const struct bb_applet *current_applet;
|
||||||
int xfunc_error_retval;
|
int xfunc_error_retval;
|
||||||
uint32_t option_mask32;
|
uint32_t option_mask32;
|
||||||
|
@ -27,9 +27,9 @@ void xfunc_die(void)
|
|||||||
* p = xmalloc(10);
|
* p = xmalloc(10);
|
||||||
* q = xmalloc(10); // BUG! if this dies, we leak p!
|
* q = xmalloc(10); // BUG! if this dies, we leak p!
|
||||||
*/
|
*/
|
||||||
/* -111 means "zero" (longjmp can't pass 0)
|
/* -2222 means "zero" (longjmp can't pass 0)
|
||||||
* spawn_and_wait() catches -111. */
|
* run_nofork_applet() catches -2222. */
|
||||||
longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -111);
|
longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222);
|
||||||
}
|
}
|
||||||
sleep(die_sleep);
|
sleep(die_sleep);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ int wait_pid(int *wstat, int pid)
|
|||||||
#if ENABLE_FEATURE_PREFER_APPLETS
|
#if ENABLE_FEATURE_PREFER_APPLETS
|
||||||
void save_nofork_data(struct nofork_save_area *save)
|
void save_nofork_data(struct nofork_save_area *save)
|
||||||
{
|
{
|
||||||
|
memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
|
||||||
save->current_applet = current_applet;
|
save->current_applet = current_applet;
|
||||||
save->xfunc_error_retval = xfunc_error_retval;
|
save->xfunc_error_retval = xfunc_error_retval;
|
||||||
save->option_mask32 = option_mask32;
|
save->option_mask32 = option_mask32;
|
||||||
@ -112,6 +113,7 @@ void save_nofork_data(struct nofork_save_area *save)
|
|||||||
|
|
||||||
void restore_nofork_data(struct nofork_save_area *save)
|
void restore_nofork_data(struct nofork_save_area *save)
|
||||||
{
|
{
|
||||||
|
memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
|
||||||
current_applet = save->current_applet;
|
current_applet = save->current_applet;
|
||||||
xfunc_error_retval = save->xfunc_error_retval;
|
xfunc_error_retval = save->xfunc_error_retval;
|
||||||
option_mask32 = save->option_mask32;
|
option_mask32 = save->option_mask32;
|
||||||
@ -147,7 +149,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet
|
|||||||
rc = a->main(argc, tmp_argv);
|
rc = a->main(argc, tmp_argv);
|
||||||
} else { /* xfunc died in NOFORK applet */
|
} else { /* xfunc died in NOFORK applet */
|
||||||
/* in case they meant to return 0... */
|
/* in case they meant to return 0... */
|
||||||
if (rc == -111)
|
if (rc == -2222)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +161,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet
|
|||||||
int run_nofork_applet(const struct bb_applet *a, char **argv)
|
int run_nofork_applet(const struct bb_applet *a, char **argv)
|
||||||
{
|
{
|
||||||
struct nofork_save_area old;
|
struct nofork_save_area old;
|
||||||
|
|
||||||
/* Saving globals */
|
/* Saving globals */
|
||||||
save_nofork_data(&old);
|
save_nofork_data(&old);
|
||||||
return run_nofork_applet_prime(&old, a, argv);
|
return run_nofork_applet_prime(&old, a, argv);
|
||||||
|
12
shell/hush.c
12
shell/hush.c
@ -427,13 +427,15 @@ enum { run_list_level = 0 };
|
|||||||
/* Normal */
|
/* Normal */
|
||||||
static void syntax(const char *msg)
|
static void syntax(const char *msg)
|
||||||
{
|
{
|
||||||
bb_error_msg(msg ? "%s: %s" : "syntax error", "syntax error", msg);
|
(interactive_fd ? bb_error_msg : bb_error_msg_and_die)
|
||||||
|
(msg ? "%s: %s" : "syntax error", "syntax error", msg);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Debug */
|
/* Debug */
|
||||||
static void syntax_lineno(int line)
|
static void syntax_lineno(int line)
|
||||||
{
|
{
|
||||||
bb_error_msg("syntax error hush.c:%d", line);
|
(interactive_fd ? bb_error_msg : bb_error_msg_and_die)
|
||||||
|
("syntax error hush.c:%d", line);
|
||||||
}
|
}
|
||||||
#define syntax(str) syntax_lineno(__LINE__)
|
#define syntax(str) syntax_lineno(__LINE__)
|
||||||
#endif
|
#endif
|
||||||
@ -3309,13 +3311,13 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
|
|||||||
/* XXX maybe someone will try to escape the '}' */
|
/* XXX maybe someone will try to escape the '}' */
|
||||||
while (1) {
|
while (1) {
|
||||||
ch = b_getch(input);
|
ch = b_getch(input);
|
||||||
if (ch == EOF) {
|
if (ch == '}')
|
||||||
|
break;
|
||||||
|
if (!isalnum(ch) && ch != '_') {
|
||||||
syntax("unterminated ${name}");
|
syntax("unterminated ${name}");
|
||||||
debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
|
debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ch == '}')
|
|
||||||
break;
|
|
||||||
debug_printf_parse(": '%c'\n", ch);
|
debug_printf_parse(": '%c'\n", ch);
|
||||||
b_addchr(dest, ch | quote_mask);
|
b_addchr(dest, ch | quote_mask);
|
||||||
quote_mask = 0;
|
quote_mask = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user