URL:
  <https://savannah.gnu.org/bugs/?68788>

                 Summary: [troff] attempting to draw a horizontal glyph rule
with `\l` with leader character as glyph fails assertion
                   Group: GNU roff
               Submitter: gbranden
               Submitted: Sat 17 Oct 2026 05:42:36 PM UTC
                Category: Formatter
                Severity: 4 - Important
              Item Group: Crash/Unresponsive
                  Status: Confirmed
                 Privacy: Public
             Assigned to: gbranden
             Open/Closed: Open
         Discussion Lock: Unlocked
         Planned Release: None


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: Sat 17 Oct 2026 05:42:36 PM UTC By: G. Branden Robinson <gbranden>
Problem reported against the `\l` escape sequence


    Date: Fri, 16 Oct 2026 21:36:33 +0800
    From: DDT Cr <[email protected]>
    To: [email protected]
    Message-ID:
<CAODORKgJKyecTxc0Unib=cekd5zuwnqhr5ea4hp1e+spzow...@mail.gmail.com>
    Subject: groff: 5 memory-safety defect(s) — reports, PoCs and patches
            attached

    [-- Attachment #1 --]
    [-- Type: multipart/alternative, Encoding: 7bit, Size: 5.1K --]

    Hello,

    I found 5 defect(s) in groff. Each has a minimal PoC, a reproduction
    command and a proposed patch.
...
    4. Assertion failure (abort) while parsing line-drawing escapes        
       CWE-617 — Low (DoS) | CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H
(5.5 Medium)                                                                
       read_line_rule_expression() assumes the token produced by a
line-drawing escape carries charinfo; a crafted sequence violates it and
aborts.    


The POC was far larger than it needed to be, using a "generated" input of 201
bytes.

I can reproduce it in 7 bytes with groff since 1.24.0, but not before.


$ for ver in HEAD 1.24.2 1.24.1 1.24.0 1.23.0 1.22.4 1.22.3; do echo -----
groff $ver; printf '\l"1\001"\n' | ~/groff-$ver/bin/groff -z; done
----- groff HEAD
troff:<standard input>:1: error: expected ordinary, special, or indexed
character, got a leader character
troff: ../src/roff/troff/input.cpp:6281: bool
read_line_rule_expression(units*, unsigned char, charinfo**): Assertion `0 ==
"attempted to use token without charinfo in" " line-drawing escape sequence"'
failed.
/home/branden/groff-HEAD/bin/groff: error: troff: Aborted (core dumped)
----- groff 1.24.2
troff:<standard input>:1: error: expected ordinary, special, or indexed
character, got a leader character
troff: ../src/roff/troff/input.cpp:6131: bool
read_line_rule_expression(units*, unsigned char, charinfo**): Assertion `0 ==
"attempted to use token without charinfo in" " line-drawing escape sequence"'
failed.
/home/branden/groff-1.24.2/bin/groff: error: troff: Aborted (core dumped)
----- groff 1.24.1
troff:<standard input>:1: error: expected ordinary, special, or indexed
character, got a leader character
troff: ../src/roff/troff/input.cpp:6131: bool
read_line_rule_expression(units*, unsigned char, charinfo**): Assertion `0 ==
"attempted to use token without charinfo in" " line-drawing escape sequence"'
failed.
/home/branden/groff-1.24.1/bin/groff: error: troff: Aborted (core dumped)
----- groff 1.24.0
troff:<standard input>:1: error: expected ordinary, special, or indexed
character, got a leader character
troff: ../src/roff/troff/input.cpp:6131: bool
read_line_rule_expression(units*, unsigned char, charinfo**): Assertion `0 ==
"attempted to use token without charinfo in" " line-drawing escape sequence"'
failed.
/home/branden/groff-1.24.0/bin/groff: error: troff: Aborted (core dumped)
----- groff 1.23.0
troff:<standard input>:1: error: expected ordinary or special character, got a
leader character
----- groff 1.22.4
troff: <standard input>:1: normal or special character expected (got a leader
character)
----- groff 1.22.3
<standard input>:1: normal or special character expected (got a leader
character)


The characterization by the reporter that "read_line_rule_expression() assumes
the token produced by a line-drawing escape carries charinfo; a crafted
sequence violates it and aborts" is misleading.  The function clearly knows
that it _shouldn't_ be receiving a "character" that lacks "charinfo", hence
the assertion.  What this means is that we should have a user-facing error
diagnostic here, and we don't.

Check the vertical glyph rule drawing logic as well.

Schedule the fix for 1.25.0.







    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68788>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/

Attachment: signature.asc
Description: PGP signature

Reply via email to