From 1053e5f957d73539741a94c0715900f2407599a1 Mon Sep 17 00:00:00 2001 From: Thomas Spriggs Date: Thu, 4 Jan 2018 11:25:29 +0000 Subject: [PATCH] Fix for [TG-1633] Inner generic types have incorrect type identifier The erase_type_arguments function in java_types.cpp is supposed to remove all the type parameters from generic type identifiers. However a bug resulted in only the first one being removed in certain circumstances. --- src/java_bytecode/java_types.cpp | 2 +- .../GenericClassWithGenericInnerClasses.class | Bin 7785 -> 7969 bytes .../GenericClassWithGenericInnerClasses.java | 2 + ...neric_class_with_generic_inner_classes.cpp | 41 +++++++++++ .../java_types/erase_type_arguments.cpp | 68 ++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 unit/java_bytecode/java_types/erase_type_arguments.cpp diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index 5945624ad28..e9d99e44c85 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -252,7 +252,7 @@ std::string erase_type_arguments(const std::string &src) class_name.erase(f_pos, e_pos - f_pos + 1); // Search the remainder of the string for generic signature - f_pos = class_name.find('<', e_pos + 1); + f_pos = class_name.find('<', f_pos + 1); } return class_name; } diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericClassWithGenericInnerClasses.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericClassWithGenericInnerClasses.class index fe2480d4734874693c44c832e11aaa18627424ff..49969bba8111413882511f52a290b80e28f48729 100644 GIT binary patch literal 7969 zcmcIoTUQ%Z6y7IX(gG@_78P3sp*5g#zbD2bP)dzJB?WpB9KryDxj-&dmJdGo;DZmY z<>kpgp--;mgFnC@nfdp>zyBekaXM?E209MY zNtp6sDhTRGKF_Ubc`dV?&FcC2v{t~ywz8oY!c-L0wXS9KB^^_Y)JxODR1$Q}zE^e( z)2X1AvMs1--_X;0f`$|JWRq>vC?0y8^+I3SGb-rnx^a-zilw|RXoBM&OD3c7K^I1| zNk1xRiUZK+i3wqBaXc+*k9#b!oGt44eJ!Q$EN70>dPdI{wW5*BM&p3Cq8k%5R}Y8G z+5sC6({n+c3%Sy6`fNon6!pEbAc9snL|z&CD&v7Q#{sNCok3qlOSFkPAB?$F0yrka z^o^ifo>}Tj7W9at07p_47Rvt2!MzY=RbtkPof5QHPjr>VcZK0v)YF2dIedNIx&|Q& z99K(7um3rEaQ60$pl6pvZz~iwE8NJipvAg~0Ov*=5%fDB(SCU4S`%aWCXTdIZ78i} z4~Ar=Jkax~WpVH3uedg1M%F0C1vNzaHv~1#=l0MkUP~BReWjGy)$>VhH;pSDiCjuc zZ)kZ#+V;i9;-P`2cbgL>)=;M#?*HDd6f zwQaG|JU9QSgmbazp zh4ptye8sAzvi0sFUZi9@7G5LNC&kwuNQahGz5)C`Z@Jh?Fo3X;yGFRE8R$t zLXHM8!^81zJM`5jJl`7j6~L7+(M{&-qcW9uVWRl2@i4uq`xR?JCp^d+6!EK}uB6a_ z>U<_rC>9kO!zM3Tj(%#X!n6OChkPM2s?_HeY?spLSNrt^Sy^dUG~QKHY+qUwwqk8ceMOsCs*?|>HgF`CoK@bPR(Fr|R52R&Uc%?N^;{{R z((f7aT_~bHSD&wNgYuoMjXt75LA{Lmg4)Y(aaJUPCK-+umWH4>$I<`8Bt8{#0PH#C zek5p+xz8? zb|<~%-0y<@wqoCeeT%xC`#rGVQ|w;YeRSKoe+TyaiXDO7uh;{yKT!NX1iO$+5XT|h zo5LtDHVynm;!m73&@hh8=0!mxIB&Bi&?t?;8h2fpfJHP(Q%GIHJ;X1Bp9gBfgzB_z z+EAEA)24P3w0zG3mG{~)!_svIGiE7j)9A3I`W~8Dlcw9c>7kK?F%X8#EXuRogx0Kf z%(AFI22q?ov8jDCyz85xTn&C1UUxFQ3!1rLn#G!EZa6fbf@Yo;g0gwwOC#5=Up8G1 z%_3;-1=Fn7M03-jSpv;{S`Nx4=}XgnPBuLb%>&SU7EJTFCYoM{CIOnyX(cF|ZC@H$ z7yO>h9fxKWG;6^$shVga4vpL?Uj)+})O=b_f=q~fVs!O{Gkd=*;n@IATZ7!tH3-2roq7csS3;^V1CWO{G|%aG&D0313Fl#qS1?}1*n+VYV;jadaOF*m?_hkF=zmAFOAP=3 literal 7785 zcmcIoTUQ%Z6y7IX(o$4PEh@GOLTftp=0d}SE*^aF!3Q6F z(53%FpIplae}F&A<#%R=$r&cY>}2Rea%Rst`}_9(&Y8WF`S-uS{~@9=df7q^RESeC zPDgQiA*em`vbd_1wES|RpqJ)z+VQcV){3DY$EhT!b4|lU|1dr>^T*Wa? zrl6LJEvRYF&~v+jhSJVri*3U&4}8x0ac{*lDd_5&v0u>4a!D67&T*g3WRj@?4@R>^ zKO$(71JLV>31Mt)iV1Txy9jYr%V>!^fqOvLF# z&~4u;^&|^=!cl-DsR|2af92p_in1y(>%>k9+Km!jb@4r6cndBK-3WG3Axz{8FYCToiAn%r_V`A z6g_K(#q2M9mR`?T&UOS&U8pF2!84gscVkS@LL?sRfl#tW(|N=K^k*H^K_z;Lg;|Ff zK}}RiX+lu6y^tC)c+fI7S!r^lQ#*yV;lHz>FGWF>n|lz^zxE?VSY2dKDCf^AI!}_t zS*>Zx19HOhwl%%9zA1^X*tJx)wCz_FgR9mV*|4CcXk>tNQLmMBbK6Nn&`6?>Q*YIt zfIloeCtLqYZA3Rz$k8CCc{u*Z4oFXVzI8lT-Z0Tk=A%(r%6n2r@n7X(`cn@o)`DK} zAnQ;hsD^ryLIaApCsHUD6&k|^FIkR$YN^8B|HebU6d6_O3k$YKY4oeTXhBw2+7pfc z)S^?&@Mx=*Z9!$8vn}kURc()QXgtqfSrm?9txA1Gn^=s<2UG_*F`Jo5A8IGsU`{LS z4?f&E)U#$X<-dj3Tx-R0DXZT%5SOi{K5~f;5Y!zno2(sG{Esw9az26M-))A1+8)T8E`5LbyE!QREb*fd5vBt{6EH3 zjN0&ho!VXd2JAN#`zGuTddHpbg#E5!--3Ocy4?A0*dHi%5A0sLaayZRKT{Jx|&6lA0 ziqc`(Yz5NDIuNuscU_tXpjip0(dwc}xHJzzvl>pbR~JpcOCul1$F$~%mco5m&tl>a ze5=Lm(BiR+S_t0%M`idn1ya|4*03{0~I%&&p@l%9pgd0GSJ7BIhI zV18c%=5t_f)3>2<{!jy^2Fx7>=8rXCW`Vg&dT5+K)quGN%zXyt&oy8k0MlS#{!#MrH&Y|5CS1ocUcq=3qx_|F4Pz_Dw{YiejPGH5pXh(VZVNO3 diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericClassWithGenericInnerClasses.java b/unit/java_bytecode/java_bytecode_parse_generics/GenericClassWithGenericInnerClasses.java index 91d269a85dd..28587c09948 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/GenericClassWithGenericInnerClasses.java +++ b/unit/java_bytecode/java_bytecode_parse_generics/GenericClassWithGenericInnerClasses.java @@ -45,6 +45,8 @@ class TwoParamInnerClass TwoParamInnerClass field9; TwoParamInnerClass field10; + GenericInnerClass>.DoublyNestedInnerGenericClass field11; + void method(InnerClass input) { diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp index 3d0b45dba8e..da1d0303e54 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp @@ -248,6 +248,47 @@ SCENARIO( {require_type::type_argument_kindt::Var, class_prefix + "::T"}}); } } + + THEN( + "The field11 component should be a pointer to " + "GenericClassWithGenericInnerClasses$" + "GenericInnerClass$DoublyNestedInnerGenericClass") + { + const struct_union_typet::componentt &field_component = + require_type::require_component(java_generic_class, "field11"); + + // Declaration of field11 to be tested - + // GenericInnerClass>. + // DoublyNestedInnerGenericClass field11; + + require_type::require_pointer( + field_component.type(), + symbol_typet( + class_prefix + "$GenericInnerClass$DoublyNestedInnerGenericClass")); + + THEN("The pointer should be GenericClassWithGenericInnerClasses") + { + const java_generic_typet &generic_field = + require_type::require_java_generic_type( + field_component.type(), + {{require_type::type_argument_kindt::Var, + "java::GenericClassWithGenericInnerClasses::T"}, + {require_type::type_argument_kindt::Inst, + "java::GenericClassWithGenericInnerClasses"}, + {require_type::type_argument_kindt::Var, + "java::GenericClassWithGenericInnerClasses::T"}}); + + THEN("Test nested Integer parameter.") + { + const typet &nested_generic_field = + generic_field.generic_type_arguments().at(1); + require_type::require_java_generic_type( + nested_generic_field, + {{require_type::type_argument_kindt::Inst, + "java::java.lang.Integer"}}); + } + } + } } } diff --git a/unit/java_bytecode/java_types/erase_type_arguments.cpp b/unit/java_bytecode/java_types/erase_type_arguments.cpp new file mode 100644 index 00000000000..4fd181eda3c --- /dev/null +++ b/unit/java_bytecode/java_types/erase_type_arguments.cpp @@ -0,0 +1,68 @@ +/*******************************************************************\ + + Module: Unit tests for java_types + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +#include +#include + +SCENARIO("erase_type_arguments", "[core][java_types]") +{ + THEN( + "erase_type_arguments should leave strings with no type arguments " + "unaltered.") + { + const std::string testInput1 = "testString1"; + REQUIRE(erase_type_arguments(testInput1) == testInput1); + } + + THEN("erase_type_arguments should remove a simple type argument") + { + REQUIRE( + erase_type_arguments("testClassName") == + "testClassName"); + } + + THEN( + "erase_type_arguments should remove multiple type arguments in cases " + "of nested classes") + { + REQUIRE( + erase_type_arguments( + "outerClass$" + "innerClass") == "outerClass$innerClass"); + } + + THEN( + "erase_type_arguments should remove type arguments which contain nested " + "type arguments") + { + REQUIRE( + erase_type_arguments( + "outerClass>") == "outerClass"); + } + + THEN( + "erase_type_arguments should remove multiple type arguments which contain " + "nested type arguments in cases of nested classes") + { + REQUIRE( + erase_type_arguments( + "outerClass>$" + "innerClass>") == + "outerClass$innerClass"); + } + + THEN( + "erase_type_arguments should throw an error if a type argument is " + "unterminated") + { + REQUIRE_THROWS_AS( + erase_type_arguments( + "testClassName"), + unsupported_java_class_signature_exceptiont &); + } +}