1 /* 2 * Copyright (C) 2018 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 "Convert.h" 18 19 #include "LoadedApk.h" 20 #include "test/Test.h" 21 #include "ziparchive/zip_archive.h" 22 23 using testing::Eq; 24 using testing::Ne; 25 26 namespace aapt { 27 28 using ConvertTest = CommandTestFixture; 29 30 TEST_F(ConvertTest, RemoveRawXmlStrings) { 31 StdErrDiagnostics diag; 32 const std::string compiled_files_dir = GetTestPath("compiled"); 33 ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)", 34 compiled_files_dir, &diag)); 35 36 const std::string out_apk = GetTestPath("out.apk"); 37 std::vector<std::string> link_args = { 38 "--manifest", GetDefaultManifest(), 39 "-o", out_apk, 40 "--keep-raw-values", 41 "--proto-format" 42 }; 43 44 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag)); 45 46 const std::string out_convert_apk = GetTestPath("out_convert.apk"); 47 std::vector<android::StringPiece> convert_args = { 48 "-o", out_convert_apk, 49 "--output-format", "binary", 50 out_apk, 51 }; 52 ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0)); 53 54 // Load the binary xml tree 55 android::ResXMLTree tree; 56 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_convert_apk, &diag); 57 58 std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml"); 59 ASSERT_THAT(data, Ne(nullptr)); 60 61 AssertLoadXml(apk.get(), data.get(), &tree); 62 63 // Check that the raw string index has not been assigned 64 EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1)); 65 } 66 67 TEST_F(ConvertTest, KeepRawXmlStrings) { 68 StdErrDiagnostics diag; 69 const std::string compiled_files_dir = GetTestPath("compiled"); 70 ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)", 71 compiled_files_dir, &diag)); 72 73 const std::string out_apk = GetTestPath("out.apk"); 74 std::vector<std::string> link_args = { 75 "--manifest", GetDefaultManifest(), 76 "-o", out_apk, 77 "--keep-raw-values", 78 "--proto-format" 79 }; 80 81 ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag)); 82 83 const std::string out_convert_apk = GetTestPath("out_convert.apk"); 84 std::vector<android::StringPiece> convert_args = { 85 "-o", out_convert_apk, 86 "--output-format", "binary", 87 "--keep-raw-values", 88 out_apk, 89 }; 90 ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0)); 91 92 // Load the binary xml tree 93 android::ResXMLTree tree; 94 std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_convert_apk, &diag); 95 96 std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml"); 97 ASSERT_THAT(data, Ne(nullptr)); 98 99 AssertLoadXml(apk.get(), data.get(), &tree); 100 101 // Check that the raw string index has been set to the correct string pool entry 102 int32_t raw_index = tree.getAttributeValueStringID(0); 103 ASSERT_THAT(raw_index, Ne(-1)); 104 EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007")); 105 } 106 107 TEST_F(ConvertTest, DuplicateEntriesWrittenOnce) { 108 StdErrDiagnostics diag; 109 const std::string apk_path = 110 file::BuildPath({android::base::GetExecutableDirectory(), 111 "integration-tests", "ConvertTest", "duplicate_entries.apk"}); 112 113 const std::string out_convert_apk = GetTestPath("out_convert.apk"); 114 std::vector<android::StringPiece> convert_args = { 115 "-o", out_convert_apk, 116 "--output-format", "proto", 117 apk_path 118 }; 119 ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0)); 120 121 ZipArchiveHandle handle; 122 ASSERT_THAT(OpenArchive(out_convert_apk.c_str(), &handle), Eq(0)); 123 124 void* cookie = nullptr; 125 126 ZipString prefix("res/theme/10"); 127 int32_t result = StartIteration(handle, &cookie, &prefix, nullptr); 128 129 // If this is -5, that means we've found a duplicate entry and this test has failed 130 EXPECT_THAT(result, Eq(0)); 131 132 // But if read succeeds, verify only one res/theme/10 entry 133 int count = 0; 134 135 // Can't pass nullptrs into Next() 136 ZipString zip_name; 137 ZipEntry zip_data; 138 139 while ((result = Next(cookie, &zip_data, &zip_name)) == 0) { 140 count++; 141 } 142 143 EndIteration(cookie); 144 145 EXPECT_THAT(count, Eq(1)); 146 } 147 148 } // namespace aapt