hush: fix handling of unmatched ${name (without closing '}') -
authorDenis Vlasenko <vda.linux@googlemail.com>
Thu, 24 May 2007 12:18:16 +0000 (12:18 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Thu, 24 May 2007 12:18:16 +0000 (12:18 -0000)
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)

include/libbb.h
libbb/error_msg_and_die.c
libbb/vfork_daemon_rexec.c
shell/hush.c

index 32bb3113d910d8f9e2215eb7134d7150d3d5615c..1859a3f09d5b02b7dbf481668a2482cd9ccbffe3 100644 (file)
@@ -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;
index 20d97159172efc74a44d3b1d65d64224dc941c1f..0e99a03cfa96ce204a751f35fdf4cdd096f71669 100644 (file)
@@ -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);
        }
index a2572b0a9d3a6ccbd24381360a1231bb1cbb5398..349628796f9da7830f916ddd5f3b35f5d4c1fa7b 100644 (file)
@@ -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);
index 579950ff92d25d87eef9f5590da07898f68c6394..1ff7b0df66d2d6fc0b18a15f1a4c7804a06cf98a 100644 (file)
@@ -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;