From d26e35c25161278a22aa605546c24ef59a097fa5 Mon Sep 17 00:00:00 2001 From: schwarze Date: Thu, 18 Dec 2014 19:22:47 +0000 Subject: [PATCH] When the head of a list item is extended with a partial explicit macro (for example .Xo) and never closed again, the item ends up without a body block. This can even happen for list types that usually don't have heads in the first place. So even in this case, check for the existence of the body before accessing it. NULL pointer access found by jsg@ with afl. --- regress/usr.bin/mandoc/mdoc/Bl/break.in | 5 +++++ regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii | 3 +++ regress/usr.bin/mandoc/mdoc/Bl/break.out_lint | 10 ++++++++-- usr.bin/mandoc/mdoc_validate.c | 14 +++++++------- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/regress/usr.bin/mandoc/mdoc/Bl/break.in b/regress/usr.bin/mandoc/mdoc/Bl/break.in index 4fe9246b5bf..9df11449d4f 100644 --- a/regress/usr.bin/mandoc/mdoc/Bl/break.in +++ b/regress/usr.bin/mandoc/mdoc/Bl/break.in @@ -48,3 +48,8 @@ after both .It before broken block Bo inside both .El after list +.Sh BUGS +.Bl -enum +.It before broken block Bo inside both +.El +after list diff --git a/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii b/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii index ed14c25d910..db2c47a1405 100644 --- a/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii +++ b/regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii @@ -28,4 +28,7 @@ EEXXAAMMPPLLEESS CCAAVVEEAATTSS before broken block [inside both after list] +BBUUGGSS + 1. + OpenBSD December 18, 2014 OpenBSD diff --git a/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint b/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint index 70b3c986446..546885b5cfa 100644 --- a/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint +++ b/regress/usr.bin/mandoc/mdoc/Bl/break.out_lint @@ -5,5 +5,11 @@ mandoc: break.in:32:2: WARNING: blocks badly nested: El breaks Bd mandoc: break.in:41:2: WARNING: blocks badly nested: El breaks Bd mandoc: break.in:42:2: ERROR: skipping item outside list: It mandoc: break.in:49:2: WARNING: blocks badly nested: El breaks It -mandoc: break.in:48:25: ERROR: appending missing end of block: Bo -mandoc: break.in:47:2: ERROR: appending missing end of block: Bl +mandoc: break.in:51:2: ERROR: inserting missing end of block: Sh breaks Bo +mandoc: break.in:51:2: ERROR: inserting missing end of block: Sh breaks It +mandoc: break.in:51:2: ERROR: inserting missing end of block: Sh breaks Bl +mandoc: break.in:54:2: WARNING: blocks badly nested: El breaks It +mandoc: break.in:53:25: ERROR: appending missing end of block: Bo +mandoc: break.in:52:2: ERROR: appending missing end of block: Bl +mandoc: break.in:53:2: WARNING: empty list item: Bl -enum It +mandoc: break.in:53:2: ERROR: skipping all arguments: It before broken block diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index f869e7afd7f..003dcbe7935 100644 --- a/usr.bin/mandoc/mdoc_validate.c +++ b/usr.bin/mandoc/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_validate.c,v 1.179 2014/11/30 05:28:00 schwarze Exp $ */ +/* $OpenBSD: mdoc_validate.c,v 1.180 2014/12/18 19:22:47 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -1188,7 +1188,7 @@ post_it(POST_ARGS) struct mdoc_node *nbl, *nit, *nch; nit = mdoc->last; - if (MDOC_BLOCK != nit->type) + if (nit->type != MDOC_BLOCK) return; nbl = nit->parent->parent; @@ -1204,7 +1204,7 @@ post_it(POST_ARGS) case LIST_inset: /* FALLTHROUGH */ case LIST_diag: - if (NULL == nit->head->child) + if (nit->head->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOHEAD, mdoc->parse, nit->line, nit->pos, "Bl -%s It", @@ -1217,14 +1217,14 @@ post_it(POST_ARGS) case LIST_enum: /* FALLTHROUGH */ case LIST_hyphen: - if (NULL == nit->body->child) + if (nit->body == NULL || nit->body->child == NULL) mandoc_vmsg(MANDOCERR_IT_NOBODY, mdoc->parse, nit->line, nit->pos, "Bl -%s It", mdoc_argnames[nbl->args->argv[0].arg]); /* FALLTHROUGH */ case LIST_item: - if (NULL != nit->head->child) + if (nit->head->child != NULL) mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, nit->line, nit->pos, "It %s", nit->head->child->string); @@ -1232,10 +1232,10 @@ post_it(POST_ARGS) case LIST_column: cols = (int)nbl->norm->Bl.ncols; - assert(NULL == nit->head->child); + assert(nit->head->child == NULL); for (i = 0, nch = nit->child; nch; nch = nch->next) - if (MDOC_BODY == nch->type) + if (nch->type == MDOC_BODY) i++; if (i < cols || i > cols + 1) -- 2.20.1