aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2022-04-28 16:21:09 +0000
committerIngo Schwarze <schwarze@openbsd.org>2022-04-28 16:21:09 +0000
commitb3dd815817ebf3e3bb6e95b8e8b9cc6ed2c64ff8 (patch)
treee720f598888796ac87c46979b54d4543ad1a3fad
parent4739b39372b31b9276373673e199b90e33fb70a8 (diff)
downloadmandoc-b3dd815817ebf3e3bb6e95b8e8b9cc6ed2c64ff8.tar.gz
mandoc-b3dd815817ebf3e3bb6e95b8e8b9cc6ed2c64ff8.tar.zst
mandoc-b3dd815817ebf3e3bb6e95b8e8b9cc6ed2c64ff8.zip
The syntax of the roff(7) .mc request is quite special
and the roff_onearg() parsing function is too generic, so provide a dedicated parsing function instead. This fixes an assertion failure when an \o escape sequence is passed as the argument; the bug was found by tb@ using afl(1). It also makes mandoc output more similar to groff in various cases.
-rw-r--r--mandoc.120
-rw-r--r--mandoc.h4
-rw-r--r--mandoc_msg.c2
-rw-r--r--regress/roff/Makefile4
-rw-r--r--regress/roff/mc/Makefile6
-rw-r--r--regress/roff/mc/args.in29
-rw-r--r--regress/roff/mc/args.out_ascii19
-rw-r--r--regress/roff/mc/args.out_lint9
-rw-r--r--roff.c53
9 files changed, 139 insertions, 7 deletions
diff --git a/mandoc.1 b/mandoc.1
index 415769b3..d689fffa 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.1,v 1.257 2022/04/24 13:38:46 schwarze Exp $
+.\" $Id: mandoc.1,v 1.258 2022/04/28 16:21:09 schwarze Exp $
.\"
.\" Copyright (c) 2012, 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: April 24 2022 $
+.Dd $Mdocdate: April 28 2022 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -1754,6 +1754,15 @@ request or a
layout modifier has an unknown
.Ar font
argument.
+.It Sy "ignoring distance argument"
+.Pq roff
+In addition to the margin character, an
+.Ic \&mc
+request has a second argument supposed to represent a distance, but the
+.Nm
+implementation of
+.Ic \&mc
+always ignores the second argument.
.It Sy "odd number of characters in request"
.Pq roff
A
@@ -2124,6 +2133,13 @@ The first argument of a
request is neither a single ASCII character
nor a single character escape sequence.
The request is ignored including all its arguments.
+.It Sy "skipping unusable escape sequence"
+.Pq roff
+The first argument of an
+.Ic mc
+request is neither a single ASCII character
+nor a single character escape sequence.
+All arguments are ignored and printing of a margin character is disabled.
.It Sy "missing manual name, using \(dq\(dq"
.Pq mdoc
The first call to
diff --git a/mandoc.h b/mandoc.h
index 32914deb..1ed0d816 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.275 2022/04/24 13:38:46 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.276 2022/04/28 16:21:09 schwarze Exp $ */
/*
* Copyright (c) 2012-2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -165,6 +165,7 @@ enum mandocerr {
MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */
MANDOCERR_CHAR_FONT, /* argument contains two font escapes */
MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */
+ MANDOCERR_MC_DIST, /* ignoring distance argument: mc ... arg */
MANDOCERR_TR_ODD, /* odd number of characters in request: tr char */
/* related to plain text */
@@ -221,6 +222,7 @@ enum mandocerr {
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
MANDOCERR_CE_NONUM, /* argument is not numeric, using 1: ce ... */
MANDOCERR_CHAR_ARG, /* argument is not a character: char ... */
+ MANDOCERR_MC_ESC, /* skipping unusable escape sequence: mc arg */
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
MANDOCERR_ST_BAD, /* unknown standard specifier: St standard */
diff --git a/mandoc_msg.c b/mandoc_msg.c
index 0361fc80..80a49d1d 100644
--- a/mandoc_msg.c
+++ b/mandoc_msg.c
@@ -166,6 +166,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
"invalid Boolean argument",
"argument contains two font escapes",
"unknown font, skipping request",
+ "ignoring distance argument",
"odd number of characters in request",
/* related to plain text */
@@ -222,6 +223,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
"missing list type, using -item",
"argument is not numeric, using 1",
"argument is not a character",
+ "skipping unusable escape sequence",
"missing manual name, using \"\"",
"uname(3) system call failed, using UNKNOWN",
"unknown standard specifier",
diff --git a/regress/roff/Makefile b/regress/roff/Makefile
index 9c9580f1..aecb314c 100644
--- a/regress/roff/Makefile
+++ b/regress/roff/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.28 2019/01/04 01:06:44 schwarze Exp $
+# $OpenBSD: Makefile,v 1.29 2022/04/28 16:16:46 schwarze Exp $
SUBDIR = args cond esc scale string
-SUBDIR += br cc ce char de ds ft ig it ll na nr po ps
+SUBDIR += br cc ce char de ds ft ig it ll mc na nr po ps
SUBDIR += return rm rn shift sp ta ti tr while
.include "../Makefile.sub"
diff --git a/regress/roff/mc/Makefile b/regress/roff/mc/Makefile
new file mode 100644
index 00000000..445af7d3
--- /dev/null
+++ b/regress/roff/mc/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.1 2022/04/28 16:16:46 schwarze Exp $
+
+REGRESS_TARGETS = args
+LINT_TARGETS = args
+
+.include <bsd.regress.mk>
diff --git a/regress/roff/mc/args.in b/regress/roff/mc/args.in
new file mode 100644
index 00000000..4e9b245f
--- /dev/null
+++ b/regress/roff/mc/args.in
@@ -0,0 +1,29 @@
+.\" $OpenBSD: args.in,v 1.1 2022/04/28 16:16:46 schwarze Exp $
+.TH MC-ARGS 1 "April 28, 2022"
+.SH NAME
+mc-args \- arguments to the .mc request
+.SH DESCRIPTION
+.ll 50n
+.nf
+initial text
+.mc |suffix
+ASCII character in the margin
+.mc \CXX
+invalid escape sequence
+.mc \!
+unsupported escape sequence
+.mc \a
+ignored escape sequence
+.mc \(ba
+special character in the margin
+.mc \[integral]
+special character represented as string
+.mc \fR
+font escape in the margin
+.mc \N'124'
+numbered character in the margin
+.mc \[u007C]suffix
+Unicode character in the margin
+.mc \o'o/'
+overstriking in the margin
+.ll
diff --git a/regress/roff/mc/args.out_ascii b/regress/roff/mc/args.out_ascii
new file mode 100644
index 00000000..d1a56be6
--- /dev/null
+++ b/regress/roff/mc/args.out_ascii
@@ -0,0 +1,19 @@
+MC-ARGS(1) General Commands Manual MC-ARGS(1)
+
+NNAAMMEE
+ mc-args - arguments to the .mc request
+
+DDEESSCCRRIIPPTTIIOONN
+ initial text
+ ASCII character in the margin |
+ invalid escape sequence
+ unsupported escape sequence
+ ignored escape sequence
+ special character in the margin |
+ special character represented as string <integral>
+ font escape in the margin
+ numbered character in the margin |
+ Unicode character in the margin |
+ overstriking in the margin
+
+OpenBSD April 28, 2022 MC-ARGS(1)
diff --git a/regress/roff/mc/args.out_lint b/regress/roff/mc/args.out_lint
new file mode 100644
index 00000000..56ed4e28
--- /dev/null
+++ b/regress/roff/mc/args.out_lint
@@ -0,0 +1,9 @@
+mandoc: args.in:9:6: WARNING: ignoring distance argument: mc ... suffix
+mandoc: args.in:11:5: WARNING: invalid escape sequence: \C
+mandoc: args.in:11:5: ERROR: skipping unusable escape sequence: mc \C
+mandoc: args.in:13:5: UNSUPP: unsupported escape sequence: \!
+mandoc: args.in:13:5: ERROR: skipping unusable escape sequence: mc \!
+mandoc: args.in:15:5: ERROR: skipping unusable escape sequence: mc \a
+mandoc: args.in:21:5: ERROR: skipping unusable escape sequence: mc \fR
+mandoc: args.in:25:13: WARNING: ignoring distance argument: mc ... suffix
+mandoc: args.in:27:5: ERROR: skipping unusable escape sequence: mc \o'o/'
diff --git a/roff.c b/roff.c
index 328855c0..7bed9429 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.383 2022/04/24 17:40:22 schwarze Exp $ */
+/* $Id: roff.c,v 1.384 2022/04/28 16:21:10 schwarze Exp $ */
/*
* Copyright (c) 2010-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -227,6 +227,7 @@ static int roff_line_ignore(ROFF_ARGS);
static void roff_man_alloc1(struct roff_man *);
static void roff_man_free1(struct roff_man *);
static int roff_manyarg(ROFF_ARGS);
+static int roff_mc(ROFF_ARGS);
static int roff_noarg(ROFF_ARGS);
static int roff_nop(ROFF_ARGS);
static int roff_nr(ROFF_ARGS);
@@ -379,7 +380,7 @@ static struct roffmac roffs[TOKEN_NONE] = {
{ roff_noarg, NULL, NULL, 0 }, /* fi */
{ roff_onearg, NULL, NULL, 0 }, /* ft */
{ roff_onearg, NULL, NULL, 0 }, /* ll */
- { roff_onearg, NULL, NULL, 0 }, /* mc */
+ { roff_mc, NULL, NULL, 0 }, /* mc */
{ roff_noarg, NULL, NULL, 0 }, /* nf */
{ roff_onearg, NULL, NULL, 0 }, /* po */
{ roff_onearg, NULL, NULL, 0 }, /* rj */
@@ -3732,6 +3733,54 @@ roff_eo(ROFF_ARGS)
}
static int
+roff_mc(ROFF_ARGS)
+{
+ struct roff_node *n;
+ char *cp;
+
+ /* Parse the first argument. */
+
+ cp = buf->buf + pos;
+ if (*cp != '\0')
+ cp++;
+ if (buf->buf[pos] == '\\') {
+ switch (mandoc_escape((const char **)&cp, NULL, NULL)) {
+ case ESCAPE_SPECIAL:
+ case ESCAPE_UNICODE:
+ case ESCAPE_NUMBERED:
+ break;
+ default:
+ *cp = '\0';
+ mandoc_msg(MANDOCERR_MC_ESC, ln, pos,
+ "mc %s", buf->buf + pos);
+ buf->buf[pos] = '\0';
+ break;
+ }
+ }
+
+ /* Ignore additional arguments. */
+
+ while (*cp == ' ')
+ *cp++ = '\0';
+ if (*cp != '\0') {
+ mandoc_msg(MANDOCERR_MC_DIST, ln, (int)(cp - buf->buf),
+ "mc ... %s", cp);
+ *cp = '\0';
+ }
+
+ /* Create the .mc node. */
+
+ roff_elem_alloc(r->man, ln, ppos, tok);
+ n = r->man->last;
+ if (buf->buf[pos] != '\0')
+ roff_word_alloc(r->man, ln, pos, buf->buf + pos);
+ n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED;
+ r->man->last = n;
+ r->man->next = ROFF_NEXT_SIBLING;
+ return ROFF_IGN;
+}
+
+static int
roff_nop(ROFF_ARGS)
{
while (buf->buf[pos] == ' ')