From e760d6bb07748e71b7a76cb5cf8386b96d775423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 12 Feb 2018 11:26:25 +0100 Subject: [PATCH 1/3] Catch unsupported generics exception in superclass ref extraction This catches `unsupported_java_class_signature_exceptiont` that is thrown in case of a non-parseable signature returned from the `extract_generic_superclass` or `extract_generic_interface methods`. --- .../java_bytecode_convert_class.cpp | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 16126efb32f..605a5ddca87 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -239,9 +239,19 @@ void java_bytecode_convert_classt::convert(const classt &c) extract_generic_superclass_reference(c.signature); if(superclass_ref.has_value()) { - const java_generic_symbol_typet generic_base( - base, superclass_ref.value(), qualified_classname); - class_type.add_base(generic_base); + try + { + const java_generic_symbol_typet generic_base( + base, superclass_ref.value(), qualified_classname); + class_type.add_base(generic_base); + } + catch(unsupported_java_class_signature_exceptiont) + { + debug() << "unsupported generic superclass signature " + << id2string(*superclass_ref) + << " falling back on using the descriptor" << eom; + class_type.add_base(base); + } } else { @@ -268,9 +278,19 @@ void java_bytecode_convert_classt::convert(const classt &c) extract_generic_interface_reference(c.signature, id2string(interface)); if(interface_ref.has_value()) { - const java_generic_symbol_typet generic_base( - base, interface_ref.value(), qualified_classname); - class_type.add_base(generic_base); + try + { + const java_generic_symbol_typet generic_base( + base, interface_ref.value(), qualified_classname); + class_type.add_base(generic_base); + } + catch(unsupported_java_class_signature_exceptiont) + { + debug() << "unsupported generic interface signature " + << id2string(*interface_ref) + << " falling back on using the descriptor" << eom; + class_type.add_base(base); + } } else { From f42eeb25881d37ff325b71aaf114d4c525d04d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 12 Feb 2018 17:53:22 +0100 Subject: [PATCH 2/3] Add unit test for generic superclass with unsupported signature --- .../DerivedGenerics.java | 20 ++++++ .../GenericBounds.class | Bin 0 -> 442 bytes .../GenericBoundsLower.class | Bin 0 -> 338 bytes .../GenericBoundsUpper.class | Bin 0 -> 338 bytes .../GenericInterface.class | Bin 0 -> 631 bytes .../parse_generic_superclasses.cpp | 64 ++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 unit/java_bytecode/java_bytecode_parse_generics/GenericBounds.class create mode 100644 unit/java_bytecode/java_bytecode_parse_generics/GenericBoundsLower.class create mode 100644 unit/java_bytecode/java_bytecode_parse_generics/GenericBoundsUpper.class create mode 100644 unit/java_bytecode/java_bytecode_parse_generics/GenericInterface.class create mode 100644 unit/java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp diff --git a/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java b/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java index 6492f0d49dc..caf7bd5e178 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java +++ b/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java @@ -169,3 +169,23 @@ public T someMethod() { return f; } } + +class GenericBounds extends Generic> { + // references exist only to load these class files, too + GenericBoundsUpper gen_upper; + GenericBoundsLower gen_lower; + GenericInterface gen_interface; + +} + +class GenericBoundsUpper extends Generic> { +} + +class GenericBoundsLower extends Generic> { +} + +class GenericInterface implements InterfaceGeneric> { + public Class someMethod(){ + return null; + } +} diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBounds.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBounds.class new file mode 100644 index 0000000000000000000000000000000000000000..50c385d2d67cdb0ffc74cc2c0add1b446499b18b GIT binary patch literal 442 zcmZutJx{|h5PfdbhK7_v2_GAb(19*&jWSRKLW)=lU6GrZVicUpNy@KcU_xTx2k@g1 zXOj+<7<}*U-McS;|9pM{ILD!fCiYzHyEtIz%!PWW77L*ng7{h}p=ENBS1K*;4LhnO zS^oNuBsMHbx~7X%rO=N&5e)rRr<)Z=qIM{iEF*^I$?25A8RscUd$CmFwtATfeaB~+ zEzT33O}UmPu1TkSl7&&Pt!TEJ$hqQWrK$30l?~%(zU0G;BJ@UTf2t<7O@>lnvq(Eq_c2QBh|He8Dv=nyh`)Pv9`Z%AmE h*5Cu|oty@`WZRZ}!xs7ep8!2<+x(8Tee7BcegPu&W(@!U literal 0 HcmV?d00001 diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBoundsLower.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBoundsLower.class new file mode 100644 index 0000000000000000000000000000000000000000..76e961d1d511d9cd9abf5fa7939740f19535fc32 GIT binary patch literal 338 zcmZWkyH3L}6g{_16B+`Asvp1zNDv0LMja?>7mKB+yPH_WDAgWLK}70JZ+S_mz$E6 zv9P%;*V1W!@5G>f&=p}KmdYrn^Bdckq7wF5xhY||(pw|z#&P@AZ%HN|gs2m7f*$|ZFXF=uj3Kj> j(JO=VSI`TS9wLrmE52cmdGb?$A>uZ_-^K(7EgpUY4`EDS literal 0 HcmV?d00001 diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBoundsUpper.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBoundsUpper.class new file mode 100644 index 0000000000000000000000000000000000000000..31a874c061520f7d727a66ec1dace602b71dce52 GIT binary patch literal 338 zcmZWkyH3L}6g{_1lQskjRX>1{heR0I8g-xumZ(chcQ>($QE)0d>3=aGBnCd9ABDIM zVF6pd=lI;mvG-pep8#$!3em+dz;S>Rf}bd@swts+cD^Ebvoe>2VXCy8*Dq^nmSSD7 zGD^!#6f0qrySJiOJt<2Vrw>v~qq5tw*13J$Zl#$J1`D;(qN)wIU;maQ>9g30xDa|1 z&kA8}a`{)8OnDQ+MOm9n-YaK6zT^2jnYTvv%1w#jp~p}A?@kC>5vS=@WJuxDVOA=i|ij9LttYOTwlxBb3gDB98! z_mgo?1dqJu5>m2#hr3-KNYy8x9t~xv{#^@C1k$zi(Yo<7H zh?OJM5VPY?0!Lg)wR`1~mYa%x;u4;!RSL+#C}0Dd4A$cQ1pTi&OGD6N930YP=wQgw z17+wVN9xw7YS7K-&eq?+UZ~KJj|mF=fJtXzM!-5%pqi2pONmbsvBsXMODjK9N-a?q dV~%BAki!-!=f}T7TQpfUUc=0$gmP?G`301xgKPi* literal 0 HcmV?d00001 diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp new file mode 100644 index 00000000000..dd89cae6aad --- /dev/null +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp @@ -0,0 +1,64 @@ +/*******************************************************************\ + + Module: Unit tests for parsing classes with generic superclasses or interfaces + with unsupported signatures, falling back to using the raw type + descriptors + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +#include +#include +#include + +SCENARIO( + "parse generic superclass signature", + "[core][java_byte code[java_bytecode_parse_generics]]") +{ + const symbol_tablet &new_symbol_table = load_java_class( + "GenericBounds", "./java_bytecode/java_bytecode_parse_generics"); + + const std::string base_generic = "java::Generic"; + const irep_idt base_generic_interface = "java::InterfaceGeneric"; + + const std::string load_class("java::GenericBounds"); + THEN( + "these fields have a non-generic base class / interface as their real " + "generic signature is unsupported at the moment") + { + // once bounds in generic signatures are supported, this test must be + // changed to check for the correct generic types, TODO(mgudemann), + // cf. TG-1286, TG-675 + { + const symbolt &upper_symbol = + new_symbol_table.lookup_ref("java::GenericBoundsUpper"); + const java_class_typet &upper_type = + to_java_class_type(upper_symbol.type); + REQUIRE(upper_type.bases().size() == 1); + const symbol_typet base_type = require_type::require_symbol( + upper_type.bases().at(0).type(), base_generic); + REQUIRE_FALSE(is_java_generic_symbol_type(base_type)); + } + { + const symbolt &lower_symbol = + new_symbol_table.lookup_ref("java::GenericBoundsLower"); + const java_class_typet &lower_type = + to_java_class_type(lower_symbol.type); + REQUIRE(lower_type.bases().size() == 1); + const symbol_typet base_type = require_type::require_symbol( + lower_type.bases().at(0).type(), base_generic); + REQUIRE_FALSE(is_java_generic_symbol_type(base_type)); + } + { + const symbolt &interface_symbol = + new_symbol_table.lookup_ref("java::GenericInterface"); + const java_class_typet &interface_type = + to_java_class_type(interface_symbol.type); + REQUIRE(interface_type.bases().size() == 2); + const symbol_typet base_type = require_type::require_symbol( + interface_type.bases().at(1).type(), base_generic_interface); + REQUIRE_FALSE(is_java_generic_symbol_type(base_type)); + } + } +} From 70702960ac8afbcaf8a091570edc16cb83b364f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Wed, 14 Feb 2018 11:53:07 +0100 Subject: [PATCH 3/3] Add unit test to Makefile --- unit/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/unit/Makefile b/unit/Makefile index 16f985fa47a..20185bd20ed 100644 --- a/unit/Makefile +++ b/unit/Makefile @@ -45,6 +45,7 @@ SRC += unit_tests.cpp \ util/symbol_table.cpp \ catch_example.cpp \ java_bytecode/java_virtual_functions/virtual_functions.cpp \ + java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp \ # Empty last line INCLUDES= -I ../src/ -I.