diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2017-02-10 16:20:34 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2017-02-10 16:20:34 +0000 |
commit | a68d897a41b530bdc20192b48d23b5c52edf457c (patch) | |
tree | 63e747725c89b05fd3af30871c0f16fb9bbc1587 | |
parent | 33be0794e265a46ae95f2b46b2d4e7d6f60e3f66 (diff) | |
download | mandoc-a68d897a41b530bdc20192b48d23b5c52edf457c.tar.gz |
In the SYNOPSIS, .Nm blocks can get broken if one of their children
gets broken. In that case, mark them as BROKEN and ENDED and make
sure they get closed out together with the child.
Fixes tree corruption leeding to a NULL dereference found by tb@
with afl(1) in: .Sh SYNOPSIS .Bl .Oo .Nm .Bk .Oc .It (where .Bk is
the child and .Oo is the breaker).
A simpler form of the same corruption (without crash) is visible in:
.Sh SYNOPSIS .Ao .Nm .Bo .Ac .Bc text
where the text ended up inside the .Nm (child .Bo, breaker .Ao).
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | mdoc_macro.c | 20 |
2 files changed, 16 insertions, 6 deletions
@@ -52,6 +52,8 @@ Changes in version 1.14.1, released on February XXX, 2017 for macro sequences like .Bl .Bl .It Bo .El .It. * mdoc(7): Fix syntax tree corruption leading to NULL dereference caused by .Ta following a nested .Bl -column breaking another block. + * mdoc(7): Fix syntax tree corruption sometimes leading to NULL + dereference caused by indirectly broken .Nm blocks in the SYNOPSIS. * mdoc(7) -Thtml: Fix a NULL dereference for .Bl -column with 0 columns. * mdoc(7): Fix NULL dereference if the only child of the head of the first .Sh was an empty in-line macro. diff --git a/mdoc_macro.c b/mdoc_macro.c index facec52e..30323293 100644 --- a/mdoc_macro.c +++ b/mdoc_macro.c @@ -575,16 +575,24 @@ blk_exp_close(MACRO_PROT_ARGS) } /* - * Mismatching end macros can never break anything, - * SYNOPSIS name blocks can never be broken, + * Mismatching end macros can never break anything * and we only care about the breaking of BLOCKs. */ - if (body == NULL || - n->tok == MDOC_Nm || - n->type != ROFFT_BLOCK) + if (body == NULL || n->type != ROFFT_BLOCK) continue; + /* + * SYNOPSIS name blocks can not be broken themselves, + * but they do get broken together with a broken child. + */ + + if (n->tok == MDOC_Nm) { + if (later != NULL) + n->flags |= NODE_BROKEN | NODE_ENDED; + continue; + } + if (n->tok == MDOC_It) { itblk = n; continue; @@ -987,7 +995,7 @@ blk_full(MACRO_PROT_ARGS) /* Close out prior implicit scopes. */ - rew_last(mdoc, n); + rew_pending(mdoc, n); } /* Skip items outside lists. */ |