diff options
author | Hiroshi Yamauchi <yamauchi@google.com> | 2015-05-20 15:51:29 -0700 |
---|---|---|
committer | Hiroshi Yamauchi <yamauchi@google.com> | 2015-05-20 16:09:30 -0700 |
commit | a56ce5e267c9744ed99e40ae5cd9b527971e1d63 (patch) | |
tree | 4a916a7f4dc89d6444ade0d74cc64a3ad5126646 /runtime/proxy_test.cc | |
parent | ce70082da8a4e63c280c2f049a67b38acc82ee1a (diff) | |
download | art-a56ce5e267c9744ed99e40ae5cd9b527971e1d63.tar.gz art-a56ce5e267c9744ed99e40ae5cd9b527971e1d63.tar.bz2 art-a56ce5e267c9744ed99e40ae5cd9b527971e1d63.zip |
Fix a cts crash around proxy class fields.
org.apache.harmony.tests.java.io.SerializationStressTest4#test_writeObject_Proxy
As the static fields of proxy classes share the dex file indices, they
shouldn't be resolved in the dex cache or else Field::GetArtField()
may return a wrong art field that belong to a different proxy class.
Bug: 20557050
Change-Id: If672c0e67bc49e672e34d75ffbe29c65f5a423b9
Diffstat (limited to 'runtime/proxy_test.cc')
-rw-r--r-- | runtime/proxy_test.cc | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc index b471293c09..93d1f668f0 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -20,6 +20,7 @@ #include "art_field-inl.h" #include "class_linker-inl.h" #include "common_compiler_test.h" +#include "mirror/field-inl.h" #include "mirror/method.h" #include "scoped_thread_state_change.h" @@ -191,4 +192,53 @@ TEST_F(ProxyTest, ProxyFieldHelper) { EXPECT_FALSE(field->IsPrimitiveType()); } +// Creates two proxy classes and check the art/mirror fields of their static fields. +TEST_F(ProxyTest, CheckArtMirrorFieldsOfProxyStaticFields) { + ScopedObjectAccess soa(Thread::Current()); + jobject jclass_loader = LoadDex("Interfaces"); + StackHandleScope<7> hs(soa.Self()); + Handle<mirror::ClassLoader> class_loader( + hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + + Handle<mirror::Class> proxyClass0; + Handle<mirror::Class> proxyClass1; + { + std::vector<mirror::Class*> interfaces; + proxyClass0 = hs.NewHandle(GenerateProxyClass(soa, jclass_loader, "$Proxy0", interfaces)); + proxyClass1 = hs.NewHandle(GenerateProxyClass(soa, jclass_loader, "$Proxy1", interfaces)); + } + + ASSERT_TRUE(proxyClass0.Get() != nullptr); + ASSERT_TRUE(proxyClass0->IsProxyClass()); + ASSERT_TRUE(proxyClass0->IsInitialized()); + ASSERT_TRUE(proxyClass1.Get() != nullptr); + ASSERT_TRUE(proxyClass1->IsProxyClass()); + ASSERT_TRUE(proxyClass1->IsInitialized()); + + ArtField* static_fields0 = proxyClass0->GetSFields(); + ASSERT_TRUE(static_fields0 != nullptr); + ASSERT_EQ(2u, proxyClass0->NumStaticFields()); + ArtField* static_fields1 = proxyClass1->GetSFields(); + ASSERT_TRUE(static_fields1 != nullptr); + ASSERT_EQ(2u, proxyClass1->NumStaticFields()); + + EXPECT_EQ(static_fields0[0].GetDeclaringClass(), proxyClass0.Get()); + EXPECT_EQ(static_fields0[1].GetDeclaringClass(), proxyClass0.Get()); + EXPECT_EQ(static_fields1[0].GetDeclaringClass(), proxyClass1.Get()); + EXPECT_EQ(static_fields1[1].GetDeclaringClass(), proxyClass1.Get()); + + Handle<mirror::Field> field00 = + hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields0[0], true)); + Handle<mirror::Field> field01 = + hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields0[1], true)); + Handle<mirror::Field> field10 = + hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields1[0], true)); + Handle<mirror::Field> field11 = + hs.NewHandle(mirror::Field::CreateFromArtField(soa.Self(), &static_fields1[1], true)); + EXPECT_EQ(field00->GetArtField(), &static_fields0[0]); + EXPECT_EQ(field01->GetArtField(), &static_fields0[1]); + EXPECT_EQ(field10->GetArtField(), &static_fields1[0]); + EXPECT_EQ(field11->GetArtField(), &static_fields1[1]); +} + } // namespace art |