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/
signature.asc
Description: PGP signature
