diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2017-02-16 09:47:11 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2017-02-16 09:47:11 +0000 |
commit | a6ff5f627763ade02a6f6f153833f35a7795373e (patch) | |
tree | 38c3815c971cc77af3df6e1ebb106a6530e2f9e2 | |
parent | 7d1062cbb23e36f11a90277ea90c18b37aa61300 (diff) |
Fix block scoping error if an explicit block is broken by two
implicit blocks (.Aq Bq Po .Pc) that left the outer breaker open
and could in exceptional cases, like between .Bl and .It, cause
tree corruption leading to NULL dereference.
Found by tb@ with afl(1).
While here, do not mark intermediate ENDBODY markers as broken.
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/break/twice.in | 19 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/break/twice.out_ascii | 14 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/mdoc/break/twice.out_lint | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_macro.c | 9 |
4 files changed, 32 insertions, 13 deletions
diff --git a/regress/usr.bin/mandoc/mdoc/break/twice.in b/regress/usr.bin/mandoc/mdoc/break/twice.in index 8853aec1a04..a8dda93f2f7 100644 --- a/regress/usr.bin/mandoc/mdoc/break/twice.in +++ b/regress/usr.bin/mandoc/mdoc/break/twice.in @@ -1,11 +1,11 @@ -.Dd February 12, 2015 +.Dd February 16, 2017 .Dt BREAK-TWICE 1 .Os OpenBSD .Sh NAME .Nm break-twice .Nd breaking the same block twice .Sh DESCRIPTION -Standard case, explicit: +Standard case, fully explicit: .Bo bo .Bro bro .Ao ao brc @@ -13,12 +13,12 @@ Standard case, explicit: .Bc ac .Ac .Pp -Standard case, implicit: +Standard case, implicit broken block: .Bo bo .Bro bro .Aq aq brc Brc bc Bc eol .Pp -Two of the same kind, explicit: +Two of the same kind, fully explicit: .Bo bo .Bo bo .Ao ao bc @@ -26,7 +26,16 @@ Two of the same kind, explicit: .Bc ac .Ac .Pp -Two of the same kind, implicit: +Two of the same kind, implicit broken block: .Bo bo .Bo bo .Aq aq bc Bc bc Bc eol +.Pp +Two implicit breakers: +.Bl -dash +.Aq aq Bq bq Po po +pc +.Pc +.It +it +.El diff --git a/regress/usr.bin/mandoc/mdoc/break/twice.out_ascii b/regress/usr.bin/mandoc/mdoc/break/twice.out_ascii index c6d0149db7d..75302910d75 100644 --- a/regress/usr.bin/mandoc/mdoc/break/twice.out_ascii +++ b/regress/usr.bin/mandoc/mdoc/break/twice.out_ascii @@ -4,12 +4,16 @@ NNAAMMEE bbrreeaakk--ttwwiiccee - breaking the same block twice DDEESSCCRRIIPPTTIIOONN - Standard case, explicit: [bo {bro <ao brc} bc] ac> + Standard case, fully explicit: [bo {bro <ao brc} bc] ac> - Standard case, implicit: [bo {bro <aq brc} bc] eol> + Standard case, implicit broken block: [bo {bro <aq brc} bc] eol> - Two of the same kind, explicit: [bo [bo <ao bc] bc] ac> + Two of the same kind, fully explicit: [bo [bo <ao bc] bc] ac> - Two of the same kind, implicit: [bo [bo <aq bc] bc] eol> + Two of the same kind, implicit broken block: [bo [bo <aq bc] bc] eol> -OpenBSD February 12, 2015 OpenBSD + Two implicit breakers: <aq [bq (po]> pc) + + -- it + +OpenBSD February 16, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/mdoc/break/twice.out_lint b/regress/usr.bin/mandoc/mdoc/break/twice.out_lint index 6ac976c0309..150800e9326 100644 --- a/regress/usr.bin/mandoc/mdoc/break/twice.out_lint +++ b/regress/usr.bin/mandoc/mdoc/break/twice.out_lint @@ -6,3 +6,6 @@ mandoc: twice.in:25:2: WARNING: blocks badly nested: Bo breaks Ao mandoc: twice.in:26:2: WARNING: blocks badly nested: Bo breaks Ao mandoc: twice.in:32:11: WARNING: blocks badly nested: Bo breaks Aq mandoc: twice.in:32:17: WARNING: blocks badly nested: Bo breaks Aq +mandoc: twice.in:36:8: WARNING: blocks badly nested: Bq breaks Po +mandoc: twice.in:36:2: WARNING: blocks badly nested: Aq breaks Po +mandoc: twice.in:36:2: WARNING: moving content out of list: Aq diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c index 47f859400fe..af3f159e4f4 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.173 2017/02/16 02:59:42 schwarze Exp $ */ +/* $OpenBSD: mdoc_macro.c,v 1.174 2017/02/16 09:47:10 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -379,6 +379,10 @@ rew_elem(struct roff_man *mdoc, int tok) static void break_intermediate(struct roff_node *n, struct roff_node *breaker) { + if (n != breaker && + n->type != ROFFT_BLOCK && n->type != ROFFT_HEAD && + (n->type != ROFFT_BODY || n->end != ENDBODY_NOT)) + n = n->parent; while (n != breaker) { if ( ! (n->flags & NODE_VALID)) n->flags |= NODE_BROKEN; @@ -408,8 +412,7 @@ find_pending(struct roff_man *mdoc, int tok, int line, int ppos, if (n->type == ROFFT_BLOCK && mdoc_macros[n->tok].flags & MDOC_EXPLICIT) { irc = 1; - break_intermediate(mdoc->last, n); - n->flags |= NODE_BROKEN; + break_intermediate(mdoc->last, target); if (target->type == ROFFT_HEAD) target->flags |= NODE_ENDED; else if ( ! (target->flags & NODE_ENDED)) { |