summaryrefslogtreecommitdiffstats
path: root/mdoc_macro.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-11-27 22:27:56 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-11-27 22:27:56 +0000
commite60121aa36205c920bf51da52a8b1ca357beb594 (patch)
tree8d4860c2d4c0b1a2e0e6910484195594fd0cfb87 /mdoc_macro.c
parent45fbe869155402e8d8a4dbfce5516c55d9563890 (diff)
downloadmandoc-e60121aa36205c920bf51da52a8b1ca357beb594.tar.gz
Multiple fixes with respect to .Eo:
1. Correctly parse stray .Ec without preceding .Eo, avoiding an assertion violation found by jsg@ with afl. 2. Correctly parse .Ec arguments when breaking another block. 3. Correct spacing around closing delimiter when breaking another block. 4. Sync some related formatting control from -Tascii to -Thtml.
Diffstat (limited to 'mdoc_macro.c')
-rw-r--r--mdoc_macro.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/mdoc_macro.c b/mdoc_macro.c
index 08dc3b27..d4c69084 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -693,6 +693,7 @@ static int
blk_exp_close(MACRO_PROT_ARGS)
{
struct mdoc_node *body; /* Our own body. */
+ struct mdoc_node *endbody; /* Our own end marker. */
struct mdoc_node *later; /* A sub-block starting later. */
struct mdoc_node *n; /* For searching backwards. */
@@ -719,7 +720,7 @@ blk_exp_close(MACRO_PROT_ARGS)
* both of our own and of pending sub-blocks.
*/
atok = rew_alt(tok);
- body = later = NULL;
+ body = endbody = later = NULL;
for (n = mdoc->last; n; n = n->parent) {
if (MDOC_VALID & n->flags)
continue;
@@ -758,6 +759,10 @@ blk_exp_close(MACRO_PROT_ARGS)
if ( ! mdoc_endbody_alloc(mdoc, line, ppos,
atok, body, ENDBODY_SPACE))
return(0);
+ if (maxargs) {
+ endbody = mdoc->last;
+ mdoc->next = MDOC_NEXT_CHILD;
+ }
break;
}
@@ -787,15 +792,28 @@ blk_exp_close(MACRO_PROT_ARGS)
if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos))
return(0);
- if (NULL == later && maxargs > 0)
- if ( ! mdoc_tail_alloc(mdoc, line, ppos, rew_alt(tok)))
+ if (maxargs && endbody == NULL) {
+ if (n == NULL) {
+ /*
+ * Stray .Ec without previous .Eo:
+ * Break the output line, ignore any arguments.
+ */
+ if ( ! mdoc_elem_alloc(mdoc, line, ppos,
+ MDOC_br, NULL))
+ return(0);
+ if ( ! rew_elem(mdoc, MDOC_br))
+ return(0);
+ } else if ( ! mdoc_tail_alloc(mdoc, line, ppos, atok))
return(0);
+ }
- for (flushed = j = 0; ; j++) {
+ flushed = n == NULL;
+ for (j = 0; ; j++) {
lastarg = *pos;
if (j == maxargs && ! flushed) {
- if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
+ if ( ! (endbody != NULL ? rew_last(mdoc, endbody) :
+ rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)))
return(0);
flushed = 1;
}
@@ -819,7 +837,8 @@ blk_exp_close(MACRO_PROT_ARGS)
}
if ( ! flushed) {
- if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
+ if ( ! (endbody != NULL ? rew_last(mdoc, endbody) :
+ rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)))
return(0);
flushed = 1;
}
@@ -831,7 +850,8 @@ blk_exp_close(MACRO_PROT_ARGS)
break;
}
- if ( ! flushed && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos))
+ if ( ! flushed && ! (endbody != NULL ? rew_last(mdoc, endbody) :
+ rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)))
return(0);
if ( ! nl)