diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2019-02-06 20:54:29 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2019-02-06 20:54:29 +0000 |
commit | 3279fc3fdce4ad6887c10f4fa3bc2cfce55c3d5c (patch) | |
tree | 50ad3bc1585793e04a44edc01e4696ec6f5d1c71 | |
parent | 73131747c4fae4a51afba57ee6cdb7f159f78b3c (diff) |
Let roff_getname() end the roff identifier at a tab character
and audit all its callers whether termination is handled correctly.
Resulting improvements:
* An escape or tab ending the macro name in a macro invocation
is discarded, and argument processing is started after it.
* An escape or tab ending a name in ".if d" and ".if r" is preserved.
* An escape ending a name in ".ds" causes the whole request to be ignored.
* A tab ending a name in ".ds" becomes part of the string.
* An escape or tab ending a name in ".rm"
causes the rest of the line to be ignored.
* An escape or tab ending the first name in ".als", ".rn", or ".nr"
causes the whole request to be ignored.
Kurt Jaeger <pi at FreeBSD> made me aware of
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=235456#c0
and in that bug report, comment 0 item (3) is a special case
of this class of issues.
Yes, the "mh" manual pages are no doubt among the worst on the planet.
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/register.in | 12 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/register.out_ascii | 6 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/string.in | 12 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/cond/string.out_ascii | 6 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/de/Makefile | 7 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/de/tab.in | 41 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/de/tab.out_ascii | 21 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/ds/Makefile | 4 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/ds/tab.in | 10 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/ds/tab.out_ascii | 9 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/nr/Makefile | 4 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/nr/tab.in | 17 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/nr/tab.out_ascii | 15 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/rn/Makefile | 5 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/rn/tab.in | 28 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/rn/tab.out_ascii | 15 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/rn/tab.out_lint | 2 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 27 |
18 files changed, 218 insertions, 23 deletions
diff --git a/regress/usr.bin/mandoc/roff/cond/register.in b/regress/usr.bin/mandoc/roff/cond/register.in index 44c53a84e11..879c573c2d9 100644 --- a/regress/usr.bin/mandoc/roff/cond/register.in +++ b/regress/usr.bin/mandoc/roff/cond/register.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: register.in,v 1.2 2017/07/04 14:53:26 schwarze Exp $ -.TH REGISTER 1 "May 31, 2015" +.\" $OpenBSD: register.in,v 1.3 2019/02/06 20:54:28 schwarze Exp $ +.TH REGISTER 1 "February 6, 2019" .SH NAME register \- conditional testing whether a register is defined .SH DESCRIPTION @@ -10,3 +10,11 @@ register \- conditional testing whether a register is defined .ie rmyreg now defined .el OOPS .if !rmyreg OOPS +.PP +identifier + identifier: +.ie rmyreg myreg is defined +.el OOPS +.PP +escape sequence after identifier: +.ie rmyreg\(enmyreg is defined +.el OOPS diff --git a/regress/usr.bin/mandoc/roff/cond/register.out_ascii b/regress/usr.bin/mandoc/roff/cond/register.out_ascii index acd0f724126..0799c5e7e9d 100644 --- a/regress/usr.bin/mandoc/roff/cond/register.out_ascii +++ b/regress/usr.bin/mandoc/roff/cond/register.out_ascii @@ -9,6 +9,10 @@ DDEESSCCRRIIPPTTIIOONN not yet defined now defined + identifier + identifier: myreg is defined + escape sequence after identifier: -myreg is defined -OpenBSD May 31, 2015 REGISTER(1) + + +OpenBSD February 6, 2019 REGISTER(1) diff --git a/regress/usr.bin/mandoc/roff/cond/string.in b/regress/usr.bin/mandoc/roff/cond/string.in index b3bf14b450d..273984be9e7 100644 --- a/regress/usr.bin/mandoc/roff/cond/string.in +++ b/regress/usr.bin/mandoc/roff/cond/string.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: string.in,v 1.3 2017/07/04 14:53:26 schwarze Exp $ -.TH STRING 1 "June 14, 2017" +.\" $OpenBSD: string.in,v 1.4 2019/02/06 20:54:28 schwarze Exp $ +.TH STRING 1 "February 6, 2019" .SH NAME string \- conditional testing whether a string is defined .SH DESCRIPTION @@ -32,3 +32,11 @@ mymacval standard macro is .ie d PP defined .el not defined \(em OOPS +.PP +identifier and tab: +.ie d mystr mystr is defined +.el OOPS +.PP +escape sequence after identifier: +.ie d mystr\(enmystr is defined +.el OOPS diff --git a/regress/usr.bin/mandoc/roff/cond/string.out_ascii b/regress/usr.bin/mandoc/roff/cond/string.out_ascii index b5075d21f9c..b01e072a747 100644 --- a/regress/usr.bin/mandoc/roff/cond/string.out_ascii +++ b/regress/usr.bin/mandoc/roff/cond/string.out_ascii @@ -17,6 +17,10 @@ DDEESSCCRRIIPPTTIIOONN standard macro is defined + identifier and tab: mystr is defined + escape sequence after identifier: -mystr is defined -OpenBSD June 14, 2017 STRING(1) + + +OpenBSD February 6, 2019 STRING(1) diff --git a/regress/usr.bin/mandoc/roff/de/Makefile b/regress/usr.bin/mandoc/roff/de/Makefile index 4f6039aeb9d..6760dc6e21a 100644 --- a/regress/usr.bin/mandoc/roff/de/Makefile +++ b/regress/usr.bin/mandoc/roff/de/Makefile @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile,v 1.11 2017/07/04 14:53:27 schwarze Exp $ +# $OpenBSD: Makefile,v 1.12 2019/02/06 20:54:28 schwarze Exp $ -REGRESS_TARGETS = append cond escname factorial indir infinite startde TH Dd +REGRESS_TARGETS = append cond escname factorial indir infinite startde tab +REGRESS_TARGETS += TH Dd LINT_TARGETS = escname indir infinite -# groff-1.22.3 defect: +# groff-1.22.4 defect: # infinite recursion aborts output completely SKIP_GROFF = infinite diff --git a/regress/usr.bin/mandoc/roff/de/tab.in b/regress/usr.bin/mandoc/roff/de/tab.in new file mode 100644 index 00000000000..5f85fe21c29 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/de/tab.in @@ -0,0 +1,41 @@ +.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $ +.Dd $Mdocdate: February 6 2019 $ +.Dt DE-TAB 1 +.Os +.Sh NAME +.Nm de-tab +.Nd tab characters in macro definition lines +.Sh DESCRIPTION +.de test1 ignored +testval \\$1;\\$2 +.. +no argument: +.test1 +.br +argument after_tab: +.test1 after_tab +.br +argument after_tab_and_space: +.test1 after_tab_and_space +.br +argument after_two_tabs: +.test1 after_two_tabs +.br +argument after_tab_tab_space: +.test1 after_tab_tab_space +.Ss End marker +.de test2 endm ignored +testval \\$1;\\$2 +.endm +no argument: +.test2 +.br +argument after_tab: +.test2 after_tab +.Ss Removal +.rm test1 test2 +macro test1 is gone: +.test1 +.br +macro test2 still exists: +.test2 diff --git a/regress/usr.bin/mandoc/roff/de/tab.out_ascii b/regress/usr.bin/mandoc/roff/de/tab.out_ascii new file mode 100644 index 00000000000..c2a82d87e8d --- /dev/null +++ b/regress/usr.bin/mandoc/roff/de/tab.out_ascii @@ -0,0 +1,21 @@ +DE-TAB(1) General Commands Manual DE-TAB(1) + +NNAAMMEE + ddee--ttaabb - tab characters in macro definition lines + +DDEESSCCRRIIPPTTIIOONN + no argument: testval ; + argument after_tab: testval after_tab; + argument after_tab_and_space: testval after_tab_and_space; + argument after_two_tabs: testval after_two_tabs; + argument after_tab_tab_space: testval ;after_tab_tab_space + + EEnndd mmaarrkkeerr + no argument: testval ; + argument after_tab: testval after_tab; + + RReemmoovvaall + macro test1 is gone: + macro test2 still exists: testval ; + +OpenBSD February 6, 2019 OpenBSD diff --git a/regress/usr.bin/mandoc/roff/ds/Makefile b/regress/usr.bin/mandoc/roff/ds/Makefile index 98a93d753fd..773105e8e6b 100644 --- a/regress/usr.bin/mandoc/roff/ds/Makefile +++ b/regress/usr.bin/mandoc/roff/ds/Makefile @@ -1,5 +1,5 @@ -# $OpenBSD: Makefile,v 1.5 2014/06/29 22:12:54 schwarze Exp $ +# $OpenBSD: Makefile,v 1.6 2019/02/06 20:54:28 schwarze Exp $ -REGRESS_TARGETS = append escname nested quoting +REGRESS_TARGETS = append escname nested quoting tab .include <bsd.regress.mk> diff --git a/regress/usr.bin/mandoc/roff/ds/tab.in b/regress/usr.bin/mandoc/roff/ds/tab.in new file mode 100644 index 00000000000..62c806f3a52 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/ds/tab.in @@ -0,0 +1,10 @@ +.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $ +.Dd $Mdocdate: February 6 2019 $ +.Dt DS-TAB 1 +.Os +.Sh NAME +.Nm ds-tab +.Nd tab characters in string definition lines +.Sh DESCRIPTION +.ds teststr myval +>>\*[teststr]<< diff --git a/regress/usr.bin/mandoc/roff/ds/tab.out_ascii b/regress/usr.bin/mandoc/roff/ds/tab.out_ascii new file mode 100644 index 00000000000..aa0507a6a62 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/ds/tab.out_ascii @@ -0,0 +1,9 @@ +DS-TAB(1) General Commands Manual DS-TAB(1) + +NNAAMMEE + ddss--ttaabb - tab characters in string definition lines + +DDEESSCCRRIIPPTTIIOONN + >> myval<< + +OpenBSD February 6, 2019 OpenBSD diff --git a/regress/usr.bin/mandoc/roff/nr/Makefile b/regress/usr.bin/mandoc/roff/nr/Makefile index b41296ab69b..dfde628c5e5 100644 --- a/regress/usr.bin/mandoc/roff/nr/Makefile +++ b/regress/usr.bin/mandoc/roff/nr/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.11 2018/04/10 00:52:21 schwarze Exp $ +# $OpenBSD: Makefile,v 1.12 2019/02/06 20:54:28 schwarze Exp $ -REGRESS_TARGETS = argc divzero escname eval incr int predef rr scale undef +REGRESS_TARGETS = argc divzero escname eval incr int predef rr scale tab undef LINT_TARGETS = divzero escname .include <bsd.regress.mk> diff --git a/regress/usr.bin/mandoc/roff/nr/tab.in b/regress/usr.bin/mandoc/roff/nr/tab.in new file mode 100644 index 00000000000..78a626f3d36 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/nr/tab.in @@ -0,0 +1,17 @@ +.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $ +.TH NR-TAB 1 "February 6, 2019" +.SH NAME +nr-tab \- tab characters in register definition lines +.SH DESCRIPTION +with tab: +.nr testreg 1 +>>\n[testreg]<< +.br +with space: +.nr testreg 2 +.nr test2 42 +>>\n[testreg]<< +.br +rr with tab: +.rr testreg test2 +>>\n[myr]:\n[test2]<< diff --git a/regress/usr.bin/mandoc/roff/nr/tab.out_ascii b/regress/usr.bin/mandoc/roff/nr/tab.out_ascii new file mode 100644 index 00000000000..91987d28602 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/nr/tab.out_ascii @@ -0,0 +1,15 @@ +NR-TAB(1) General Commands Manual NR-TAB(1) + + + +NNAAMMEE + nr-tab - tab characters in register definition lines + +DDEESSCCRRIIPPTTIIOONN + with tab: >>0<< + with space: >>2<< + rr with tab: >>0:42<< + + + +OpenBSD February 6, 2019 NR-TAB(1) diff --git a/regress/usr.bin/mandoc/roff/rn/Makefile b/regress/usr.bin/mandoc/roff/rn/Makefile index 4fe29d76f5c..8d87c4f14b5 100644 --- a/regress/usr.bin/mandoc/roff/rn/Makefile +++ b/regress/usr.bin/mandoc/roff/rn/Makefile @@ -1,5 +1,6 @@ -# $OpenBSD: Makefile,v 1.1 2017/06/18 17:35:40 schwarze Exp $ +# $OpenBSD: Makefile,v 1.2 2019/02/06 20:54:28 schwarze Exp $ -REGRESS_TARGETS = append +REGRESS_TARGETS = append tab +LINT_TARGETS = tab .include <bsd.regress.mk> diff --git a/regress/usr.bin/mandoc/roff/rn/tab.in b/regress/usr.bin/mandoc/roff/rn/tab.in new file mode 100644 index 00000000000..558b1f42770 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/rn/tab.in @@ -0,0 +1,28 @@ +.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $ +.Dd $Mdocdate: February 6 2019 $ +.Dt RN-TAB 1 +.Os +.Sh NAME +.Nm rn-tab +.Nd tab characters in macro renaming requests +.Sh DESCRIPTION +.de test1 +testval +.. +trying to rename with a tab between the names: +.rn test1 test2 +.br +calling the macro with the old name: +.test1 +.br +calling the macro with the new name: +.test2 +.Pp +trying to rename with a tab after the names: +.rn test1 test2 ignored +.br +calling the macro with the old name: +.test1 +.br +calling the macro with the new name: +.test2 diff --git a/regress/usr.bin/mandoc/roff/rn/tab.out_ascii b/regress/usr.bin/mandoc/roff/rn/tab.out_ascii new file mode 100644 index 00000000000..6f00c8c1297 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/rn/tab.out_ascii @@ -0,0 +1,15 @@ +RN-TAB(1) General Commands Manual RN-TAB(1) + +NNAAMMEE + rrnn--ttaabb - tab characters in macro renaming requests + +DDEESSCCRRIIPPTTIIOONN + trying to rename with a tab between the names: + calling the macro with the old name: testval + calling the macro with the new name: + + trying to rename with a tab after the names: + calling the macro with the old name: + calling the macro with the new name: testval + +OpenBSD February 6, 2019 OpenBSD diff --git a/regress/usr.bin/mandoc/roff/rn/tab.out_lint b/regress/usr.bin/mandoc/roff/rn/tab.out_lint new file mode 100644 index 00000000000..509988954ef --- /dev/null +++ b/regress/usr.bin/mandoc/roff/rn/tab.out_lint @@ -0,0 +1,2 @@ +mandoc: tab.in:19:2: ERROR: skipping unknown macro: .test2 +mandoc: tab.in:25:2: ERROR: skipping unknown macro: .test1 diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 4b8198ca9e9..b14aebd8071 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.234 2019/02/06 17:39:57 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.235 2019/02/06 20:54:28 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org> @@ -2535,7 +2535,7 @@ roff_evalcond(struct roff *r, int ln, char *v, int *pos) roff_getstrn(r, name, sz, &deftype); istrue = !!deftype; } - *pos = cp - v; + *pos = (name + sz) - v; return istrue == wanttrue; default: break; @@ -2681,8 +2681,15 @@ roff_ds(ROFF_ARGS) return ROFF_IGN; namesz = roff_getname(r, &string, ln, pos); - if (name[namesz] == '\\') + switch (name[namesz]) { + case '\\': return ROFF_IGN; + case '\t': + string = buf->buf + pos + namesz; + break; + default: + break; + } /* Read past the initial double-quote, if any. */ if (*string == '"') @@ -3058,7 +3065,7 @@ roff_nr(ROFF_ARGS) return ROFF_IGN; keysz = roff_getname(r, &val, ln, pos); - if (key[keysz] == '\\') + if (key[keysz] == '\\' || key[keysz] == '\t') return ROFF_IGN; sign = *val; @@ -3122,7 +3129,7 @@ roff_rm(ROFF_ARGS) namesz = roff_getname(r, &cp, ln, (int)(cp - buf->buf)); roff_setstrn(&r->strtab, name, namesz, NULL, 0, 0); roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); - if (name[namesz] == '\\') + if (name[namesz] == '\\' || name[namesz] == '\t') break; } return ROFF_IGN; @@ -3457,7 +3464,7 @@ roff_als(ROFF_ARGS) return ROFF_IGN; newsz = roff_getname(r, &oldn, ln, pos); - if (newn[newsz] == '\\' || *oldn == '\0') + if (newn[newsz] == '\\' || newn[newsz] == '\t' || *oldn == '\0') return ROFF_IGN; end = oldn; @@ -3687,7 +3694,7 @@ roff_rn(ROFF_ARGS) return ROFF_IGN; oldsz = roff_getname(r, &newn, ln, pos); - if (oldn[oldsz] == '\\' || *newn == '\0') + if (oldn[oldsz] == '\\' || oldn[oldsz] == '\t' || *newn == '\0') return ROFF_IGN; end = newn; @@ -3881,8 +3888,12 @@ roff_getname(struct roff *r, char **cpp, int ln, int pos) for (cp = name; 1; cp++) { namesz = cp - name; - if (*cp == '\0' || *cp == ' ') + if (*cp == '\0') break; + if (*cp == ' ' || *cp == '\t') { + cp++; + break; + } if (*cp != '\\') continue; if (cp[1] == '{' || cp[1] == '}') |