summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2019-02-06 21:11:43 +0000
committerIngo Schwarze <schwarze@openbsd.org>2019-02-06 21:11:43 +0000
commit386d70b32810ee1090f13d0944310eb93a0ba0fc (patch)
tree3f894d3f306d64ebe183d2f08edc2f8b7ffe8dcc
parent3b603764164fcabf9c701ff02e59f9410c580ae8 (diff)
downloadmandoc-386d70b32810ee1090f13d0944310eb93a0ba0fc.tar.gz
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/roff/cond/register.in12
-rw-r--r--regress/roff/cond/register.out_ascii6
-rw-r--r--regress/roff/cond/string.in12
-rw-r--r--regress/roff/cond/string.out_ascii6
-rw-r--r--regress/roff/de/Makefile7
-rw-r--r--regress/roff/de/tab.in41
-rw-r--r--regress/roff/de/tab.out_ascii21
-rw-r--r--regress/roff/ds/Makefile4
-rw-r--r--regress/roff/ds/tab.in10
-rw-r--r--regress/roff/ds/tab.out_ascii9
-rw-r--r--regress/roff/nr/Makefile4
-rw-r--r--regress/roff/nr/tab.in17
-rw-r--r--regress/roff/nr/tab.out_ascii15
-rw-r--r--regress/roff/rn/Makefile5
-rw-r--r--regress/roff/rn/tab.in28
-rw-r--r--regress/roff/rn/tab.out_ascii15
-rw-r--r--regress/roff/rn/tab.out_lint2
-rw-r--r--roff.c25
18 files changed, 217 insertions, 22 deletions
diff --git a/regress/roff/cond/register.in b/regress/roff/cond/register.in
index 44c53a84..879c573c 100644
--- a/regress/roff/cond/register.in
+++ b/regress/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/roff/cond/register.out_ascii b/regress/roff/cond/register.out_ascii
index acd0f724..0799c5e7 100644
--- a/regress/roff/cond/register.out_ascii
+++ b/regress/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/roff/cond/string.in b/regress/roff/cond/string.in
index b3bf14b4..273984be 100644
--- a/regress/roff/cond/string.in
+++ b/regress/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/roff/cond/string.out_ascii b/regress/roff/cond/string.out_ascii
index b5075d21..b01e072a 100644
--- a/regress/roff/cond/string.out_ascii
+++ b/regress/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/roff/de/Makefile b/regress/roff/de/Makefile
index 0d024a23..0d4d203f 100644
--- a/regress/roff/de/Makefile
+++ b/regress/roff/de/Makefile
@@ -1,9 +1,10 @@
-# $OpenBSD: Makefile,v 1.9 2015/02/03 19:37:25 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/roff/de/tab.in b/regress/roff/de/tab.in
new file mode 100644
index 00000000..49d3f2ce
--- /dev/null
+++ b/regress/roff/de/tab.in
@@ -0,0 +1,41 @@
+.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $
+.Dd $Mdocdate$
+.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/roff/de/tab.out_ascii b/regress/roff/de/tab.out_ascii
new file mode 100644
index 00000000..c2a82d87
--- /dev/null
+++ b/regress/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/roff/ds/Makefile b/regress/roff/ds/Makefile
index 98a93d75..773105e8 100644
--- a/regress/roff/ds/Makefile
+++ b/regress/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/roff/ds/tab.in b/regress/roff/ds/tab.in
new file mode 100644
index 00000000..b96cc155
--- /dev/null
+++ b/regress/roff/ds/tab.in
@@ -0,0 +1,10 @@
+.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $
+.Dd $Mdocdate$
+.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/roff/ds/tab.out_ascii b/regress/roff/ds/tab.out_ascii
new file mode 100644
index 00000000..aa0507a6
--- /dev/null
+++ b/regress/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/roff/nr/Makefile b/regress/roff/nr/Makefile
index 562a5f30..dfde628c 100644
--- a/regress/roff/nr/Makefile
+++ b/regress/roff/nr/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.9 2015/01/23 00:38:43 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/roff/nr/tab.in b/regress/roff/nr/tab.in
new file mode 100644
index 00000000..78a626f3
--- /dev/null
+++ b/regress/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/roff/nr/tab.out_ascii b/regress/roff/nr/tab.out_ascii
new file mode 100644
index 00000000..91987d28
--- /dev/null
+++ b/regress/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/roff/rn/Makefile b/regress/roff/rn/Makefile
index 87ef7fe1..8d87c4f1 100644
--- a/regress/roff/rn/Makefile
+++ b/regress/roff/rn/Makefile
@@ -1,5 +1,6 @@
-# $OpenBSD: Makefile,v 1.10 2017/03/07 20:00:02 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/roff/rn/tab.in b/regress/roff/rn/tab.in
new file mode 100644
index 00000000..e8fdbedc
--- /dev/null
+++ b/regress/roff/rn/tab.in
@@ -0,0 +1,28 @@
+.\" $OpenBSD: tab.in,v 1.1 2019/02/06 20:54:28 schwarze Exp $
+.Dd $Mdocdate$
+.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/roff/rn/tab.out_ascii b/regress/roff/rn/tab.out_ascii
new file mode 100644
index 00000000..6f00c8c1
--- /dev/null
+++ b/regress/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/roff/rn/tab.out_lint b/regress/roff/rn/tab.out_lint
new file mode 100644
index 00000000..50998895
--- /dev/null
+++ b/regress/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/roff.c b/roff.c
index d0156977..0766abad 100644
--- a/roff.c
+++ b/roff.c
@@ -2537,7 +2537,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;
@@ -2683,8 +2683,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 == '"')
@@ -3060,7 +3067,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;
@@ -3124,7 +3131,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;
@@ -3459,7 +3466,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;
@@ -3689,7 +3696,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;
@@ -3883,8 +3890,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] == '}')