From 4dca9e6b256fa831689e386abf09471867a2e009 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Sun, 26 Mar 2017 14:52:35 +0200 Subject: [PATCH 1/3] THRIFT-4134-Fix-remaining-undefined-behavior-invalid.patch --- build/docker/scripts/ubsan.sh | 2 +- compiler/cpp/src/thrift/generate/t_haxe_generator.cc | 2 +- compiler/cpp/src/thrift/generate/t_java_generator.cc | 4 ++-- compiler/cpp/src/thrift/generate/t_json_generator.cc | 6 +++++- compiler/cpp/src/thrift/generate/t_xml_generator.cc | 7 ++++++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/build/docker/scripts/ubsan.sh b/build/docker/scripts/ubsan.sh index 6db10f3d8dc..ab64e22a005 100755 --- a/build/docker/scripts/ubsan.sh +++ b/build/docker/scripts/ubsan.sh @@ -15,7 +15,7 @@ export CXX=clang++-3.8 # undefined casting, aka "vptr". # # TODO: fix undefined vptr behavior and turn this option back on. -export CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -fno-sanitize=vptr" +export CFLAGS="-fsanitize=undefined" # Builds without optimization and with debugging symbols for making crash reports more # readable. export CFLAGS="${CFLAGS} -O0 -ggdb3" diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc index f5d292fd80e..4de4307b3f8 100644 --- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc @@ -2573,7 +2573,7 @@ string t_haxe_generator::type_name(t_type* ttype, bool in_container, bool in_ini } if (ttype->is_set()) { - t_type* tkey = get_true_type(((t_list*)ttype)->get_elem_type()); + t_type* tkey = get_true_type(((t_set*)ttype)->get_elem_type()); if (tkey->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)tkey)->get_base(); switch (tbase) { diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc index db70dc51e3f..80b8eeff7f0 100644 --- a/compiler/cpp/src/thrift/generate/t_java_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc @@ -2685,7 +2685,7 @@ void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type } else if (type->is_set()) { indent(out) << "new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, "; - t_type* elem_type = ((t_list*)type)->get_elem_type(); + t_type* elem_type = ((t_set*)type)->get_elem_type(); generate_field_value_meta_data(out, elem_type); } else { // map indent(out) @@ -3748,7 +3748,7 @@ void t_java_generator::generate_deserialize_container(ofstream& out, } else if (ttype->is_list()) { indent(out) << "org.apache.thrift.protocol.TList " << obj << " = new org.apache.thrift.protocol.TList(" - << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", iprot.readI32());" + << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", iprot.readI32());" << endl; } } diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc index 36e92166943..f3d67e0e39f 100644 --- a/compiler/cpp/src/thrift/generate/t_json_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc @@ -273,10 +273,14 @@ void t_json_generator::write_type_spec(t_type* ttype) { write_key_and_string("valueTypeId", get_type_name(vtype)); write_type_spec_object("keyType", ktype); write_type_spec_object("valueType", vtype); - } else if (ttype->is_list() || ttype->is_set()) { + } else if (ttype->is_list()) { t_type* etype = ((t_list*)ttype)->get_elem_type(); write_key_and_string("elemTypeId", get_type_name(etype)); write_type_spec_object("elemType", etype); + } else if (ttype->is_set()) { + t_type* etype = ((t_set*)ttype)->get_elem_type(); + write_key_and_string("elemTypeId", get_type_name(etype)); + write_type_spec_object("elemType", etype); } } diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc index b35f35107ea..e7e01fd8c35 100644 --- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc @@ -391,11 +391,16 @@ void t_xml_generator::write_type(t_type* ttype) { if (type == "id") { write_attribute("type-module", ttype->get_program()->get_name()); write_attribute("type-id", ttype->get_name()); - } else if (type == "list" || type == "set") { + } else if (type == "list") { t_type* etype = ((t_list*)ttype)->get_elem_type(); write_element_start("elemType"); write_type(etype); write_element_end(); + } else if (type == "set") { + t_type* etype = ((t_set*)ttype)->get_elem_type(); + write_element_start("elemType"); + write_type(etype); + write_element_end(); } else if (type == "map") { t_type* ktype = ((t_map*)ttype)->get_key_type(); write_element_start("keyType"); From 0d3cc7204d2d531623f35624e80a83c91b03c8e8 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Sun, 26 Mar 2017 17:27:59 +0200 Subject: [PATCH 2/3] THRIFT-4134-Fix-remaining-undefined-behavior-invalid.patch --- build/docker/scripts/ubsan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/docker/scripts/ubsan.sh b/build/docker/scripts/ubsan.sh index ab64e22a005..d39cc8361d2 100755 --- a/build/docker/scripts/ubsan.sh +++ b/build/docker/scripts/ubsan.sh @@ -15,7 +15,7 @@ export CXX=clang++-3.8 # undefined casting, aka "vptr". # # TODO: fix undefined vptr behavior and turn this option back on. -export CFLAGS="-fsanitize=undefined" +export CFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined" # Builds without optimization and with debugging symbols for making crash reports more # readable. export CFLAGS="${CFLAGS} -O0 -ggdb3" From e67ee35eadb62774fdf967e332d9bc6711a0177e Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Sun, 26 Mar 2017 19:41:24 +0200 Subject: [PATCH 3/3] THRIFT-4134 Fix remaining undefined behavior invalid vptr --- compiler/cpp/src/thrift/parse/t_scope.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/cpp/src/thrift/parse/t_scope.h b/compiler/cpp/src/thrift/parse/t_scope.h index e1962002301..02aa550bfda 100644 --- a/compiler/cpp/src/thrift/parse/t_scope.h +++ b/compiler/cpp/src/thrift/parse/t_scope.h @@ -31,6 +31,7 @@ #include "thrift/parse/t_base_type.h" #include "thrift/parse/t_map.h" #include "thrift/parse/t_list.h" +#include "thrift/parse/t_set.h" namespace plugin_output { template @@ -81,12 +82,18 @@ class t_scope { resolve_const_value(v_iter->first, ((t_map*)ttype)->get_key_type()); resolve_const_value(v_iter->second, ((t_map*)ttype)->get_val_type()); } - } else if (ttype->is_list() || ttype->is_set()) { + } else if (ttype->is_list()) { const std::vector& val = const_val->get_list(); std::vector::const_iterator v_iter; for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { resolve_const_value((*v_iter), ((t_list*)ttype)->get_elem_type()); } + } else if (ttype->is_set()) { + const std::vector& val = const_val->get_list(); + std::vector::const_iterator v_iter; + for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { + resolve_const_value((*v_iter), ((t_set*)ttype)->get_elem_type()); + } } else if (ttype->is_struct()) { t_struct* tstruct = (t_struct*)ttype; const std::map& map = const_val->get_map();