Currently, our ksh/sh accepts things like:

    while do done

which cannot be interrupted via ^C by default.

If, However, the expression is not empty everything is fine.  E.g.

    while :; do done

Most other shells require a non-empty expression which avoids this
problem (zsh is the outlier here).  AT&T ksh and other shells also
require a non-empty loop body so I've added a check for that too.
So now the expression has to be at least:

    while :; do :; done

There are other places we could tighten up the syntax checking but
I'll leave that for someone else ;-)

The new behavior is:

$ while do done
ksh: syntax error: `do' unexpected

$ while :; do done
ksh: syntax error: `done' unexpected

Which is similar to the error produced by bash and AT&T ksh.
The ksh regress still passes.

 - todd

Index: bin/ksh/syn.c
===================================================================
RCS file: /cvs/src/bin/ksh/syn.c,v
retrieving revision 1.39
diff -u -p -u -r1.39 syn.c
--- bin/ksh/syn.c       24 Apr 2018 08:25:16 -0000      1.39
+++ bin/ksh/syn.c       2 Jul 2021 18:14:21 -0000
@@ -331,7 +331,11 @@ get_command(int cf)
                nesting_push(&old_nesting, c);
                t = newtp((c == WHILE) ? TWHILE : TUNTIL);
                t->left = c_list(true);
+               if (t->left == NULL)
+                       syntaxerr(NULL);
                t->right = dogroup();
+               if (t->right == NULL)
+                       syntaxerr(NULL);
                nesting_pop(&old_nesting);
                break;
 

Reply via email to