summaryrefslogtreecommitdiffstats
path: root/usr.bin/mandoc/mdoc_macro.c
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2017-02-16 09:47:10 +0000
committerschwarze <schwarze@openbsd.org>2017-02-16 09:47:10 +0000
commit61e75b073b07e914c6c7011069ed7e77d7bfdcdc (patch)
tree25296c3a660b21ff88a79e3b1e3402b880a461de /usr.bin/mandoc/mdoc_macro.c
parentMatch the recent change in the kernel and ask for a generic armv8-a (diff)
downloadwireguard-openbsd-61e75b073b07e914c6c7011069ed7e77d7bfdcdc.tar.xz
wireguard-openbsd-61e75b073b07e914c6c7011069ed7e77d7bfdcdc.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.
Diffstat (limited to 'usr.bin/mandoc/mdoc_macro.c')
-rw-r--r--usr.bin/mandoc/mdoc_macro.c9
1 files changed, 6 insertions, 3 deletions
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)) {