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)
No binary (build failed)
—
(log yok)
| @@ -512,6 +512,7 @@ int wait_nohang(int *wstat); | |
| /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */ | |
| int spawn_and_wait(char **argv); | |
| struct nofork_save_area { | |
| + | jmp_buf die_jmp; |
| const struct bb_applet *current_applet; | |
| int xfunc_error_retval; | |
| uint32_t option_mask32; | |
| @@ -27,9 +27,9 @@ void xfunc_die(void) | |
| * p = xmalloc(10); | |
| * q = xmalloc(10); // BUG! if this dies, we leak p! | |
| */ | |
| - | /* -111 means "zero" (longjmp can't pass 0) |
| - | * spawn_and_wait() catches -111. */ |
| - | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -111); |
| + | /* -2222 means "zero" (longjmp can't pass 0) |
| + | * run_nofork_applet() catches -2222. */ |
| + | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); |
| } | |
| sleep(die_sleep); | |
| } | |
| @@ -103,6 +103,7 @@ int wait_pid(int *wstat, int pid) | |
| #if ENABLE_FEATURE_PREFER_APPLETS | |
| void save_nofork_data(struct nofork_save_area *save) | |
| { | |
| + | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); |
| save->current_applet = current_applet; | |
| save->xfunc_error_retval = xfunc_error_retval; | |
| 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) | |
| { | |
| + | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); |
| current_applet = save->current_applet; | |
| xfunc_error_retval = save->xfunc_error_retval; | |
| 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); | |
| } else { /* xfunc died in NOFORK applet */ | |
| /* in case they meant to return 0... */ | |
| - | if (rc == -111) |
| + | if (rc == -2222) |
| 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) | |
| { | |
| struct nofork_save_area old; | |
| + | |
| /* Saving globals */ | |
| save_nofork_data(&old); | |
| return run_nofork_applet_prime(&old, a, argv); | |
| @@ -427,13 +427,15 @@ enum { run_list_level = 0 }; | |
| /* Normal */ | |
| 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 | |
| /* Debug */ | |
| 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__) | |
| #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 '}' */ | |
| while (1) { | |
| ch = b_getch(input); | |
| - | if (ch == EOF) { |
| + | if (ch == '}') |
| + | break; |
| + | if (!isalnum(ch) && ch != '_') { |
| syntax("unterminated ${name}"); | |
| debug_printf_parse("handle_dollar return 1: unterminated ${name}\n"); | |
| return 1; | |
| } | |
| - | if (ch == '}') |
| - | break; |
| debug_printf_parse(": '%c'\n", ch); | |
| b_addchr(dest, ch | quote_mask); | |
| quote_mask = 0; | |