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:
Denis Vlasenko 2007-05-24 12:18:16 +00:00
parent 90e485ce79
commit b055001b6a
4 changed files with 15 additions and 9 deletions

View File

@ -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;

View File

@ -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);
} }

View File

@ -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);

View File

@ -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;