diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-24 12:18:16 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-24 12:18:16 +0000 |
| commit | b055001b6a69cf8fd513d36622cf693ee20c0e92 (patch) | |
| tree | 13b92d347774d453d227b2f29dee695974a8727d | |
| parent | 90e485ce79b8a0cd345bc5be76100291ec589579 (diff) | |
| download | busybox-w32-b055001b6a69cf8fd513d36622cf693ee20c0e92.tar.gz busybox-w32-b055001b6a69cf8fd513d36622cf693ee20c0e92.tar.bz2 busybox-w32-b055001b6a69cf8fd513d36622cf693ee20c0e92.zip | |
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)
| -rw-r--r-- | include/libbb.h | 1 | ||||
| -rw-r--r-- | libbb/error_msg_and_die.c | 6 | ||||
| -rw-r--r-- | libbb/vfork_daemon_rexec.c | 5 | ||||
| -rw-r--r-- | shell/hush.c | 12 |
4 files changed, 15 insertions, 9 deletions
diff --git a/include/libbb.h b/include/libbb.h index 32bb3113d..1859a3f09 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -512,6 +512,7 @@ int wait_nohang(int *wstat); | |||
| 512 | /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */ | 512 | /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */ |
| 513 | int spawn_and_wait(char **argv); | 513 | int spawn_and_wait(char **argv); |
| 514 | struct nofork_save_area { | 514 | struct nofork_save_area { |
| 515 | jmp_buf die_jmp; | ||
| 515 | const struct bb_applet *current_applet; | 516 | const struct bb_applet *current_applet; |
| 516 | int xfunc_error_retval; | 517 | int xfunc_error_retval; |
| 517 | uint32_t option_mask32; | 518 | uint32_t option_mask32; |
diff --git a/libbb/error_msg_and_die.c b/libbb/error_msg_and_die.c index 20d971591..0e99a03cf 100644 --- a/libbb/error_msg_and_die.c +++ b/libbb/error_msg_and_die.c | |||
| @@ -27,9 +27,9 @@ void xfunc_die(void) | |||
| 27 | * p = xmalloc(10); | 27 | * p = xmalloc(10); |
| 28 | * q = xmalloc(10); // BUG! if this dies, we leak p! | 28 | * q = xmalloc(10); // BUG! if this dies, we leak p! |
| 29 | */ | 29 | */ |
| 30 | /* -111 means "zero" (longjmp can't pass 0) | 30 | /* -2222 means "zero" (longjmp can't pass 0) |
| 31 | * spawn_and_wait() catches -111. */ | 31 | * run_nofork_applet() catches -2222. */ |
| 32 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -111); | 32 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); |
| 33 | } | 33 | } |
| 34 | sleep(die_sleep); | 34 | sleep(die_sleep); |
| 35 | } | 35 | } |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index a2572b0a9..349628796 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
| @@ -103,6 +103,7 @@ int wait_pid(int *wstat, int pid) | |||
| 103 | #if ENABLE_FEATURE_PREFER_APPLETS | 103 | #if ENABLE_FEATURE_PREFER_APPLETS |
| 104 | void save_nofork_data(struct nofork_save_area *save) | 104 | void save_nofork_data(struct nofork_save_area *save) |
| 105 | { | 105 | { |
| 106 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); | ||
| 106 | save->current_applet = current_applet; | 107 | save->current_applet = current_applet; |
| 107 | save->xfunc_error_retval = xfunc_error_retval; | 108 | save->xfunc_error_retval = xfunc_error_retval; |
| 108 | save->option_mask32 = option_mask32; | 109 | save->option_mask32 = option_mask32; |
| @@ -112,6 +113,7 @@ void save_nofork_data(struct nofork_save_area *save) | |||
| 112 | 113 | ||
| 113 | void restore_nofork_data(struct nofork_save_area *save) | 114 | void restore_nofork_data(struct nofork_save_area *save) |
| 114 | { | 115 | { |
| 116 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); | ||
| 115 | current_applet = save->current_applet; | 117 | current_applet = save->current_applet; |
| 116 | xfunc_error_retval = save->xfunc_error_retval; | 118 | xfunc_error_retval = save->xfunc_error_retval; |
| 117 | option_mask32 = save->option_mask32; | 119 | option_mask32 = save->option_mask32; |
| @@ -147,7 +149,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet | |||
| 147 | rc = a->main(argc, tmp_argv); | 149 | rc = a->main(argc, tmp_argv); |
| 148 | } else { /* xfunc died in NOFORK applet */ | 150 | } else { /* xfunc died in NOFORK applet */ |
| 149 | /* in case they meant to return 0... */ | 151 | /* in case they meant to return 0... */ |
| 150 | if (rc == -111) | 152 | if (rc == -2222) |
| 151 | rc = 0; | 153 | rc = 0; |
| 152 | } | 154 | } |
| 153 | 155 | ||
| @@ -159,6 +161,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet | |||
| 159 | int run_nofork_applet(const struct bb_applet *a, char **argv) | 161 | int run_nofork_applet(const struct bb_applet *a, char **argv) |
| 160 | { | 162 | { |
| 161 | struct nofork_save_area old; | 163 | struct nofork_save_area old; |
| 164 | |||
| 162 | /* Saving globals */ | 165 | /* Saving globals */ |
| 163 | save_nofork_data(&old); | 166 | save_nofork_data(&old); |
| 164 | return run_nofork_applet_prime(&old, a, argv); | 167 | return run_nofork_applet_prime(&old, a, argv); |
diff --git a/shell/hush.c b/shell/hush.c index 579950ff9..1ff7b0df6 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -427,13 +427,15 @@ enum { run_list_level = 0 }; | |||
| 427 | /* Normal */ | 427 | /* Normal */ |
| 428 | static void syntax(const char *msg) | 428 | static void syntax(const char *msg) |
| 429 | { | 429 | { |
| 430 | bb_error_msg(msg ? "%s: %s" : "syntax error", "syntax error", msg); | 430 | (interactive_fd ? bb_error_msg : bb_error_msg_and_die) |
| 431 | (msg ? "%s: %s" : "syntax error", "syntax error", msg); | ||
| 431 | } | 432 | } |
| 432 | #else | 433 | #else |
| 433 | /* Debug */ | 434 | /* Debug */ |
| 434 | static void syntax_lineno(int line) | 435 | static void syntax_lineno(int line) |
| 435 | { | 436 | { |
| 436 | bb_error_msg("syntax error hush.c:%d", line); | 437 | (interactive_fd ? bb_error_msg : bb_error_msg_and_die) |
| 438 | ("syntax error hush.c:%d", line); | ||
| 437 | } | 439 | } |
| 438 | #define syntax(str) syntax_lineno(__LINE__) | 440 | #define syntax(str) syntax_lineno(__LINE__) |
| 439 | #endif | 441 | #endif |
| @@ -3309,13 +3311,13 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i | |||
| 3309 | /* XXX maybe someone will try to escape the '}' */ | 3311 | /* XXX maybe someone will try to escape the '}' */ |
| 3310 | while (1) { | 3312 | while (1) { |
| 3311 | ch = b_getch(input); | 3313 | ch = b_getch(input); |
| 3312 | if (ch == EOF) { | 3314 | if (ch == '}') |
| 3315 | break; | ||
| 3316 | if (!isalnum(ch) && ch != '_') { | ||
| 3313 | syntax("unterminated ${name}"); | 3317 | syntax("unterminated ${name}"); |
| 3314 | debug_printf_parse("handle_dollar return 1: unterminated ${name}\n"); | 3318 | debug_printf_parse("handle_dollar return 1: unterminated ${name}\n"); |
| 3315 | return 1; | 3319 | return 1; |
| 3316 | } | 3320 | } |
| 3317 | if (ch == '}') | ||
| 3318 | break; | ||
| 3319 | debug_printf_parse(": '%c'\n", ch); | 3321 | debug_printf_parse(": '%c'\n", ch); |
| 3320 | b_addchr(dest, ch | quote_mask); | 3322 | b_addchr(dest, ch | quote_mask); |
| 3321 | quote_mask = 0; | 3323 | quote_mask = 0; |
