ash: catch error in arithmetic expansion in PS1
authorRon Yorston <rmy@pobox.com>
Thu, 18 Apr 2019 08:49:13 +0000 (09:49 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 19 Apr 2019 11:21:34 +0000 (13:21 +0200)
Setting PS1 to:

   PS1='$((123+))'

causes the shell to enter an infinite error loop:

   sh: arithmetic syntax error

Catch any exception raised by expandarg() in expandstr() and allow
processing to continue.

function                                             old     new   delta
expandstr                                            262     344     +82
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 82/0)               Total: 82 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index f3a2c6952aad4f894a555206efe863ba3e737c0e..924e17f32d3e9f7d42cea80288e02f766d1853f1 100644 (file)
@@ -13043,6 +13043,9 @@ expandstr(const char *ps, int syntax_type)
        union node n;
        int saveprompt;
        struct parsefile *file_stop = g_parsefile;
+       volatile int saveint;
+       struct jmploc *volatile savehandler = exception_handler;
+       struct jmploc jmploc;
 
        /* XXX Fix (char *) cast. */
        setinputstring((char *)ps);
@@ -13054,18 +13057,13 @@ expandstr(const char *ps, int syntax_type)
         * Try a prompt with syntactically wrong command:
         * PS1='$(date "+%H:%M:%S) > '
         */
-       {
-               volatile int saveint;
-               struct jmploc *volatile savehandler = exception_handler;
-               struct jmploc jmploc;
-               SAVE_INT(saveint);
-               if (setjmp(jmploc.loc) == 0) {
-                       exception_handler = &jmploc;
-                       readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
-               }
-               exception_handler = savehandler;
-               RESTORE_INT(saveint);
+       SAVE_INT(saveint);
+       if (setjmp(jmploc.loc) == 0) {
+               exception_handler = &jmploc;
+               readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0);
        }
+       exception_handler = savehandler;
+       RESTORE_INT(saveint);
 
        doprompt = saveprompt;
 
@@ -13077,7 +13075,17 @@ expandstr(const char *ps, int syntax_type)
        n.narg.text = wordtext;
        n.narg.backquote = backquotelist;
 
-       expandarg(&n, NULL, EXP_QUOTED);
+       /* expandarg() might fail too:
+        * PS1='$((123+))'
+        */
+       SAVE_INT(saveint);
+       if (setjmp(jmploc.loc) == 0) {
+               exception_handler = &jmploc;
+               expandarg(&n, NULL, EXP_QUOTED);
+       }
+       exception_handler = savehandler;
+       RESTORE_INT(saveint);
+
        return stackblock();
 }