]> 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>
 .\"
 .\" 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.
 .\"
 .\" 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
 .Dt MANDOC 1
 .Os
 .Sh NAME
@@ -1754,6 +1754,15 @@ request or a
 layout modifier has an unknown
 .Ar font
 argument.
 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
 .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.
 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
 .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>
 /*
  * 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_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 */
        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_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 */
        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",
        "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 */
        "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",
        "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",
        "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  = 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"
 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>
 /*
  * 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 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);
 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_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 */
        { 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;
 }
 
        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)
 {
 static int
 roff_nop(ROFF_ARGS)
 {