From: schwarze Date: Sat, 20 Dec 2014 02:26:42 +0000 (+0000) Subject: Fix two issues causing a class of assertion failures found by jsg@ with afl. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=42c9ede6f67e9ee0627823d05205159b281d7546;p=openbsd Fix two issues causing a class of assertion failures found by jsg@ with afl. 1) rew_sub(): Make sure REWIND_MORE is acted upon even when followed by REWIND_NONE. This prevents .It from ending up inside other children of .Bl. 2) blk_exp_close(): Only allow extension of .Bl when it has at least one .It. Otherwise, a broken child block could be moved in front of the .Bl, effectively resulting in a .Bl that ended before it began. --- diff --git a/regress/usr.bin/mandoc/mdoc/Bl/Makefile b/regress/usr.bin/mandoc/mdoc/Bl/Makefile index 4e37f578368..299bf820148 100644 --- a/regress/usr.bin/mandoc/mdoc/Bl/Makefile +++ b/regress/usr.bin/mandoc/mdoc/Bl/Makefile @@ -1,24 +1,25 @@ -# $OpenBSD: Makefile,v 1.26 2014/11/10 21:54:29 schwarze Exp $ +# $OpenBSD: Makefile,v 1.27 2014/12/20 02:26:42 schwarze Exp $ REGRESS_TARGETS = item inset diag ohang bullet dash enum hang tag REGRESS_TARGETS += column extend nested offset secstart REGRESS_TARGETS += notype multitype badargs REGRESS_TARGETS += empty noIt emptyhead emptytag emptyitem multitag -REGRESS_TARGETS += bareIt bareTa unclosed break broken +REGRESS_TARGETS += bareIt bareTa unclosed break breakingIt broken LINT_TARGETS = column notype badargs LINT_TARGETS += noIt emptyhead emptytag emptyitem -LINT_TARGETS += bareIt bareTa break broken +LINT_TARGETS += bareIt bareTa break breakingIt broken -# groff-1.22.2 defects: +# groff-1.22.3 defects: # - lists with missing or late type ruin indentation # - empty lists ruin indentation and sometimes cause empty lines # - breaking lists continue indefinitely +# - breaking items sometimes ruin indentation, sometimes abort processing # - breaking a list aborts processing # - empty -tag item heads lose the blank line and the indentation -SKIP_GROFF ?= notype empty break broken emptytag +SKIP_GROFF ?= notype empty break breakingIt broken emptytag SKIP_TMAN ?= column multitype multitag bareTa break broken diff --git a/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.in b/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.in new file mode 100644 index 00000000000..bcae378920f --- /dev/null +++ b/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.in @@ -0,0 +1,37 @@ +.Dd December 19, 2014 +.Dt BL-BREAKINGIT 1 +.Os OpenBSD +.Sh NAME +.Nm Bl-breakingIt +.Nd items breaking other blocks +.Sh DESCRIPTION +.Ss Breaking partial explicit macros +.Bl -tag -width Ds +Stray text. +.Ao +More stray text. +.It tag +Tagged text. +.El +.Bl -bullet +Stray text. +.Ao +More stray text. +.It +Bullet point. +.El +.Ss Breaking full explicit macros +.Bl -tag -width Ds +Stray text. +.Bd -ragged -offset indent +More stray text. +.It tag +Tagged text. +.El +.Bl -bullet +Stray text. +.Bd -ragged -offset indent +More stray text. +.It +Bullet point. +.El diff --git a/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.out_ascii b/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.out_ascii new file mode 100644 index 00000000000..0013bba8b6b --- /dev/null +++ b/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.out_ascii @@ -0,0 +1,27 @@ +BL-BREAKINGIT(1) General Commands Manual BL-BREAKINGIT(1) + +NNAAMMEE + BBll--bbrreeaakkiinnggIItt - items breaking other blocks + +DDEESSCCRRIIPPTTIIOONN + BBrreeaakkiinngg ppaarrttiiaall eexxpplliicciitt mmaaccrrooss + Stray text. + + tag Tagged text. + Stray text. + + ++oo Bullet point. + + BBrreeaakkiinngg ffuullll eexxpplliicciitt mmaaccrrooss + Stray text. + + More stray text. + + tag Tagged text. + Stray text. + + More stray text. + + ++oo Bullet point. + +OpenBSD December 19, 2014 OpenBSD diff --git a/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.out_lint b/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.out_lint new file mode 100644 index 00000000000..50b9dcbf7c8 --- /dev/null +++ b/regress/usr.bin/mandoc/mdoc/Bl/breakingIt.out_lint @@ -0,0 +1,12 @@ +mandoc: breakingIt.in:13:2: ERROR: inserting missing end of block: It breaks Ao +mandoc: breakingIt.in:10:1: WARNING: moving content out of list: text +mandoc: breakingIt.in:11:2: WARNING: moving content out of list: Ao +mandoc: breakingIt.in:20:2: ERROR: inserting missing end of block: It breaks Ao +mandoc: breakingIt.in:17:1: WARNING: moving content out of list: text +mandoc: breakingIt.in:18:2: WARNING: moving content out of list: Ao +mandoc: breakingIt.in:28:2: ERROR: inserting missing end of block: It breaks Bd +mandoc: breakingIt.in:25:1: WARNING: moving content out of list: text +mandoc: breakingIt.in:26:2: WARNING: moving content out of list: Bd +mandoc: breakingIt.in:35:2: ERROR: inserting missing end of block: It breaks Bd +mandoc: breakingIt.in:32:1: WARNING: moving content out of list: text +mandoc: breakingIt.in:33:2: WARNING: moving content out of list: Bd diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c index eb4fa301f18..14c686fdeb4 100644 --- a/usr.bin/mandoc/mdoc_macro.c +++ b/usr.bin/mandoc/mdoc_macro.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_macro.c,v 1.115 2014/12/18 20:58:00 schwarze Exp $ */ +/* $OpenBSD: mdoc_macro.c,v 1.116 2014/12/20 02:26:42 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze @@ -548,13 +548,17 @@ static void rew_sub(enum mdoc_type t, struct mdoc *mdoc, enum mdoct tok, int line, int ppos) { - struct mdoc_node *n; + struct mdoc_node *n, *to; + to = NULL; n = mdoc->last; while (n) { switch (rew_dohalt(tok, t, n)) { case REWIND_NONE: - return; + if (to == NULL) + return; + n = to; + break; case REWIND_THIS: n->lastline = line - (mdoc->flags & MDOC_NEWLINE && @@ -569,6 +573,7 @@ rew_sub(enum mdoc_type t, struct mdoc *mdoc, case REWIND_MORE: n->lastline = line - (mdoc->flags & MDOC_NEWLINE ? 1 : 0); + to = n; n = n->parent; continue; case REWIND_LATER: @@ -711,7 +716,7 @@ blk_exp_close(MACRO_PROT_ARGS) struct mdoc_node *later; /* A sub-block starting later. */ struct mdoc_node *n; /* For searching backwards. */ - int j, lastarg, maxargs, flushed, nl; + int flushed, have_it, j, lastarg, maxargs, nl; enum margserr ac; enum mdoct atok, ntok; char *p; @@ -735,6 +740,7 @@ blk_exp_close(MACRO_PROT_ARGS) * both of our own and of pending sub-blocks. */ + have_it = 0; atok = rew_alt(tok); body = endbody = later = NULL; for (n = mdoc->last; n; n = n->parent) { @@ -751,6 +757,12 @@ blk_exp_close(MACRO_PROT_ARGS) if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm) continue; + + if (n->tok == MDOC_It) { + have_it = 1; + continue; + } + if (atok == n->tok) { assert(body); @@ -760,7 +772,8 @@ blk_exp_close(MACRO_PROT_ARGS) * just proceed to closing out. */ - if (later == NULL) + if (later == NULL || + (tok == MDOC_El && !have_it)) break; /* @@ -799,10 +812,8 @@ blk_exp_close(MACRO_PROT_ARGS) * implicit ones, the first open implicit block. */ - if (later && - mdoc_macros[later->tok].flags & MDOC_EXPLICIT) - continue; - if (n->tok != MDOC_It) + if (later == NULL || + ! (mdoc_macros[later->tok].flags & MDOC_EXPLICIT)) later = n; } rew_sub(MDOC_BODY, mdoc, tok, line, ppos);