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

                 Summary: [troff] SEGV in font_info::get_tfont()
                   Group: GNU roff
               Submitter: gbranden
               Submitted: Wed 28 Jan 2026 05:29:47 PM UTC
                Category: Core
                Severity: 4 - Important
              Item Group: Crash/Unresponsive
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Unlocked
         Planned Release: None


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: Wed 28 Jan 2026 05:29:47 PM UTC By: G. Branden Robinson <gbranden>
[https://lists.gnu.org/archive/html/bug-groff/2026-01/msg00339.html Bruno
Haible reported the following to the bug-groff list.]

***

In the 1990ies it was well-known that you could crash many programs by
giving them garbage (a.k.a. "random") input. This technique uncovered
many bugs that would also occur on valid (but rarely seen) input.
Later this technique evolved into "fuzzing".

It applies to groff too. See:


$ groff --version
GNU groff version 1.24.0.rc2
...
GNU grops (groff) version 1.24.0.rc2
GNU troff (groff) version 1.24.0.rc2

$ wget https://ftp.gnu.org/gnu/sed/sed-4.8.tar.xz

$ groff -Tpdf sed-4.8.tar.xz  > /dev/null
...
troff:sed-4.8.tar.xz:4026: error: cannot format glyph: no current font
troff:sed-4.8.tar.xz:4026: error: ignoring invalid numeric expression starting

with character code 225
groff: error: troff: Segmentation fault (core dumped)


Oops: troff dumped core! Let's see where:


$ gdb /arch/x86_64-linux-gnu/gnu-inst-groff/1.24.0-rc2/bin/troff 
/var/lib/apport/coredump/core._arch_x86_64-linux-gnu_gnu-inst-groff_1_24_0-rc2_bin_troff.1000.1da7a7b2-b09b-458f-8578-69b57283288c.1409721.176848446

