gbranden pushed a commit to branch master
in repository groff.
commit 1e7f305ac5406da4aac8aecf64d6443ffa68111c
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Apr 15 11:52:36 2026 -0500
[troff]: Fix Savannah #68246.
* src/roff/troff/div.cpp (diversion_trap_request): Ignore request if
arguments are present but nonsensical: either the first is not a valid
vertical position expression, or it's present and valid but no second
argument is present.
* src/roff/groff/tests/error-dt-request-given-bogus-arguments.sh: Test
it.
* src/roff/groff/groff.am (groff_TESTS): Run test.
* doc/groff.texi.in (Other Differences):
* man/groff_diff.7.man (Other differences):
* NEWS: Document this behavioral difference from AT&T troffs.
Fixes <https://savannah.gnu.org/bugs/?68246>.
---
ChangeLog | 17 +++++
NEWS | 7 ++
doc/groff.texi.in | 13 ++++
man/groff_diff.7.man | 14 ++++
src/roff/groff/groff.am | 1 +
.../error-dt-request-given-bogus-arguments.sh | 80 ++++++++++++++++++++++
src/roff/troff/div.cpp | 23 ++++---
7 files changed, 146 insertions(+), 9 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f499c34be..91f34b112 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2026-04-15 G. Branden Robinson <[email protected]>
+
+ * src/roff/troff/div.cpp (diversion_trap_request): Ignore
+ request if arguments are present but nonsensical: either the
+ first is not a valid vertical position expression, or it's
+ present and valid but no second argument is present.
+
+ * src/roff/groff/tests/\
+ error-dt-request-given-bogus-arguments.sh: Test it.
+ * src/roff/groff/groff.am (groff_TESTS): Run test.
+
+ * doc/groff.texi.in (Other Differences):
+ * man/groff_diff.7.man (Other differences):
+ * NEWS: Document this behavioral difference from AT&T troffs.
+
+ Fixes <https://savannah.gnu.org/bugs/?68246>.
+
2026-04-15 G. Branden Robinson <[email protected]>
* src/roff/troff/div.cpp (diversion_trap_request): Throw warning
diff --git a/NEWS b/NEWS
index 1346fc271..3739866af 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,13 @@ troff
* GNU troff, the formatter, now employs the unusual Roman numerals "W"
and "Z" of AT&T troff only in compatibility mode.
+* The `dt` request, when given invalid arguments, now does nothing
+ instead of removing any existing diversion trap. This change is
+ inconsistent with AT&T troff but more consistent with general *roff
+ syntax; as a rule, requests given invalid arguments (and that don't
+ process a list of similar objects, as `rm` and `rr` do) perform no
+ operation.
+
* The "delim", "syntax", and "escape" warning categories are enabled by
default.
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 953ef5f31..80dacb8b7 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -22926,6 +22926,19 @@ does not accept a scaling unit on the argument,
a page number;
the former does (uselessly).
+@cindex @code{dt} request, incompatibilities with @acronym{AT&T} @code{troff}
+When the
+@code{dt}
+request is given invalid arguments,
+@acronym{AT&T}
+@command{troff} @c AT&T
+behaves as if it were given no arguments at all,
+removing any existing diversion trap;
+GNU
+@command{troff} @c GNU
+does nothing,
+more consistently with other requests given unintelligible arguments.
+
@cindex @code{lf} request, incompatibilities with @acronym{AT&T} @code{troff}
The
@code{lf}
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 1fb1f48ca..006a75ca4 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -7027,6 +7027,20 @@ the former does (uselessly).
.
.
.P
+When the
+.B dt
+request is given invalid arguments,
+AT&T
+.I troff \" AT&T
+behaves as if it were given no arguments at all,
+removing any existing diversion trap;
+GNU
+.I troff \" GNU
+does nothing,
+more consistently with other requests given unintelligible arguments.
+.
+.
+.P
The
.B lf
request sets the number of the
diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am
index 7de0c2ead..35a7f5053 100644
--- a/src/roff/groff/groff.am
+++ b/src/roff/groff/groff.am
@@ -92,6 +92,7 @@ groff_TESTS = \
src/roff/groff/tests/driver-C-and-G-options-work.sh \
src/roff/groff/tests/dt-request-works.sh \
src/roff/groff/tests/dvi-device-smoke-test.sh \
+ src/roff/groff/tests/error-dt-request-given-bogus-arguments.sh \
src/roff/groff/tests/error-overflow-symbol-table.sh \
src/roff/groff/tests/evc-request-produces-no-output-if-invalid.sh \
src/roff/groff/tests/fi-and-nf-requests-work.sh \
diff --git a/src/roff/groff/tests/error-dt-request-given-bogus-arguments.sh
b/src/roff/groff/tests/error-dt-request-given-bogus-arguments.sh
new file mode 100755
index 000000000..dad835d16
--- /dev/null
+++ b/src/roff/groff/tests/error-dt-request-given-bogus-arguments.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# Copyright 2026 G. Branden Robinson
+#
+# This file is part of groff, the GNU roff typesetting system.
+#
+# groff is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# groff is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+groff="${abs_top_builddir:-.}/test-groff"
+
+fail=
+
+wail () {
+ echo "...FAILED"
+ fail=yes
+}
+
+# If the `dt` request is given arguments, two must be present and they
+# must be valid, otherwise GNU troff performs no operation.
+
+input='.
+.de TT
+WHOOPS
+.br
+..
+.di DD
+.dt 3v TT
+.nf
+foo
+bar
+.dt \e
+.sp
+baz
+.di
+.DD
+.'
+
+output=$(printf '%s\n' "$input" | "$groff" -T ascii)
+echo "$output"
+output=$(echo $output) # condense onto one line
+echo "$output" | grep -q "foo bar WHOOPS baz" || wail
+
+# TODO: read_identifier() needs to interact differently with its callers
+# for us to support this.
+#input2='.
+#.de TT
+#WHOOPS
+#.br
+#..
+#.di DD
+#.dt 3v TT
+#.nf
+#foo
+#bar
+#.dt 4v foo bar
+#.sp
+#baz
+#.di
+#.DD
+#.'
+#
+#output2=$(printf '%s\n' "$input2" | "$groff" -a 2>/dev/null)
+#echo "$output2"
+#output2=$(echo $output2) # condense onto one line
+#echo "$output2" | grep -q "foo bar WHOOPS baz" || wail
+
+test -z "$fail"
+
+# vim:set autoindent expandtab shiftwidth=4 tabstop=4 textwidth=72:
diff --git a/src/roff/troff/div.cpp b/src/roff/troff/div.cpp
index 8a688ebdf..51341f5e5 100644
--- a/src/roff/troff/div.cpp
+++ b/src/roff/troff/div.cpp
@@ -997,18 +997,23 @@ void top_level_diversion::clear_diversion_trap()
static void diversion_trap_request() // .dt
{
vunits n;
- if (has_arg() && read_vunits(&n, 'v')) {
- symbol s = read_identifier();
- if (!s.is_null())
- curdiv->set_diversion_trap(s, n);
- else {
+ if (!has_arg())
+ curdiv->clear_diversion_trap();
+ else if (read_vunits(&n, 'v')) {
+ if (has_arg()) {
+ symbol s = read_identifier();
+ if (!s.is_null())
+ curdiv->set_diversion_trap(s, n);
+ }
+ else
warning(WARN_MISSING, "diversion trap request expects macro"
" identifier argument after vertical position argument");
- curdiv->set_diversion_trap(s, n);
- }
}
- else
- curdiv->clear_diversion_trap();
+ // We have no `else` branch here; `read_vunits()` already threw an
+ // error diagnostic. Historically, GNU troff, like other troffs,
+ // treated botched `dt` arguments the same as no arguments at all,
+ // removing the trap. That behavior was inconsistent with other
+ // request handling.
skip_line();
}
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit