[
https://issues.apache.org/jira/browse/THRIFT-6332?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jens Geyer resolved THRIFT-6332.
--------------------------------
Fix Version/s: 0.26.0
Assignee: Sylwester Lachiewicz
Resolution: Fixed
> 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.23.0, 0.24.0, 0.25.0
> Reporter: Sylwester Lachiewicz
> Assignee: Sylwester Lachiewicz
> Priority: Major
> Fix For: 0.26.0
>
> Time Spent: 20m
> Remaining Estimate: 0h
>
> {{--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)