summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2016-08-20 14:43:39 +0000
committerschwarze <schwarze@openbsd.org>2016-08-20 14:43:39 +0000
commitad7fa6e5733c8a528a9c220b6e810b4e8d68855c (patch)
tree264ddd9b32134a00365b99abf864e422fcf1e051
parentRemove obsolete sxiuart(4) header. (diff)
downloadwireguard-openbsd-ad7fa6e5733c8a528a9c220b6e810b4e8d68855c.tar.xz
wireguard-openbsd-ad7fa6e5733c8a528a9c220b6e810b4e8d68855c.zip
If a column list starts with implicit rows (that is, rows without .It)
and roff-level nodes (e.g. tbl or eqn) follow, don't run into an assertion. Instead, wrap the roff-level nodes in their own row. Issue found by tb@ with afl(1).
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/Makefile6
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/colNoIt.in15
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/colNoIt.out_ascii13
-rw-r--r--regress/usr.bin/mandoc/tbl/macro/Makefile9
-rw-r--r--regress/usr.bin/mandoc/tbl/macro/column.in16
-rw-r--r--regress/usr.bin/mandoc/tbl/macro/column.out_ascii13
-rw-r--r--usr.bin/mandoc/mdoc.c63
-rw-r--r--usr.bin/mandoc/mdoc_validate.c40
8 files changed, 119 insertions, 56 deletions
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/Makefile b/regress/usr.bin/mandoc/mdoc/Bl/Makefile
index 9c740556d88..a40a2828d99 100644
--- a/regress/usr.bin/mandoc/mdoc/Bl/Makefile
+++ b/regress/usr.bin/mandoc/mdoc/Bl/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.29 2015/10/12 15:27:53 schwarze Exp $
+# $OpenBSD: Makefile,v 1.30 2016/08/20 14:43:39 schwarze Exp $
REGRESS_TARGETS = item inset diag ohang bullet dash enum hang tag
-REGRESS_TARGETS += column extend nested offset secstart
+REGRESS_TARGETS += column colNoIt extend nested offset secstart
REGRESS_TARGETS += notype multitype badargs
REGRESS_TARGETS += empty noIt emptyhead emptytag emptyitem multitag
@@ -23,7 +23,7 @@ LINT_TARGETS += bareIt bareTa break breakingIt broken
SKIP_GROFF ?= notype empty break breakingIt broken emptytag
-SKIP_TMAN ?= column multitype multitag bareTa break broken
+SKIP_TMAN ?= column colNoIt multitype multitag bareTa break broken
# Fixing the indentation in long .IP and .TP tags in -man -Tascii
# caused a minor regression in -Tman that is not trivial to fix,
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/colNoIt.in b/regress/usr.bin/mandoc/mdoc/Bl/colNoIt.in
new file mode 100644
index 00000000000..7c80cf9320d
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Bl/colNoIt.in
@@ -0,0 +1,15 @@
+.Dd August 20, 2016
+.Dt BL-COLNOIT 1
+.Os OpenBSD
+.Sh NAME
+.Nm Bl-colNoIt
+.Nd column lists without item macros
+.Sh DESCRIPTION
+.Bl -column "a" "b"
+.Sy a Ta b
+.Em c Ta d
+.El
+.Bl -column "a" "b"
+a b
+c d
+.El
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/colNoIt.out_ascii b/regress/usr.bin/mandoc/mdoc/Bl/colNoIt.out_ascii
new file mode 100644
index 00000000000..e61c33343ff
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Bl/colNoIt.out_ascii
@@ -0,0 +1,13 @@
+BL-COLNOIT(1) General Commands Manual BL-COLNOIT(1)
+
+NNAAMMEE
+ BBll--ccoollNNooIItt - column lists without item macros
+
+DDEESSCCRRIIPPTTIIOONN
+ aa b
+ _c d
+
+ a b
+ c d
+
+OpenBSD August 20, 2016 OpenBSD
diff --git a/regress/usr.bin/mandoc/tbl/macro/Makefile b/regress/usr.bin/mandoc/tbl/macro/Makefile
index 25e415f92c0..70ec1b332c1 100644
--- a/regress/usr.bin/mandoc/tbl/macro/Makefile
+++ b/regress/usr.bin/mandoc/tbl/macro/Makefile
@@ -1,11 +1,12 @@
-# $OpenBSD: Makefile,v 1.1.1.1 2015/01/29 23:24:24 schwarze Exp $
+# $OpenBSD: Makefile,v 1.2 2016/08/20 14:43:40 schwarze Exp $
-REGRESS_TARGETS = man nested
+REGRESS_TARGETS = man nested column
LINT_TARGETS = man nested
-# trivial difference to groff-1.22.3:
+# trivial differences to groff-1.22.3:
# .TS in a table causes a blank table line in GNU tbl(1), but not in mandoc.
+# .TS in a column list causes a blank line in mandoc, but not in GNU tbl(1).
-SKIP_GROFF = nested
+SKIP_GROFF = nested column
.include <bsd.regress.mk>
diff --git a/regress/usr.bin/mandoc/tbl/macro/column.in b/regress/usr.bin/mandoc/tbl/macro/column.in
new file mode 100644
index 00000000000..511025eaf6d
--- /dev/null
+++ b/regress/usr.bin/mandoc/tbl/macro/column.in
@@ -0,0 +1,16 @@
+.Dd August 20, 2016
+.Dt TBL-COLUMN 1
+.Os OpenBSD
+.Sh NAME
+.Nm TBL-column
+.Nd tables inside column lists
+.Sh DESCRIPTION
+.Bl -column "a" "b"
+.Sy a Ta b
+.TS
+lll.
+1 2 3
+4 5 6
+.TE
+.Em c Ta d
+.El
diff --git a/regress/usr.bin/mandoc/tbl/macro/column.out_ascii b/regress/usr.bin/mandoc/tbl/macro/column.out_ascii
new file mode 100644
index 00000000000..b4428aa649d
--- /dev/null
+++ b/regress/usr.bin/mandoc/tbl/macro/column.out_ascii
@@ -0,0 +1,13 @@
+TBL-COLUMN(1) General Commands Manual TBL-COLUMN(1)
+
+NNAAMMEE
+ TTBBLL--ccoolluummnn - tables inside column lists
+
+DDEESSCCRRIIPPTTIIOONN
+ aa b
+ 1 2 3
+ 4 5 6
+
+ _c d
+
+OpenBSD August 20, 2016 OpenBSD
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index 56ae0c9acd5..407f6bb3240 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: mdoc.c,v 1.145 2015/10/30 19:03:36 schwarze Exp $ */
+/* $OpenBSD: mdoc.c,v 1.146 2016/08/20 14:43:39 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -217,29 +217,19 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
struct roff_node *n;
char *c, *ws, *end;
- assert(mdoc->last);
n = mdoc->last;
/*
- * Divert directly to list processing if we're encountering a
- * columnar ROFFT_BLOCK with or without a prior ROFFT_BLOCK entry
- * (a ROFFT_BODY means it's already open, in which case we should
- * process within its context in the normal way).
+ * If a column list contains plain text, assume an implicit item
+ * macro. This can happen one or more times at the beginning
+ * of such a list, intermixed with non-It mdoc macros and with
+ * nodes generated on the roff level, for example by tbl.
*/
- if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
- n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
- /* `Bl' is open without any children. */
- mdoc->flags |= MDOC_FREECOL;
- mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
- return 1;
- }
-
- if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
- NULL != n->parent &&
- MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->norm->Bl.type) {
- /* `Bl' has block-level `It' children. */
+ if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
+ n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
+ (n->parent != NULL && n->parent->tok == MDOC_Bl &&
+ n->parent->norm->Bl.type == LIST_column)) {
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf);
return 1;
@@ -391,36 +381,23 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
* into macro processing.
*/
- if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
- mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
- return 1;
- }
-
n = mdoc->last;
- assert(mdoc->last);
-
- /*
- * If the first macro of a `Bl -column', open an `It' block
- * context around the parsed macro.
- */
-
- if (n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
- n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) {
- mdoc->flags |= MDOC_FREECOL;
- mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
+ if (n == NULL || tok == MDOC_It || tok == MDOC_El) {
+ mdoc_macro(mdoc, tok, ln, sv, &offs, buf);
return 1;
}
/*
- * If we're following a block-level `It' within a `Bl -column'
- * context (perhaps opened in the above block or in ptext()),
- * then open an `It' block context around the parsed macro.
+ * If a column list contains a non-It macro, assume an implicit
+ * item macro. This can happen one or more times at the
+ * beginning of such a list, intermixed with text lines and
+ * with nodes generated on the roff level, for example by tbl.
*/
- if (n->tok == MDOC_It && n->type == ROFFT_BLOCK &&
- NULL != n->parent &&
- MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->norm->Bl.type) {
+ if ((n->tok == MDOC_Bl && n->type == ROFFT_BODY &&
+ n->end == ENDBODY_NOT && n->norm->Bl.type == LIST_column) ||
+ (n->parent != NULL && n->parent->tok == MDOC_Bl &&
+ n->parent->norm->Bl.type == LIST_column)) {
mdoc->flags |= MDOC_FREECOL;
mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf);
return 1;
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index 9d69b6faf11..d1d9bb4d7e2 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.223 2016/08/11 11:39:19 schwarze Exp $ */
+/* $OpenBSD: mdoc_validate.c,v 1.224 2016/08/20 14:43:39 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
@@ -1320,11 +1320,41 @@ post_bl(POST_ARGS)
return;
}
while (nchild != NULL) {
+ nnext = nchild->next;
if (nchild->tok == MDOC_It ||
(nchild->tok == MDOC_Sm &&
- nchild->next != NULL &&
- nchild->next->tok == MDOC_It)) {
- nchild = nchild->next;
+ nnext != NULL && nnext->tok == MDOC_It)) {
+ nchild = nnext;
+ continue;
+ }
+
+ /*
+ * In .Bl -column, the first rows may be implicit,
+ * that is, they may not start with .It macros.
+ * Such rows may be followed by nodes generated on the
+ * roff level, for example .TS, which cannot be moved
+ * out of the list. In that case, wrap such roff nodes
+ * into an implicit row.
+ */
+
+ if (nchild->prev != NULL) {
+ mdoc->last = nchild;
+ mdoc->next = ROFF_NEXT_SIBLING;
+ roff_block_alloc(mdoc, nchild->line,
+ nchild->pos, MDOC_It);
+ roff_head_alloc(mdoc, nchild->line,
+ nchild->pos, MDOC_It);
+ mdoc->next = ROFF_NEXT_SIBLING;
+ roff_body_alloc(mdoc, nchild->line,
+ nchild->pos, MDOC_It);
+ while (nchild->tok != MDOC_It) {
+ mdoc_node_relink(mdoc, nchild);
+ if ((nchild = nnext) == NULL)
+ break;
+ nnext = nchild->next;
+ mdoc->next = ROFF_NEXT_SIBLING;
+ }
+ mdoc->last = nbody;
continue;
}
@@ -1340,13 +1370,11 @@ post_bl(POST_ARGS)
nblock = nbody->parent;
nprev = nblock->prev;
nparent = nblock->parent;
- nnext = nchild->next;
/*
* Unlink this child.
*/
- assert(nchild->prev == NULL);
nbody->child = nnext;
if (nnext == NULL)
nbody->last = NULL;