URL: <https://savannah.gnu.org/bugs/?68558>
Summary: [PATCH] [troff] assertion failure in `do` request
handler when given an invalid identifier
Group: GNU roff
Submitter: gbranden
Submitted: Fri 24 Jul 2026 09:15:13 PM UTC
Category: Core
Severity: 4 - Important
Item Group: Crash/Unresponsive
Status: In Progress
Privacy: Public
Assigned to: gbranden
Open/Closed: Open
Discussion Lock: Unlocked
Planned Release: None
_______________________________________________________
Follow-up Comments:
-------------------------------------------------------
Date: Fri 24 Jul 2026 09:15:13 PM UTC By: G. Branden Robinson <gbranden>
Discovered by inspection while investigating bug #68552.
I was emotionally preparing myself to fall upon my sword, present my palms for
the nails, rend my garments, and so on.
But it turns out this bad boy is **old**.
$ printf '.do \\a\n' | ~/groff-1.24.1/bin/groff
troff:<standard input>:1: error: expected identifier, got a non-interpreted
character node token; treated as missing
troff: ../src/roff/troff/input.cpp:10349: request_or_macro*
lookup_request(symbol): Assertion `!nm.is_null()' failed.
/home/branden/groff-1.24.1/bin/groff: error: troff: Aborted (core dumped)
$ printf '.do \\a\n' | ~/groff-1.24.0/bin/groff
troff:<standard input>:1: error: expected identifier, got a non-interpreted
character node token; treated as missing
troff: ../src/roff/troff/input.cpp:10339: request_or_macro*
lookup_request(symbol): Assertion `!nm.is_null()' failed.
/home/branden/groff-1.24.0/bin/groff: error: troff: Aborted (core dumped)
$ printf '.do \\a\n' | ~/groff-1.23.0/bin/groff
troff:<standard input>:1: error: expected identifier, got a node; treated as
missing
troff: src/roff/troff/input.cpp:8510: request_or_macro*
lookup_request(symbol): Assertion `!nm.is_null()' failed.
/home/branden/groff-1.23.0/bin/groff: error: troff: Aborted (core dumped)
$ printf '.do \\a\n' | ~/groff-1.22.4/bin/groff
troff: <standard input>:1: name expected (got a node): treated as missing
troff: Failed assertion at line 8286, file 'src/roff/troff/input.cpp'.
/home/branden/groff-1.22.4/bin/groff: troff: Signal 6 (core dumped)
$ printf '.do \\a\n' | ~/groff-1.22.3/bin/groff
<standard input>:1: name expected (got a node): treated as missing
troff: Failed assertion at line 8342, file `input.cpp'.
/home/branden/groff-1.22.3/bin/groff: troff: Signal 6 (core dumped)
Busting the _groff_ 1.25.0 code freeze for this. I have a fix.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index f3657fc99..f63de35e5 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -3494,11 +3494,18 @@ static void do_request() // .do
skip_line();
return;
}
+ // We must attempt to read the first request argument--a request or
+ // macro identifier--with compatibility mode _off_, but if the user
+ // doesn't supply a valid one, we must unwind.
want_att_compat_stack.push(want_att_compat);
want_att_compat = false;
symbol nm = read_identifier();
- if (nm.is_null())
+ if (nm.is_null()) {
+ want_att_compat = want_att_compat_stack.top();
+ want_att_compat_stack.pop();
skip_line();
+ return;
+ }
else
interpolate_macro_or_invoke_request(nm, true /* don't want next token
*/);
assert(!want_att_compat_stack.empty());
I do deserve _some_ blame. I lovingly refactored this thing to migrate it to
use an STL container to stack nested compatibility mode enablement values, and
carefully preserved the bug this whole time.
_______________________________________________________
Reply to this item at:
<https://savannah.gnu.org/bugs/?68558>
_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc
Description: PGP signature