Core was generated by `troff -Tpdf sed-4.8.tar.xz'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000000000044704d in font_info::get_tfont (this=0x191, fs=..., height=0,

slant=0, fontno=-1) at src/roff/troff/node.cpp:312
312       if (0 /* nullptr */ == last_tfont
(gdb) where
#0  0x000000000044704d in font_info::get_tfont (this=0x191, fs=..., height=0,

slant=0, fontno=-1) at src/roff/troff/node.cpp:312
#1  0x0000000000452377 in device_extension_node::device_extension_node 
(this=0x14ded180, m=..., b=false) at src/roff/troff/node.cpp:4369
#2  0x000000000042fcb2 in do_device_extension () at 
src/roff/troff/input.cpp:6787
#3  0x0000000000423635 in token::next (this=0x4b4b40 <tok>) at 
src/roff/troff/input.cpp:2675
#4  0x0000000000425d28 in process_input_stack () at 
src/roff/troff/input.cpp:3556
#5  0x00000000004376d3 in process_input_file (name=0x7ffde98a36d3 
"sed-4.8.tar.xz") at src/roff/troff/input.cpp:9731
#6  0x00000000004389ba in main (argc=3, argv=0x7ffde98a2ce8) at 
src/roff/troff/input.cpp:10103
(gdb) print this
$4 = (font_info * const) 0x191
(gdb) up
#1  0x0000000000452377 in device_extension_node::device_extension_node 
(this=0x14ded180, m=..., b=false) at src/roff/troff/node.cpp:4369
4369      tf = font_table[fontno]->get_tfont(fs, char_height, char_slant,
(gdb) print font_table
$5 = (font_info **) 0x14cef9c0
(gdb) print fontno
$6 = -1
(gdb) print this
$7 = (device_extension_node * const) 0x14ded180
(gdb) print *this
$8 = {<node> = {_vptr.node = 0x47dc80 <vtable for device_extension_node+16>, 
next = 0x0, last = 0x0, state = 0x0, push_state = 0x0, 
    div_nest_level = 0, is_special = true}, mac = {<request_or_macro> = 
{<object> = {_vptr.object = 0x479218 <vtable for macro+16>, 
        refcount = 0}, <No data fields>}, filename = 0x14d3d490 
"sed-4.8.tar.xz", lineno = 4026, len = 233, is_empty_macro = false, 
    is_a_diversion = false, is_a_string = true, p = 0x14de14e0}, tf = 
0x59eeabe12b567b76, gcol = 0x367076eedc716e23, fcol = 0x34673043c6e9ad4c, 
  lacks_command_prefix = false}
(gdb) print curenv
$9 = (environment *) 0x14b01e10
(gdb) print *curenv
$10 = {is_dummy_env = false, prev_line_length = {n = 468000}, line_length = {n

= 468000}, prev_title_length = {n = 468000}, title_length = {
    n = 468000}, prev_size = {p = 10000}, size = {p = 4000}, requested_size =

4000, prev_requested_size = 10000, char_height = 0, 
  char_slant = 0, prev_fontno = 24, fontno = 2, prev_family = 0x14dd5170, 
family = 0x14dd1190, space_size = 12, sentence_space_size = 12, 
  adjust_mode = 1, is_filling = true, was_line_interrupted = false, 
was_previous_line_interrupted = 0, centered_line_count = 0, 
  right_aligned_line_count = 0, prev_vertical_spacing = {n = 12000}, 
vertical_spacing = {n = 12000}, prev_post_vertical_spacing = {n = 0}, 
  post_vertical_spacing = {n = 0}, prev_line_spacing = 1, line_spacing = 1, 
prev_indent = {n = 0}, indent = {n = 0}, temporary_indent = {
    n = 0}, have_temporary_indent = false, saved_indent = {n = 0}, 
target_text_length = {n = 468000}, pre_underline_fontno = 0, 
  underlined_line_count = 0, underline_spaces = false, input_trap = {s = 0x0},

input_trap_count = -1, continued_input_trap = false, 
  line = 0x14de15a0, prev_text_length = {n = 468000}, width_total = {n = 
181333}, space_total = 9, input_line_start = {n = 39999}, 
  tab_contents = 0x0, tab_width = {n = 0}, tab_distance = {n = 0}, 
using_line_tabs = false, current_tab = TAB_NONE, leader_node = 0x0, 
  tab_char = 0x0, leader_char = 0x14af3110, has_current_field = false, 
field_distance = {n = 0}, pre_field_width = {n = 0}, field_spaces = 0, 
  tab_field_spaces = 347148832, tab_precedes_field = false, is_discarding = 
false, is_spreading = false, margin_character_flags = 0 '\000', 
  margin_character_node = 0x0, margin_character_distance = {n = 10000}, 
numbering_nodes = 0x0, line_number_digit_width = {n = 0}, 
  number_text_separation = 1, line_number_indent = 0, line_number_multiple =
1, 
no_number_count = 0, hyphenation_mode = 4, 
  hyphenation_mode_default = 4, hyphen_line_count = 0, hyphen_line_max = -1, 
hyphenation_space = {n = 0}, hyphenation_margin = {n = 0}, 
  composite = false, pending_lines = 0x0, stroke_color = 0x4b8660 
<default_color>, prev_stroke_color = 0x4b8660 <default_color>, 
  fill_color = 0x14b42900, prev_fill_color = 0x4b8660 <default_color>, 
control_character = 46 '.', no_break_control_character = 39 '\'', 
  seen_space = true, seen_eol = false, suppress_next_eol = false, seen_break =

true, tabs = {initial_list = 0x0, repeated_list = 0x14b01fc0}, 
  name = {s = 0x14aa95e2 "0"}, hyphen_indicator_char = 0x0}


So, it seems like the expression env_resolve_font(curenv) (node.cpp:4368)
can return -1, whereas the code is not prepared for this case.

Bruno







    _______________________________________________________

Reply to this item at:

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

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

Attachment: signature.asc
Description: PGP signature

Reply via email to