Sylwester Lachiewicz created THRIFT-6332:
--------------------------------------------
Summary: Graphviz generator crashes on struct, typedef and nested
container constants
Key: THRIFT-6332
URL: https://issues.apache.org/jira/browse/THRIFT-6332
Project: Thrift
Issue Type: Bug
Components: Graphviz - Compiler
Affects Versions: 0.22.0, 0.25.0, 0.24.0, 0.23.0
Reporter: Sylwester Lachiewicz
{{--gen gv}} crashes on a constant whose declared type is a struct, a typedef,
or a container nested in either. {{t_gv_generator::print_const_value}} casts
the declared type to {{t_map*}}, {{t_list*}} or {{t_set*}} by the shape of the
*value* without checking the type: a struct literal is a {{CV_MAP}} value, so
the cast reads a {{t_map}} member out of a {{t_struct}} object, and a typedef
of a container is a {{t_typedef}} object cast the same way. An integer or
string under the wrong type survives because nothing dereferences the type; an
enum identifier or a nested container does not.
Minimal reproducer, crashes on every run:
{code}
enum E { A = 1 }
struct S { 1: E e }
const S C = { "e": E.A }
{code}
{noformat}
$ thrift --gen gv repro.thrift
Segmentation fault: 11
{noformat}
Under AddressSanitizer (master at 43cd5e041, {{-fsanitize=address}}):
{noformat}
==1556==ERROR: AddressSanitizer: heap-buffer-overflow ...
READ of size 8 at 0x602000000c58 thread T0
#0 t_gv_generator::print_const_value(t_type*, t_const_value*)
t_gv_generator.cc:286
#1 t_gv_generator::print_const_value(t_type*, t_const_value*)
t_gv_generator.cc:263
#2 t_gv_generator::generate_const(t_const*) t_gv_generator.cc:171
{noformat}
Line 263 is {{((t_map*)type)->get_val_type()}} with {{type}} a {{t_struct}};
line 286 then calls {{type->get_name()}} on the garbage pointer that returned.
Other shapes that report the same overflow at lines 261/263, or segfault at 286
through the {{t_set*}} branch: a typedef of {{map<string, E>}} with an enum
value, a typedef of {{list<E>}}, a struct constant holding a map, a struct
constant holding a struct. Only a flat {{{ "x": 1 }}} survives.
In the shipped test suite, {{--gen gv}} on {{test/DebugProtoTest.thrift}} and
{{test/EnumTest.thrift}} crashes, as do
{{lib/go/test/ConstOptionalField.thrift}} and
{{lib/go/test/StructKeyTest.thrift}}: 18 of 20 runs of the last one segfault,
the rest print empty type names where the enum should be.
Fix: resolve the declared type with {{get_true_type()}} for the shape dispatch,
and for a struct literal look each key up as a field name and print the value
with the field's type. Over every {{.thrift}} file in the repository the fixed
generator is sanitizer-clean, produces byte-identical output for the 154 files
that did not crash, and generates the 5 that did.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)