diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2014-11-27 22:27:56 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2014-11-27 22:27:56 +0000 |
commit | e60121aa36205c920bf51da52a8b1ca357beb594 (patch) | |
tree | 8d4860c2d4c0b1a2e0e6910484195594fd0cfb87 /mdoc_macro.c | |
parent | 45fbe869155402e8d8a4dbfce5516c55d9563890 (diff) | |
download | mandoc-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.c | 34 |
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) |