aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_macro.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-02-10 22:19:18 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-02-10 22:19:18 +0000
commitf360c3af5782e19039793c68f4421b5fc7c48b25 (patch)
treee47c20529cd38a40ec0022756fe96d9fa4cbd4d5 /mdoc_macro.c
parent129204d2b6e8eb95a79408a2653069d26ec852d7 (diff)
downloadmandoc-f360c3af5782e19039793c68f4421b5fc7c48b25.tar.gz
mandoc-f360c3af5782e19039793c68f4421b5fc7c48b25.tar.zst
mandoc-f360c3af5782e19039793c68f4421b5fc7c48b25.zip
For child macros of block-end macros, only scan backwards for pending
breakers unless the parent of the block is already closed. While the scanning is needed in cases like ".Ac Bo" for broken Ao, it is useless and crashy in cases like ".Ac Bc" for non-broken Ao. This fixes a NULL pointer dereference that tb@ found with afl(1).
Diffstat (limited to 'mdoc_macro.c')
-rw-r--r--mdoc_macro.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/mdoc_macro.c b/mdoc_macro.c
index aa3f4cde..15038f35 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.211 2017/02/10 16:20:34 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.212 2017/02/10 22:19:18 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
@@ -398,9 +398,9 @@ 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;
- n->flags = NODE_BROKEN;
+ n->flags |= NODE_BROKEN;
if (target->type == ROFFT_HEAD)
- target->flags = NODE_ENDED;
+ target->flags |= NODE_ENDED;
else if ( ! (target->flags & NODE_ENDED)) {
mandoc_vmsg(MANDOCERR_BLK_NEST,
mdoc->parse, line, ppos,
@@ -714,15 +714,16 @@ blk_exp_close(MACRO_PROT_ARGS)
}
if (n != NULL) {
+ pending = 0;
if (ntok != TOKEN_NONE && n->flags & NODE_BROKEN) {
target = n;
do
target = target->parent;
while ( ! (target->flags & NODE_ENDED));
- pending = find_pending(mdoc, ntok, line, ppos,
- target);
- } else
- pending = 0;
+ if ( ! (target->flags & NODE_VALID))
+ pending = find_pending(mdoc, ntok,
+ line, ppos, target);
+ }
if ( ! pending)
rew_pending(mdoc, n);
}