aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-02-16 09:47:31 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-02-16 09:47:31 +0000
commitaabe46b7c8c0f9da0079b71a1eb350536961bc3f (patch)
tree39fb19e2d44158549869c4fe305c6058e4ec8abc
parent873dc9b1d77212924c035df9c1accfbb3a4a6a7e (diff)
downloadmandoc-aabe46b7c8c0f9da0079b71a1eb350536961bc3f.tar.gz
mandoc-aabe46b7c8c0f9da0079b71a1eb350536961bc3f.tar.zst
mandoc-aabe46b7c8c0f9da0079b71a1eb350536961bc3f.zip
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--mdoc_macro.c9
-rw-r--r--regress/mdoc/break/twice.in19
-rw-r--r--regress/mdoc/break/twice.out_ascii14
-rw-r--r--regress/mdoc/break/twice.out_lint3
4 files changed, 32 insertions, 13 deletions
diff --git a/mdoc_macro.c b/mdoc_macro.c
index a7ec6739..5ab9c412 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.216 2017/02/16 03:00:23 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.217 2017/02/16 09:47:31 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -381,6 +381,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;
@@ -410,8 +414,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)) {
diff --git a/regress/mdoc/break/twice.in b/regress/mdoc/break/twice.in
index 8853aec1..a8dda93f 100644
--- a/regress/mdoc/break/twice.in
+++ b/regress/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/mdoc/break/twice.out_ascii b/regress/mdoc/break/twice.out_ascii
index c6d0149d..75302910 100644
--- a/regress/mdoc/break/twice.out_ascii
+++ b/regress/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/mdoc/break/twice.out_lint b/regress/mdoc/break/twice.out_lint
index 6ac976c0..150800e9 100644
--- a/regress/mdoc/break/twice.out_lint
+++ b/regress/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