When the head of a list item is extended with a partial explicit
authorschwarze <schwarze@openbsd.org>
Thu, 18 Dec 2014 19:22:47 +0000 (19:22 +0000)
committerschwarze <schwarze@openbsd.org>
Thu, 18 Dec 2014 19:22:47 +0000 (19:22 +0000)
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
regress/usr.bin/mandoc/mdoc/Bl/break.out_ascii
regress/usr.bin/mandoc/mdoc/Bl/break.out_lint
usr.bin/mandoc/mdoc_validate.c

index 4fe9246..9df1144 100644 (file)
@@ -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
index ed14c25..db2c47a 100644 (file)
@@ -28,4 +28,7 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
 C\bCA\bAV\bVE\bEA\bAT\bTS\bS
      before broken block [inside both after list]
 
+B\bBU\bUG\bGS\bS
+     1.
+
 OpenBSD                        December 18, 2014                       OpenBSD
index 70b3c98..546885b 100644 (file)
@@ -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
index f869e7a..003dcbe 100644 (file)
@@ -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 <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -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)