blob: 2328e3ddbbb3bada1100abe144b16c482ad1fba4 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Carl Shapiro1fb86202011-06-27 17:43:13 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "dex_file.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070018
Ian Rogers700a4022014-05-19 16:49:03 -070019#include <memory>
20
Ian Rogerse63db272014-07-15 15:36:11 -070021#include "base/stl_util.h"
22#include "base/unix_file/fd_file.h"
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080023#include "common_runtime_test.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080024#include "dex_file-inl.h"
Orion Hodsona4c2a052016-08-17 10:51:42 +010025#include "mem_map.h"
Ian Rogerse63db272014-07-15 15:36:11 -070026#include "os.h"
27#include "scoped_thread_state_change.h"
28#include "thread-inl.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070029
Carl Shapiro1fb86202011-06-27 17:43:13 -070030namespace art {
31
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080032class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070033
34TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070035 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080036 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070037 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070038}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070039
Ian Rogers13735952014-10-08 12:43:28 -070040static const uint8_t kBase64Map[256] = {
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080041 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
44 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
45 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
46 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
47 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
48 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
49 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
50 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
51 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255
63};
64
Orion Hodsona4c2a052016-08-17 10:51:42 +010065static inline std::vector<uint8_t> DecodeBase64(const char* src) {
Ian Rogers13735952014-10-08 12:43:28 -070066 std::vector<uint8_t> tmp;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080067 uint32_t t = 0, y = 0;
68 int g = 3;
69 for (size_t i = 0; src[i] != '\0'; ++i) {
Ian Rogers13735952014-10-08 12:43:28 -070070 uint8_t c = kBase64Map[src[i] & 0xFF];
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080071 if (c == 255) continue;
72 // the final = symbols are read and used to trim the remaining bytes
73 if (c == 254) {
74 c = 0;
75 // prevent g < 0 which would potentially allow an overflow later
76 if (--g < 0) {
Orion Hodsona4c2a052016-08-17 10:51:42 +010077 return std::vector<uint8_t>();
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080078 }
79 } else if (g != 3) {
80 // we only allow = to be at the end
Orion Hodsona4c2a052016-08-17 10:51:42 +010081 return std::vector<uint8_t>();
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080082 }
83 t = (t << 6) | c;
84 if (++y == 4) {
85 tmp.push_back((t >> 16) & 255);
86 if (g > 1) {
87 tmp.push_back((t >> 8) & 255);
88 }
89 if (g > 2) {
90 tmp.push_back(t & 255);
91 }
92 y = t = 0;
93 }
94 }
95 if (y != 0) {
Orion Hodsona4c2a052016-08-17 10:51:42 +010096 return std::vector<uint8_t>();
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080097 }
Orion Hodsona4c2a052016-08-17 10:51:42 +010098 return tmp;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080099}
100
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700101// Although this is the same content logically as the Nested test dex,
102// the DexFileHeader test is sensitive to subtle changes in the
103// contents due to the checksum etc, so we embed the exact input here.
104//
105// class Nested {
106// class Inner {
107// }
108// }
109static const char kRawDex[] =
110 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
111 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
112 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
113 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
114 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
115 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
116 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
117 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
118 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
119 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
120 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
121 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
122 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
123 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
124 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
125 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
126
Narayan Kamath52e66502016-08-01 14:20:31 +0100127// kRawDex38 and 39 are dex'ed versions of the following Java source :
128//
129// public class Main {
130// public static void main(String[] foo) {
131// }
132// }
133//
134// The dex file was manually edited to change its dex version code to 38
135// or 39, respectively.
136static const char kRawDex38[] =
137 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
138 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
139 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
140 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
141 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
142 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
143 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
144 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
145 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
146 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
147
148static const char kRawDex39[] =
149 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
150 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
151 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
152 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
153 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
154 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
155 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
156 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
157 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
158 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
159
ganxiaolincd16d0a2016-07-18 11:21:44 +0800160static const char kRawDexZeroLength[] =
161 "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
162 "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
163 "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
164 "AA==";
165
Narayan Kamath52e66502016-08-01 14:20:31 +0100166static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700167 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700168 CHECK(base64 != nullptr);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100169 std::vector<uint8_t> dex_bytes = DecodeBase64(base64);
170 CHECK_NE(dex_bytes.size(), 0u);
Ian Rogers33e95662013-05-20 20:29:14 -0700171
172 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700173 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700174 CHECK(file.get() != nullptr);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100175 if (!file->WriteFully(dex_bytes.data(), dex_bytes.size())) {
Ian Rogers33e95662013-05-20 20:29:14 -0700176 PLOG(FATAL) << "Failed to write base64 as dex file";
177 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800178 if (file->FlushCloseOrErase() != 0) {
179 PLOG(FATAL) << "Could not flush and close test file.";
180 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100181}
182
183static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
184 const char* location) {
185 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700186
187 // read dex file
188 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700189 static constexpr bool kVerifyChecksum = true;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700190 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800191 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700192 bool success = DexFile::Open(location, location, kVerifyChecksum, &error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700193 CHECK(success) << error_msg;
194 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800195 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Brian Carlstrome0948e12013-08-29 09:36:15 -0700196 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
197 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700198 return dex_file;
199}
200
Orion Hodsona4c2a052016-08-17 10:51:42 +0100201static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
202 const char* location,
203 uint32_t location_checksum) {
204 CHECK(base64 != nullptr);
205 std::vector<uint8_t> dex_bytes = DecodeBase64(base64);
206 CHECK_NE(dex_bytes.size(), 0u);
207
208 std::string error_message;
209 std::unique_ptr<MemMap> region(MemMap::MapAnonymous("test-region",
210 nullptr,
211 dex_bytes.size(),
212 PROT_READ | PROT_WRITE,
213 /* low_4gb */ false,
214 /* reuse */ false,
215 &error_message));
216 memcpy(region->Begin(), dex_bytes.data(), dex_bytes.size());
217 std::unique_ptr<const DexFile> dex_file(DexFile::Open(location,
218 location_checksum,
219 std::move(region),
220 /* verify */ true,
221 /* verify_checksum */ true,
222 &error_message));
223 CHECK(dex_file != nullptr) << error_message;
224 return dex_file;
225}
226
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700227TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700228 ScratchFile tmp;
Ian Rogers700a4022014-05-19 16:49:03 -0700229 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
Orion Hodsona4c2a052016-08-17 10:51:42 +0100230 ASSERT_TRUE(raw != nullptr);
231
232 const DexFile::Header& header = raw->GetHeader();
233 // TODO: header.magic_
234 EXPECT_EQ(0x00d87910U, header.checksum_);
235 // TODO: header.signature_
236 EXPECT_EQ(904U, header.file_size_);
237 EXPECT_EQ(112U, header.header_size_);
238 EXPECT_EQ(0U, header.link_size_);
239 EXPECT_EQ(0U, header.link_off_);
240 EXPECT_EQ(15U, header.string_ids_size_);
241 EXPECT_EQ(112U, header.string_ids_off_);
242 EXPECT_EQ(7U, header.type_ids_size_);
243 EXPECT_EQ(172U, header.type_ids_off_);
244 EXPECT_EQ(2U, header.proto_ids_size_);
245 EXPECT_EQ(200U, header.proto_ids_off_);
246 EXPECT_EQ(1U, header.field_ids_size_);
247 EXPECT_EQ(224U, header.field_ids_off_);
248 EXPECT_EQ(3U, header.method_ids_size_);
249 EXPECT_EQ(232U, header.method_ids_off_);
250 EXPECT_EQ(2U, header.class_defs_size_);
251 EXPECT_EQ(256U, header.class_defs_off_);
252 EXPECT_EQ(584U, header.data_size_);
253 EXPECT_EQ(320U, header.data_off_);
254
255 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
256}
257
258TEST_F(DexFileTest, HeaderInMemory) {
259 ScratchFile tmp;
260 std::unique_ptr<const DexFile> raw =
261 OpenDexFileInMemoryBase64(kRawDex, tmp.GetFilename().c_str(), 0x00d87910U);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700262 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700263
Brian Carlstromf615a612011-07-23 12:50:34 -0700264 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700265 // TODO: header.magic_
266 EXPECT_EQ(0x00d87910U, header.checksum_);
267 // TODO: header.signature_
268 EXPECT_EQ(904U, header.file_size_);
269 EXPECT_EQ(112U, header.header_size_);
270 EXPECT_EQ(0U, header.link_size_);
271 EXPECT_EQ(0U, header.link_off_);
272 EXPECT_EQ(15U, header.string_ids_size_);
273 EXPECT_EQ(112U, header.string_ids_off_);
274 EXPECT_EQ(7U, header.type_ids_size_);
275 EXPECT_EQ(172U, header.type_ids_off_);
276 EXPECT_EQ(2U, header.proto_ids_size_);
277 EXPECT_EQ(200U, header.proto_ids_off_);
278 EXPECT_EQ(1U, header.field_ids_size_);
279 EXPECT_EQ(224U, header.field_ids_off_);
280 EXPECT_EQ(3U, header.method_ids_size_);
281 EXPECT_EQ(232U, header.method_ids_off_);
282 EXPECT_EQ(2U, header.class_defs_size_);
283 EXPECT_EQ(256U, header.class_defs_off_);
284 EXPECT_EQ(584U, header.data_size_);
285 EXPECT_EQ(320U, header.data_off_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800286
287 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
288}
289
Narayan Kamath52e66502016-08-01 14:20:31 +0100290TEST_F(DexFileTest, Version38Accepted) {
291 ScratchFile tmp;
292 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
293 ASSERT_TRUE(raw.get() != nullptr);
294
295 const DexFile::Header& header = raw->GetHeader();
296 EXPECT_EQ(38u, header.GetVersion());
297}
298
299TEST_F(DexFileTest, Version39Rejected) {
300 ScratchFile tmp;
301 const char* location = tmp.GetFilename().c_str();
302 DecodeAndWriteDexFile(kRawDex39, location);
303
304 ScopedObjectAccess soa(Thread::Current());
305 static constexpr bool kVerifyChecksum = true;
306 std::string error_msg;
307 std::vector<std::unique_ptr<const DexFile>> dex_files;
308 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
309}
310
ganxiaolincd16d0a2016-07-18 11:21:44 +0800311TEST_F(DexFileTest, ZeroLengthDexRejected) {
312 ScratchFile tmp;
313 const char* location = tmp.GetFilename().c_str();
314 DecodeAndWriteDexFile(kRawDexZeroLength, location);
315
316 ScopedObjectAccess soa(Thread::Current());
317 static constexpr bool kVerifyChecksum = true;
318 std::string error_msg;
319 std::vector<std::unique_ptr<const DexFile>> dex_files;
320 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
321}
322
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800323TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700324 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800325 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800326 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
327}
328
329TEST_F(DexFileTest, GetChecksum) {
330 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700331 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700332 std::string error_msg;
Przemyslaw Szczepaniak5b8e6e32015-09-30 14:40:33 +0100333 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileNames()[0].c_str(), &checksum, &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700334 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800335 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700336}
337
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700338TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700339 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800340 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
341 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700342 EXPECT_EQ(2U, raw->NumClassDefs());
343
Brian Carlstromf615a612011-07-23 12:50:34 -0700344 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700345 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
346
Brian Carlstromf615a612011-07-23 12:50:34 -0700347 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700348 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700349}
350
Ian Rogersd91d6d62013-09-25 20:26:14 -0700351TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700352 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800353 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
354 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700355 EXPECT_EQ(1U, raw->NumClassDefs());
356
357 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700358 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700359
Ian Rogers13735952014-10-08 12:43:28 -0700360 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700361 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800362 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700363
Ian Rogers0571d352011-11-03 19:51:38 -0700364 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700365
Ian Rogers0571d352011-11-03 19:51:38 -0700366 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700367 {
Ian Rogers0571d352011-11-03 19:51:38 -0700368 ASSERT_EQ(1U, it.NumDirectMethods());
369 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700370 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700371 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700372 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700373 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700374 }
375
376 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700377 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700378 {
Ian Rogers0571d352011-11-03 19:51:38 -0700379 it.Next();
380 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700381
Ian Rogers0571d352011-11-03 19:51:38 -0700382 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700383 ASSERT_STREQ("m1", name);
384
Ian Rogersd91d6d62013-09-25 20:26:14 -0700385 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700386 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700387 }
388
389 {
Ian Rogers0571d352011-11-03 19:51:38 -0700390 it.Next();
391 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700392
Ian Rogers0571d352011-11-03 19:51:38 -0700393 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700394 ASSERT_STREQ("m2", name);
395
Ian Rogersd91d6d62013-09-25 20:26:14 -0700396 std::string signature(raw->GetMethodSignature(method_id).ToString());
397 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700398 }
399}
400
401TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700402 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800403 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
404 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700405 EXPECT_EQ(1U, raw->NumClassDefs());
406
Ian Rogersd91d6d62013-09-25 20:26:14 -0700407 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700408 "D", "I", "J", nullptr };
409 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700410 const char* str = strings[i];
411 const DexFile::StringId* str_id = raw->FindStringId(str);
412 const char* dex_str = raw->GetStringData(*str_id);
413 EXPECT_STREQ(dex_str, str);
414 }
415}
416
417TEST_F(DexFileTest, FindTypeId) {
418 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
419 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
420 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700421 ASSERT_TRUE(type_str_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700422 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
423 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700424 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700425 ASSERT_TRUE(type_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700426 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
427 }
428}
429
430TEST_F(DexFileTest, FindProtoId) {
431 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
432 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
433 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
434 std::vector<uint16_t> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700435 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700436 for (size_t j = 0; j < to_find_tl->Size(); j++) {
437 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
438 }
439 }
440 const DexFile::ProtoId* found =
441 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700442 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700443 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
444 }
445}
446
447TEST_F(DexFileTest, FindMethodId) {
448 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
449 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
450 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
451 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
452 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
453 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700454 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700455 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
456 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700457 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700458 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700459 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700460}
461
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800462TEST_F(DexFileTest, FindFieldId) {
463 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
464 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
465 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
466 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
467 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
468 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700469 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800470 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
471 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
472 << java_lang_dex_file_->GetStringData(name);
473 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
474 }
475}
476
Calin Juravle4e1d5792014-07-15 23:56:47 +0100477TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Andreas Gampe90e34042015-04-27 20:01:52 -0700478 ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
479 ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
480 ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
481 ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
482}
483
484TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100485 std::string dex_location_str = "/system/app/framework.jar";
486 const char* dex_location = dex_location_str.c_str();
Andreas Gampe90e34042015-04-27 20:01:52 -0700487 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
488 ASSERT_EQ("/system/app/framework.jar:classes2.dex",
489 DexFile::GetMultiDexLocation(1, dex_location));
490 ASSERT_EQ("/system/app/framework.jar:classes101.dex",
491 DexFile::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100492}
493
494TEST_F(DexFileTest, GetDexCanonicalLocation) {
495 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100496 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
497 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100498
Calin Juravle61281dc2014-08-07 11:54:36 +0100499 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Andreas Gampe90e34042015-04-27 20:01:52 -0700500 std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100501 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
502
503 std::string dex_location_sym = dex_location + "symlink";
504 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
505
506 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
507
Andreas Gampe90e34042015-04-27 20:01:52 -0700508 std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100509 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
510
511 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
512}
513
Richard Uhlere5fed032015-03-18 08:21:11 -0700514TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
515 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
516 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes2.dex"));
517 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes8.dex"));
518 EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
519 EXPECT_EQ(":classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes2.dex"));
520 EXPECT_EQ(":classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes8.dex"));
521}
522
Carl Shapiro1fb86202011-06-27 17:43:13 -0700523} // namespace art