diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2015-02-12 12:24:33 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2015-02-12 12:24:33 +0000 |
commit | 33da493a191d7c9f4dd1e96d178eeb11d1218abc (patch) | |
tree | 686aa38a2482948a55f21b52b23fc267ac7c729f /mdoc_validate.c | |
parent | a5ec4b155fd2b5756e3494144f8347f3ad03d4c1 (diff) | |
download | mandoc-33da493a191d7c9f4dd1e96d178eeb11d1218abc.tar.gz |
Delete the mdoc_node.pending pointer and the function calculating
it, make_pending(), which was the most difficult function of the
whole mdoc(7) parser. After almost five years of maintaining this
hellhole, i just noticed the pointer isn't needed after all.
Blocks are always rewound in the reverse order they were opened;
that even holds for broken blocks. Consequently, it is sufficient
to just mark broken blogs with the flag MDOC_BROKEN and breaking
blocks with the flag MDOC_ENDED. When rewinding, instead of iterating
the pending pointers, just iterate from each broken block to its
parents, rewinding all that are MDOC_ENDED and stopping after
processing the first ancestor that it not MDOC_BROKEN. For ENDBODY
markers, use the mdoc_node.body pointer in place of the former
mdoc_node.pending.
This also fixes an assertion failure found by jsg@ with afl,
test case #467 (Bo Bl It Bd Bc It), where (surprise surprise)
the pending pointer got corrupted.
Improved functionality, minus one function, minus one struct field,
minus 50 lines of code.
Diffstat (limited to 'mdoc_validate.c')
-rw-r--r-- | mdoc_validate.c | 44 |
1 files changed, 5 insertions, 39 deletions
diff --git a/mdoc_validate.c b/mdoc_validate.c index 94e36d9f..21948506 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -325,7 +325,7 @@ mdoc_valid_post(struct mdoc *mdoc) n = mdoc->last; if (n->flags & MDOC_VALID) return; - n->flags |= MDOC_VALID; + n->flags |= MDOC_VALID | MDOC_ENDED; switch (n->type) { case MDOC_TEXT: @@ -416,24 +416,13 @@ pre_display(PRE_ARGS) static void pre_bl(PRE_ARGS) { - struct mdoc_node *np; struct mdoc_argv *argv, *wa; int i; enum mdocargt mdoclt; enum mdoc_list lt; - if (MDOC_BLOCK != n->type) { - if (ENDBODY_NOT != n->end) { - assert(n->pending); - np = n->pending->parent; - } else - np = n->parent; - - assert(np); - assert(MDOC_BLOCK == np->type); - assert(MDOC_Bl == np->tok); + if (n->type != MDOC_BLOCK) return; - } /* * First figure out which kind of list to use: bind ourselves to @@ -609,25 +598,14 @@ pre_bl(PRE_ARGS) static void pre_bd(PRE_ARGS) { - struct mdoc_node *np; struct mdoc_argv *argv; int i; enum mdoc_disp dt; pre_literal(mdoc, n); - if (MDOC_BLOCK != n->type) { - if (ENDBODY_NOT != n->end) { - assert(n->pending); - np = n->pending->parent; - } else - np = n->parent; - - assert(np); - assert(MDOC_BLOCK == np->type); - assert(MDOC_Bd == np->tok); + if (n->type != MDOC_BLOCK) return; - } for (i = 0; n->args && i < (int)n->args->argc; i++) { argv = n->args->argv + i; @@ -797,22 +775,10 @@ post_bf(POST_ARGS) * element, which contains the goods. */ - if (MDOC_HEAD != mdoc->last->type) { - if (ENDBODY_NOT != mdoc->last->end) { - assert(mdoc->last->pending); - np = mdoc->last->pending->parent->head; - } else if (MDOC_BLOCK != mdoc->last->type) { - np = mdoc->last->parent->head; - } else - np = mdoc->last->head; - - assert(np); - assert(MDOC_HEAD == np->type); - assert(MDOC_Bf == np->tok); + np = mdoc->last; + if (MDOC_HEAD != np->type) return; - } - np = mdoc->last; assert(MDOC_BLOCK == np->parent->type); assert(MDOC_Bf == np->parent->tok); |