aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2022-04-28 10:26:37 +0000
committerIngo Schwarze <schwarze@openbsd.org>2022-04-28 10:26:37 +0000
commit4739b39372b31b9276373673e199b90e33fb70a8 (patch)
treeff5870d41a82b125632e2b5e08ef6f1c3afcbd0e
parent25152678ffdb7653b13569fefe86cb617d1e0532 (diff)
downloadmandoc-4739b39372b31b9276373673e199b90e33fb70a8.tar.gz
mandoc-4739b39372b31b9276373673e199b90e33fb70a8.tar.zst
mandoc-4739b39372b31b9276373673e199b90e33fb70a8.zip
Element next-line scopes may nest, so man_breakscope() may have to
break multiple element next-line scopes at the same time, similar to what man_descope() already does for unconditional rewinding. This fixes an assertion failure that tb@ found with afl(1), caused by .SH .I .I .BI and similar sequences of macros without arguments.
-rw-r--r--man.c24
-rw-r--r--regress/man/B/Makefile6
-rw-r--r--regress/man/B/nest.in20
-rw-r--r--regress/man/B/nest.out_ascii12
-rw-r--r--regress/man/B/nest.out_lint6
5 files changed, 59 insertions, 9 deletions
diff --git a/man.c b/man.c
index f0e4002b..8c592b70 100644
--- a/man.c
+++ b/man.c
@@ -1,7 +1,7 @@
-/* $Id: man.c,v 1.187 2019/01/05 00:36:50 schwarze Exp $ */
+/* $Id: man.c,v 1.188 2022/04/28 10:26:37 schwarze Exp $ */
/*
+ * Copyright (c) 2013-2015,2017-2019,2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Joerg Sonnenberger <joerg@netbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -70,6 +70,9 @@ man_hasc(char *start)
return (ep - cp) % 2 ? NULL : ep;
}
+/*
+ * Rewind all open next-line scopes.
+ */
void
man_descope(struct roff_man *man, int line, int offs, char *start)
{
@@ -274,6 +277,10 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
return 1;
}
+/*
+ * Rewind open next-line scopes
+ * unless the tok request or macro is allowed inside them.
+ */
void
man_breakscope(struct roff_man *man, int tok)
{
@@ -294,10 +301,15 @@ man_breakscope(struct roff_man *man, int tok)
(man_macro(n->tok)->flags & (MAN_NSCOPED | MAN_ESCOPED))
== MAN_NSCOPED)
n = n->parent;
-
- mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos,
- "%s breaks %s", roff_name[tok], roff_name[n->tok]);
-
+ for (;;) {
+ mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos,
+ "%s breaks %s", roff_name[tok], roff_name[n->tok]);
+ if (n->parent->type != ROFFT_ELEM ||
+ (man_macro(n->parent->tok)->flags &
+ MAN_ESCOPED) == 0)
+ break;
+ n = n->parent;
+ }
roff_node_delete(man, n);
man->flags &= ~MAN_ELINE;
}
diff --git a/regress/man/B/Makefile b/regress/man/B/Makefile
index 0fbecac0..a3ac6257 100644
--- a/regress/man/B/Makefile
+++ b/regress/man/B/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.1 2014/08/14 02:00:52 schwarze Exp $
+# $OpenBSD: Makefile,v 1.3 2022/04/28 10:17:38 schwarze Exp $
-REGRESS_TARGETS = args blank
-LINT_TARGETS = args blank
+REGRESS_TARGETS = args blank nest
+LINT_TARGETS = args blank nest
# groff-1.22.3 defect:
# - A blank line in next line scope causes a blank line.
diff --git a/regress/man/B/nest.in b/regress/man/B/nest.in
new file mode 100644
index 00000000..5523b4a5
--- /dev/null
+++ b/regress/man/B/nest.in
@@ -0,0 +1,20 @@
+.\" $OpenBSD: nest.in,v 1.2 2022/04/28 10:23:31 schwarze Exp $
+.TH B-NEST 1 "April 28, 2022"
+.SH NAME
+B-nest \- nested next-line scopes
+.SH DESCRIPTION
+initial text
+.B
+.SM
+bold text
+back to roman
+.B
+.SM
+.IR italic roman
+.B
+.SM
+.SH
+.B
+.B
+.RI section header
+final text
diff --git a/regress/man/B/nest.out_ascii b/regress/man/B/nest.out_ascii
new file mode 100644
index 00000000..30aa897d
--- /dev/null
+++ b/regress/man/B/nest.out_ascii
@@ -0,0 +1,12 @@
+B-NEST(1) General Commands Manual B-NEST(1)
+
+NNAAMMEE
+ B-nest - nested next-line scopes
+
+DDEESSCCRRIIPPTTIIOONN
+ initial text bboolldd tteexxtt back to roman _i_t_a_l_i_croman
+
+section_h_e_a_d_e_r
+ final text
+
+OpenBSD April 28, 2022 B-NEST(1)
diff --git a/regress/man/B/nest.out_lint b/regress/man/B/nest.out_lint
new file mode 100644
index 00000000..dd6ba7bd
--- /dev/null
+++ b/regress/man/B/nest.out_lint
@@ -0,0 +1,6 @@
+mandoc: nest.in:12:2: WARNING: line scope broken: IR breaks SM
+mandoc: nest.in:11:2: WARNING: line scope broken: IR breaks B
+mandoc: nest.in:15:2: WARNING: line scope broken: SH breaks SM
+mandoc: nest.in:14:2: WARNING: line scope broken: SH breaks B
+mandoc: nest.in:18:2: WARNING: line scope broken: RI breaks B
+mandoc: nest.in:17:2: WARNING: line scope broken: RI breaks B