From 884a60b25e9e47062115672eba1e8ab234747909 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Thu, 16 Feb 2017 09:47:31 +0000 Subject: 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. --- mdoc_macro.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'mdoc_macro.c') diff --git a/mdoc_macro.c b/mdoc_macro.c index a4730ff1..f6634b62 100644 --- a/mdoc_macro.c +++ b/mdoc_macro.c @@ -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)) { -- cgit