msh: fix "while...continue" bug 3884.
authorDenis Vlasenko <vda.linux@googlemail.com>
Sun, 20 Jul 2008 23:03:23 +0000 (23:03 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sun, 20 Jul 2008 23:03:23 +0000 (23:03 -0000)
shell/msh.c
shell/msh_test/msh-execution/many_continues.right [new file with mode: 0644]
shell/msh_test/msh-execution/many_continues.tests [new file with mode: 0755]

index 44213c657457f00e20a7d2f4e6ac4af32c4553f1..eb17eb6689e58de985fcecc988d65a1cc387182d 100644 (file)
@@ -2573,6 +2573,10 @@ static int execute(struct op *t, int *pin, int *pout, int no_fork)
                while (setjmp(bc.brkpt))
                        if (isbreak)
                                goto broken;
+               /* Restore areanum value. It may be incremented by execute()
+                * below, and then "continue" may jump back to setjmp above */
+               areanum = a + 1;
+               freearea(areanum + 1);
                brkset(&bc);
                for (t1 = t->left; i-- && *wp != NULL;) {
                        setval(vp, *wp++);
@@ -2586,6 +2590,10 @@ static int execute(struct op *t, int *pin, int *pout, int no_fork)
                while (setjmp(bc.brkpt))
                        if (isbreak)
                                goto broken;
+               /* Restore areanum value. It may be incremented by execute()
+                * below, and then "continue" may jump back to setjmp above */
+               areanum = a + 1;
+               freearea(areanum + 1);
                brkset(&bc);
                t1 = t->left;
                while ((execute(t1, pin, pout, /* no_fork: */ 0) == 0) == (t->op_type == TWHILE))
diff --git a/shell/msh_test/msh-execution/many_continues.right b/shell/msh_test/msh-execution/many_continues.right
new file mode 100644 (file)
index 0000000..d86bac9
--- /dev/null
@@ -0,0 +1 @@
+OK
diff --git a/shell/msh_test/msh-execution/many_continues.tests b/shell/msh_test/msh-execution/many_continues.tests
new file mode 100755 (executable)
index 0000000..86c729a
--- /dev/null
@@ -0,0 +1,15 @@
+if test $# = 0; then
+    # Child will kill us in 1 second
+    "$THIS_SH" "$0" $$ &
+
+    # Loop many, many times
+    trap 'echo OK; exit 0' 15
+    while true; do
+       continue
+    done
+    echo BAD
+    exit 1
+fi
+
+sleep 1
+kill $1