Hello Automake mavens,

Please see the attached Git commit.

I had to use a nasty hack to force serialization of two regression tests
that both can cause core dumps, and so can race with each other in the
TOCTTOU window on the existence of a "core" file.

Am I doing something wrong?  Is this a known bug?

Is there something I can do that's (1) portable and (2) less nasty than
sleeping?

Regards,
Branden
commit a9f9eb958fec96c0530771a9b9bca2f2e7597e66
Author: G. Branden Robinson <[email protected]>
Date:   Thu Mar 5 09:15:30 2026 -0600

    [groff]: Regression-test Savannah #67978.
    
    * src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh:
      Do it.
    
    * src/roff/groff/groff.am (groff_TESTS): Run test.
    
    Test fails at this commit.

diff --git a/ChangeLog b/ChangeLog
index 5edc379be..4d1fea94e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-03-05  G. Branden Robinson <[email protected]>
+
+	[groff]: Regression-test Savannah #67978.
+
+	* src/roff/groff/tests/\
+	do-not-crash-on-backslash-X-if-font-invalid.sh: Do it.
+	* src/roff/groff/groff.am (groff_TESTS): Run test.
+
 2026-03-03  Rocket Ma <[email protected]>
 
 	* src/preproc/eqn/eqn.am (neqn): `-f $(SH_DEPS_SED_SCRIPT)`
diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am
index 88d95f23c..448d8d89e 100644
--- a/src/roff/groff/groff.am
+++ b/src/roff/groff/groff.am
@@ -64,6 +64,7 @@ groff_TESTS = \
   src/roff/groff/tests/device-request-passes-most-escape-sequences.sh \
   src/roff/groff/tests/device-request-works.sh \
   src/roff/groff/tests/devicem-request-works.sh \
+  src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh \
   src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh \
   src/roff/groff/tests/do-not-free-file-name-pointers-early.sh \
   src/roff/groff/tests/do-not-loop-infinitely-when-breaking-cjk.sh \
@@ -133,6 +134,14 @@ groff_TESTS = \
 TESTS += $(groff_TESTS)
 EXTRA_DIST += $(groff_TESTS)
 
+# This dependency forces serialization of their corresponding tests:
+# since both can create a "core" file, they can race with each other,
+# causing one to spuriously report failure.
+#
+# See section "Parallel Test Harness" of the GNU Automake manual.
+src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.log: \
+  src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.log
+
 # required test artifacts
 EXTRA_DIST += \
   src/roff/groff/tests/artifacts/HONEYPOT \
diff --git a/src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh b/src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh
new file mode 100755
index 000000000..5ed9b99b7
--- /dev/null
+++ b/src/roff/groff/tests/do-not-crash-on-backslash-X-if-font-invalid.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright 2025 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 over
+# 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"
+
+# troff should not perform invalid memory access when writing a device
+# extension command with `\X` when the current font is invalid.
+# Savannah #67978.
+
+if [ -e core ]
+then
+  echo "$0: 'core' file already exists; skipping" >&2
+  exit 77 # skip
+fi
+
+# We disable filling only to make the crash happen "early", before
+# exiting the formatter because the last input line has been read.
+input='.
+.nr BarPos \n[.fp]
+.sty \n[.fp] Bar
+.fam Foo
+.ft \n[BarPos]
+.tm .f=\n[.f]
+.nf
+\X@baz@
+.'
+
+output=$(printf '%s\n' "$input" | "$groff" -a)
+! test -e core
+
+# vim:set autoindent expandtab shiftwidth=4 tabstop=4 textwidth=72:
diff --git a/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh b/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh
index 06f8e1557..753464cea 100755
--- a/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh
+++ b/src/roff/groff/tests/do-not-crash-on-mismatched-diversion-request.sh
@@ -16,13 +16,17 @@
 #
 # 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"
 
 # troff should not perform invalid memory access when using `box` to
 # close a regular diversion.  Savannah #67139.
 
+# XXX: We _tried_ to serialize this test with another core dump
+# producer--see "groff.am"--but it doesn't work with Automake 1.16.3.
+# Force serialization the nasty way (and not necessarily reliably).
+sleep 5
+
 if [ -e core ]
 then
   echo "$0: 'core' file already exists; skipping" >&2

Attachment: signature.asc
Description: PGP signature

Reply via email to