aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_macro.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-02-11 13:24:12 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-02-11 13:24:12 +0000
commit1e9e28c63eaf6fb303ca37783e0d0f8e70361aa9 (patch)
tree8d811429c9adbefb2e1d2756ccc8d23e02485a59 /mdoc_macro.c
parentf360c3af5782e19039793c68f4421b5fc7c48b25 (diff)
downloadmandoc-1e9e28c63eaf6fb303ca37783e0d0f8e70361aa9.tar.gz
mandoc-1e9e28c63eaf6fb303ca37783e0d0f8e70361aa9.tar.zst
mandoc-1e9e28c63eaf6fb303ca37783e0d0f8e70361aa9.zip
Do not prematurely mark intermediate blocks as broken while scanning
backwards. Only do so when a block is found that is actually broken. Logic error found while investigating crashes reported by tb@.
Diffstat (limited to 'mdoc_macro.c')
-rw-r--r--mdoc_macro.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/mdoc_macro.c b/mdoc_macro.c
index 15038f35..3326add6 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.212 2017/02/10 22:19:18 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.213 2017/02/11 13:24:12 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
@@ -50,6 +50,8 @@ static int find_pending(struct roff_man *, int, int, int,
struct roff_node *);
static int lookup(struct roff_man *, int, int, int, const char *);
static int macro_or_word(MACRO_PROT_ARGS, int);
+static void break_intermediate(struct roff_node *,
+ struct roff_node *);
static int parse_rest(struct roff_man *, int, int, int *, char *);
static int rew_alt(int);
static void rew_elem(struct roff_man *, int);
@@ -376,6 +378,16 @@ rew_elem(struct roff_man *mdoc, int tok)
rew_last(mdoc, n);
}
+static void
+break_intermediate(struct roff_node *n, struct roff_node *breaker)
+{
+ while (n != breaker) {
+ if ( ! (n->flags & NODE_VALID))
+ n->flags |= NODE_BROKEN;
+ n = n->parent;
+ }
+}
+
/*
* If there is an open sub-block of the target requiring
* explicit close-out, postpone closing out the target until
@@ -390,14 +402,12 @@ find_pending(struct roff_man *mdoc, int tok, int line, int ppos,
irc = 0;
for (n = mdoc->last; n != NULL && n != target; n = n->parent) {
- if (n->flags & NODE_ENDED) {
- if ( ! (n->flags & NODE_VALID))
- n->flags |= NODE_BROKEN;
+ if (n->flags & NODE_ENDED)
continue;
- }
if (n->type == ROFFT_BLOCK &&
mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
irc = 1;
+ break_intermediate(mdoc->last, n);
n->flags |= NODE_BROKEN;
if (target->type == ROFFT_HEAD)
target->flags |= NODE_ENDED;
@@ -568,11 +578,8 @@ blk_exp_close(MACRO_PROT_ARGS)
endbody = itblk = later = NULL;
for (n = mdoc->last; n; n = n->parent) {
- if (n->flags & NODE_ENDED) {
- if ( ! (n->flags & NODE_VALID))
- n->flags |= NODE_BROKEN;
+ if (n->flags & NODE_ENDED)
continue;
- }
/*
* Mismatching end macros can never break anything
@@ -599,7 +606,6 @@ blk_exp_close(MACRO_PROT_ARGS)
}
if (atok == n->tok) {
- assert(body);
/*
* Found the start of our own block.
@@ -650,6 +656,7 @@ blk_exp_close(MACRO_PROT_ARGS)
/* Breaking an open sub block. */
+ break_intermediate(mdoc->last, body);
n->flags |= NODE_BROKEN;
if (later == NULL)
later = n;