1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "string_reference.h" 18 19 #include <memory> 20 21 #include "dex/dex_file_types.h" 22 #include "dex/test_dex_file_builder.h" 23 #include "gtest/gtest.h" 24 25 namespace art { 26 27 TEST(StringReference, ValueComparator) { 28 // This is a regression test for the StringReferenceValueComparator using the wrong 29 // dex file to get the string data from a StringId. We construct two dex files with 30 // just a single string with the same length but different value. This creates dex 31 // files that have the same layout, so the byte offset read from the StringId in one 32 // dex file, when used in the other dex file still points to valid string data, except 33 // that it's the wrong string. Without the fix the strings would then compare equal. 34 TestDexFileBuilder builder1; 35 builder1.AddString("String1"); 36 std::unique_ptr<const DexFile> dex_file1 = builder1.Build("dummy location 1"); 37 ASSERT_EQ(1u, dex_file1->NumStringIds()); 38 ASSERT_STREQ("String1", dex_file1->GetStringData(dex_file1->GetStringId(dex::StringIndex(0)))); 39 StringReference sr1(dex_file1.get(), dex::StringIndex(0)); 40 41 TestDexFileBuilder builder2; 42 builder2.AddString("String2"); 43 std::unique_ptr<const DexFile> dex_file2 = builder2.Build("dummy location 2"); 44 ASSERT_EQ(1u, dex_file2->NumStringIds()); 45 ASSERT_STREQ("String2", dex_file2->GetStringData(dex_file2->GetStringId(dex::StringIndex(0)))); 46 StringReference sr2(dex_file2.get(), dex::StringIndex(0)); 47 48 StringReferenceValueComparator cmp; 49 EXPECT_TRUE(cmp(sr1, sr2)); // "String1" < "String2" is true. 50 EXPECT_FALSE(cmp(sr2, sr1)); // "String2" < "String1" is false. 51 } 52 53 TEST(StringReference, ValueComparator2) { 54 const char* const kDexFile1Strings[] = { 55 "", 56 "abc", 57 "abcxyz", 58 }; 59 const char* const kDexFile2Strings[] = { 60 "a", 61 "abc", 62 "abcdef", 63 "def", 64 }; 65 const bool expectedCmp12[arraysize(kDexFile1Strings)][arraysize(kDexFile2Strings)] = { 66 { true, true, true, true }, 67 { false, false, true, true }, 68 { false, false, false, true }, 69 }; 70 const bool expectedCmp21[arraysize(kDexFile2Strings)][arraysize(kDexFile1Strings)] = { 71 { false, true, true }, 72 { false, false, true }, 73 { false, false, true }, 74 { false, false, false }, 75 }; 76 77 TestDexFileBuilder builder1; 78 for (const char* s : kDexFile1Strings) { 79 builder1.AddString(s); 80 } 81 std::unique_ptr<const DexFile> dex_file1 = builder1.Build("dummy location 1"); 82 ASSERT_EQ(arraysize(kDexFile1Strings), dex_file1->NumStringIds()); 83 for (size_t index = 0; index != arraysize(kDexFile1Strings); ++index) { 84 ASSERT_STREQ(kDexFile1Strings[index], 85 dex_file1->GetStringData(dex_file1->GetStringId(dex::StringIndex(index)))); 86 } 87 88 TestDexFileBuilder builder2; 89 for (const char* s : kDexFile2Strings) { 90 builder2.AddString(s); 91 } 92 std::unique_ptr<const DexFile> dex_file2 = builder2.Build("dummy location 1"); 93 ASSERT_EQ(arraysize(kDexFile2Strings), dex_file2->NumStringIds()); 94 for (size_t index = 0; index != arraysize(kDexFile2Strings); ++index) { 95 ASSERT_STREQ(kDexFile2Strings[index], 96 dex_file2->GetStringData(dex_file2->GetStringId(dex::StringIndex(index)))); 97 } 98 99 StringReferenceValueComparator cmp; 100 for (size_t index1 = 0; index1 != arraysize(kDexFile1Strings); ++index1) { 101 for (size_t index2 = 0; index2 != arraysize(kDexFile2Strings); ++index2) { 102 StringReference sr1(dex_file1.get(), dex::StringIndex(index1)); 103 StringReference sr2(dex_file2.get(), dex::StringIndex(index2)); 104 EXPECT_EQ(expectedCmp12[index1][index2], cmp(sr1, sr2)) << index1 << " " << index2; 105 EXPECT_EQ(expectedCmp21[index2][index1], cmp(sr2, sr1)) << index1 << " " << index2; 106 } 107 } 108 } 109 110 } // namespace art 111