aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_macro.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-02-10 16:20:34 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-02-10 16:20:34 +0000
commit129204d2b6e8eb95a79408a2653069d26ec852d7 (patch)
treed9186b8e7011c50d4fb39c5095211049de7aad18 /mdoc_macro.c
parenta4aa2b1f59e2f2354dd17be89ef5ebc595a4bfc0 (diff)
downloadmandoc-129204d2b6e8eb95a79408a2653069d26ec852d7.tar.gz
mandoc-129204d2b6e8eb95a79408a2653069d26ec852d7.tar.zst
mandoc-129204d2b6e8eb95a79408a2653069d26ec852d7.zip
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).
Diffstat (limited to 'mdoc_macro.c')
-rw-r--r--mdoc_macro.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/mdoc_macro.c b/mdoc_macro.c
index d4edcea1..aa3f4cde 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.210 2017/01/10 13:47:00 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.211 2017/02/10 16:20:34 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
@@ -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. */