hush: fix handling of ^C in eval
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 11 Jan 2018 12:17:30 +0000 (13:17 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 11 Jan 2018 12:17:30 +0000 (13:17 +0100)
function                                             old     new   delta
run_list                                            1044    1259    +215
builtin_eval                                          45     126     +81
expand_strvec_to_string                               91       -     -91
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/0 up/down: 296/-91)           Total: 205 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash_test/ash-misc/control_char2.right [new file with mode: 0644]
shell/ash_test/ash-misc/control_char2.tests [new file with mode: 0755]
shell/hush.c
shell/hush_test/hush-misc/control_char2.right [new file with mode: 0644]
shell/hush_test/hush-misc/control_char2.tests [new file with mode: 0755]

diff --git a/shell/ash_test/ash-misc/control_char2.right b/shell/ash_test/ash-misc/control_char2.right
new file mode 100644 (file)
index 0000000..9498b42
--- /dev/null
@@ -0,0 +1,2 @@
+\ 3
+Done:0
diff --git a/shell/ash_test/ash-misc/control_char2.tests b/shell/ash_test/ash-misc/control_char2.tests
new file mode 100755 (executable)
index 0000000..e77d7a1
--- /dev/null
@@ -0,0 +1,3 @@
+c=`printf '\3'`
+eval "echo $c"
+echo Done:$?
index 48f503cb6a5a950dad11a90de02266fb2bccc92f..c2b987f49e51f6f705f67f2709ebf209e0eef03c 100644 (file)
@@ -6199,7 +6199,7 @@ static char *expand_string_to_string(const char *str, int do_unbackslash)
        return (char*)list;
 }
 
-/* Used for "eval" builtin and case string */
+#if ENABLE_HUSH_CASE
 static char* expand_strvec_to_string(char **argv)
 {
        char **list;
@@ -6221,6 +6221,7 @@ static char* expand_strvec_to_string(char **argv)
        debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
        return (char*)list;
 }
+#endif
 
 static char **expand_assignments(char **argv, int count)
 {
@@ -9349,13 +9350,34 @@ static int FAST_FUNC builtin_eval(char **argv)
        int rcode = EXIT_SUCCESS;
 
        argv = skip_dash_dash(argv);
-       if (*argv) {
-               char *str = expand_strvec_to_string(argv);
+       if (argv[0]) {
+               char *str = NULL;
+
+               if (argv[1]) {
+                       /* "The eval utility shall construct a command by
+                        * concatenating arguments together, separating
+                        * each with a <space> character."
+                        */
+                       char *p;
+                       unsigned len = 0;
+                       char **pp = argv;
+                       do
+                               len += strlen(*pp) + 1;
+                       while (*++pp);
+                       str = p = xmalloc(len);
+                       pp = argv;
+                       do {
+                               p = stpcpy(p, *pp);
+                               *p++ = ' ';
+                       } while (*++pp);
+                       p[-1] = '\0';
+               }
+
                /* bash:
                 * eval "echo Hi; done" ("done" is syntax error):
                 * "echo Hi" will not execute too.
                 */
-               parse_and_run_string(str);
+               parse_and_run_string(str ? str : argv[0]);
                free(str);
                rcode = G.last_exitcode;
        }
diff --git a/shell/hush_test/hush-misc/control_char2.right b/shell/hush_test/hush-misc/control_char2.right
new file mode 100644 (file)
index 0000000..9498b42
--- /dev/null
@@ -0,0 +1,2 @@
+\ 3
+Done:0
diff --git a/shell/hush_test/hush-misc/control_char2.tests b/shell/hush_test/hush-misc/control_char2.tests
new file mode 100755 (executable)
index 0000000..e77d7a1
--- /dev/null
@@ -0,0 +1,3 @@
+c=`printf '\3'`
+eval "echo $c"
+echo Done:$?