From 3c72c09b0b46063f51691bedeabc69413194fb61 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Wed, 6 Feb 2019 21:11:43 +0000 Subject: 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 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. --- regress/roff/cond/register.in | 12 +++++++++-- regress/roff/cond/register.out_ascii | 6 +++++- regress/roff/cond/string.in | 12 +++++++++-- regress/roff/cond/string.out_ascii | 6 +++++- regress/roff/de/Makefile | 7 +++--- regress/roff/de/tab.in | 41 ++++++++++++++++++++++++++++++++++++ regress/roff/de/tab.out_ascii | 21 ++++++++++++++++++ regress/roff/ds/Makefile | 4 ++-- regress/roff/ds/tab.in | 10 +++++++++ regress/roff/ds/tab.out_ascii | 9 ++++++++ regress/roff/nr/Makefile | 4 ++-- regress/roff/nr/tab.in | 17 +++++++++++++++ regress/roff/nr/tab.out_ascii | 15 +++++++++++++ regress/roff/rn/Makefile | 5 +++-- regress/roff/rn/tab.in | 28 ++++++++++++++++++++++++ regress/roff/rn/tab.out_ascii | 15 +++++++++++++ regress/roff/rn/tab.out_lint | 2 ++ roff.c | 27 +++++++++++++++++------- 18 files changed, 218 insertions(+), 23 deletions(-) create mode 100644 regress/roff/de/tab.in create mode 100644 regress/roff/de/tab.out_ascii create mode 100644 regress/roff/ds/tab.in create mode 100644 regress/roff/ds/tab.out_ascii create mode 100644 regress/roff/nr/tab.in create mode 100644 regress/roff/nr/tab.out_ascii create mode 100644 regress/roff/rn/tab.in create mode 100644 regress/roff/rn/tab.out_ascii create mode 100644 regress/roff/rn/tab.out_lint 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..5f85fe21 --- /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: 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/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 diff --git a/regress/roff/ds/tab.in b/regress/roff/ds/tab.in new file mode 100644 index 00000000..62c806f3 --- /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: 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/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 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 diff --git a/regress/roff/rn/tab.in b/regress/roff/rn/tab.in new file mode 100644 index 00000000..558b1f42 --- /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: 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/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 b4a452d5..2b07352b 100644 --- a/roff.c +++ b/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.362 2019/02/06 17:40:13 schwarze Exp $ */ +/* $Id: roff.c,v 1.363 2019/02/06 21:11:43 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze @@ -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] == '}') -- cgit v1.2.3-56-ge451