]> git.cameronkatri.com Git - mandoc.git/commitdiff
The syntax of the roff(7) .mc request is quite special
authorIngo Schwarze <schwarze@openbsd.org>
Thu, 28 Apr 2022 16:21:09 +0000 (16:21 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Thu, 28 Apr 2022 16:21:09 +0000 (16:21 +0000)
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.

mandoc.1
mandoc.h
mandoc_msg.c
regress/roff/Makefile
regress/roff/mc/Makefile [new file with mode: 0644]
regress/roff/mc/args.in [new file with mode: 0644]
regress/roff/mc/args.out_ascii [new file with mode: 0644]
regress/roff/mc/args.out_lint [new file with mode: 0644]
roff.c

index 415769b3d287e5fcee6b6de6aa1620262ee60784..d689fffa7e86ef129f35856a21a11809ba6fed6d 100644 (file)
--- 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
index 32914deb774eb07dc4afb11cff08d52671baa5ff..1ed0d816bf3ca5a87ea1922a2853adbae2416d08 100644 (file)
--- 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 */
index 0361fc8042050642b5a5aba852dca04d9d16b0a7..80a49d1d8cd5ad532281be0068d92d639b478998 100644 (file)
@@ -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",
index 9c9580f19410d05fbb3c852fe7ad4f73b6a7c3b4..aecb314c87462368faf15b7bac7ae33f3ae62a48 100644 (file)
@@ -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 (file)
index 0000000..445af7d
--- /dev/null
@@ -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 (file)
index 0000000..4e9b245
--- /dev/null
@@ -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 (file)
index 0000000..d1a56be
--- /dev/null
@@ -0,0 +1,19 @@
+MC-ARGS(1)                  General Commands Manual                 MC-ARGS(1)
+
+N\bNA\bAM\bME\bE
+       mc-args - arguments to the .mc request
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+       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 (file)
index 0000000..56ed4e2
--- /dev/null
@@ -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 328855c052c83e1f5ad9dde35bf359e415176c79..7bed94293f04a895bd66738090d6d5106fbdb813 100644 (file)
--- 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 */
@@ -3731,6 +3732,54 @@ roff_eo(ROFF_ARGS)
        return ROFF_IGN;
 }
 
+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)
 {