When we open a new .while loop, let's not attempt to close out
authorschwarze <schwarze@openbsd.org>
Sun, 24 Apr 2022 17:39:31 +0000 (17:39 +0000)
committerschwarze <schwarze@openbsd.org>
Sun, 24 Apr 2022 17:39:31 +0000 (17:39 +0000)
another enclosing .while loop at the same time.
Instead, postpone the closing until the next iteration of ROFF_RERUN.

This prevents one-line constructions like ".while 0 .while 0 something"
and ".while rx .while rx .rr x" (which admittedly aren't particularly
useful) from dying of abort(3), which was a bug tb@ found with afl(1).

usr.bin/mandoc/roff.c

index 6c26872..7ea4f6e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.254 2022/04/24 13:34:53 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.255 2022/04/24 17:39:31 schwarze Exp $ */
 /*
  * Copyright (c) 2010-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -2431,9 +2431,11 @@ roff_cond_sub(ROFF_ARGS)
                        }
                }
        } else if (t != TOKEN_NONE &&
-           (rr || roffs[t].flags & ROFFMAC_STRUCT))
+           (rr || roffs[t].flags & ROFFMAC_STRUCT)) {
                irc |= (*roffs[t].proc)(r, t, buf, ln, ppos, pos, offs);
-       else
+               if (irc & ROFF_WHILE)
+                       irc &= ~(ROFF_LOOPCONT | ROFF_LOOPEXIT);
+       } else
                irc |= rr ? ROFF_CONT : ROFF_IGN;
        return irc;
 }