blob: 2704d8a0101dcc5faad94611a2c6a63276cc9abc [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"
Ian Rogerse63db272014-07-15 15:36:11 -070025#include "os.h"
26#include "scoped_thread_state_change.h"
27#include "thread-inl.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070028
Carl Shapiro1fb86202011-06-27 17:43:13 -070029namespace art {
30
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080031class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070032
33TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070034 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080035 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070036 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070037}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070038
Ian Rogers13735952014-10-08 12:43:28 -070039static const uint8_t kBase64Map[256] = {
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080040 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 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, 62, 255, 255, 255, 63,
44 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
45 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
46 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
47 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
48 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
49 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
50 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
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
62};
63
Ian Rogers13735952014-10-08 12:43:28 -070064static inline uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
65 std::vector<uint8_t> tmp;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080066 uint32_t t = 0, y = 0;
67 int g = 3;
68 for (size_t i = 0; src[i] != '\0'; ++i) {
Ian Rogers13735952014-10-08 12:43:28 -070069 uint8_t c = kBase64Map[src[i] & 0xFF];
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080070 if (c == 255) continue;
71 // the final = symbols are read and used to trim the remaining bytes
72 if (c == 254) {
73 c = 0;
74 // prevent g < 0 which would potentially allow an overflow later
75 if (--g < 0) {
76 *dst_size = 0;
77 return nullptr;
78 }
79 } else if (g != 3) {
80 // we only allow = to be at the end
81 *dst_size = 0;
82 return nullptr;
83 }
84 t = (t << 6) | c;
85 if (++y == 4) {
86 tmp.push_back((t >> 16) & 255);
87 if (g > 1) {
88 tmp.push_back((t >> 8) & 255);
89 }
90 if (g > 2) {
91 tmp.push_back(t & 255);
92 }
93 y = t = 0;
94 }
95 }
96 if (y != 0) {
97 *dst_size = 0;
98 return nullptr;
99 }
Ian Rogers13735952014-10-08 12:43:28 -0700100 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -0800101 if (dst_size != nullptr) {
102 *dst_size = tmp.size();
103 } else {
104 *dst_size = 0;
105 }
106 std::copy(tmp.begin(), tmp.end(), dst.get());
107 return dst.release();
108}
109
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700110// Although this is the same content logically as the Nested test dex,
111// the DexFileHeader test is sensitive to subtle changes in the
112// contents due to the checksum etc, so we embed the exact input here.
113//
114// class Nested {
115// class Inner {
116// }
117// }
118static const char kRawDex[] =
119 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
120 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
121 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
122 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
123 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
124 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
125 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
126 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
127 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
128 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
129 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
130 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
131 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
132 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
133 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
134 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
135
Narayan Kamath52e66502016-08-01 14:20:31 +0100136// kRawDex38 and 39 are dex'ed versions of the following Java source :
137//
138// public class Main {
139// public static void main(String[] foo) {
140// }
141// }
142//
143// The dex file was manually edited to change its dex version code to 38
144// or 39, respectively.
145static const char kRawDex38[] =
146 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
147 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
148 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
149 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
150 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
151 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
152 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
153 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
154 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
155 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
156
157static const char kRawDex39[] =
158 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
159 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
160 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
161 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
162 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
163 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
164 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
165 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
166 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
167 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
168
ganxiaolincd16d0a2016-07-18 11:21:44 +0800169static const char kRawDexZeroLength[] =
170 "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
171 "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
172 "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
173 "AA==";
174
Narayan Kamath52e66502016-08-01 14:20:31 +0100175static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700176 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700177 CHECK(base64 != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700178 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -0700179 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700180 CHECK(dex_bytes.get() != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700181
182 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700183 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700184 CHECK(file.get() != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700185 if (!file->WriteFully(dex_bytes.get(), length)) {
186 PLOG(FATAL) << "Failed to write base64 as dex file";
187 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800188 if (file->FlushCloseOrErase() != 0) {
189 PLOG(FATAL) << "Could not flush and close test file.";
190 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100191}
192
193static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
194 const char* location) {
195 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700196
197 // read dex file
198 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700199 static constexpr bool kVerifyChecksum = true;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700200 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800201 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700202 bool success = DexFile::Open(location, location, kVerifyChecksum, &error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700203 CHECK(success) << error_msg;
204 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800205 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Brian Carlstrome0948e12013-08-29 09:36:15 -0700206 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
207 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700208 return dex_file;
209}
210
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700211TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700212 ScratchFile tmp;
Ian Rogers700a4022014-05-19 16:49:03 -0700213 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700214 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700215
Brian Carlstromf615a612011-07-23 12:50:34 -0700216 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700217 // TODO: header.magic_
218 EXPECT_EQ(0x00d87910U, header.checksum_);
219 // TODO: header.signature_
220 EXPECT_EQ(904U, header.file_size_);
221 EXPECT_EQ(112U, header.header_size_);
222 EXPECT_EQ(0U, header.link_size_);
223 EXPECT_EQ(0U, header.link_off_);
224 EXPECT_EQ(15U, header.string_ids_size_);
225 EXPECT_EQ(112U, header.string_ids_off_);
226 EXPECT_EQ(7U, header.type_ids_size_);
227 EXPECT_EQ(172U, header.type_ids_off_);
228 EXPECT_EQ(2U, header.proto_ids_size_);
229 EXPECT_EQ(200U, header.proto_ids_off_);
230 EXPECT_EQ(1U, header.field_ids_size_);
231 EXPECT_EQ(224U, header.field_ids_off_);
232 EXPECT_EQ(3U, header.method_ids_size_);
233 EXPECT_EQ(232U, header.method_ids_off_);
234 EXPECT_EQ(2U, header.class_defs_size_);
235 EXPECT_EQ(256U, header.class_defs_off_);
236 EXPECT_EQ(584U, header.data_size_);
237 EXPECT_EQ(320U, header.data_off_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800238
239 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
240}
241
Narayan Kamath52e66502016-08-01 14:20:31 +0100242TEST_F(DexFileTest, Version38Accepted) {
243 ScratchFile tmp;
244 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
245 ASSERT_TRUE(raw.get() != nullptr);
246
247 const DexFile::Header& header = raw->GetHeader();
248 EXPECT_EQ(38u, header.GetVersion());
249}
250
251TEST_F(DexFileTest, Version39Rejected) {
252 ScratchFile tmp;
253 const char* location = tmp.GetFilename().c_str();
254 DecodeAndWriteDexFile(kRawDex39, location);
255
256 ScopedObjectAccess soa(Thread::Current());
257 static constexpr bool kVerifyChecksum = true;
258 std::string error_msg;
259 std::vector<std::unique_ptr<const DexFile>> dex_files;
260 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
261}
262
ganxiaolincd16d0a2016-07-18 11:21:44 +0800263TEST_F(DexFileTest, ZeroLengthDexRejected) {
264 ScratchFile tmp;
265 const char* location = tmp.GetFilename().c_str();
266 DecodeAndWriteDexFile(kRawDexZeroLength, location);
267
268 ScopedObjectAccess soa(Thread::Current());
269 static constexpr bool kVerifyChecksum = true;
270 std::string error_msg;
271 std::vector<std::unique_ptr<const DexFile>> dex_files;
272 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
273}
274
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800275TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700276 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800277 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800278 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
279}
280
281TEST_F(DexFileTest, GetChecksum) {
282 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700283 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700284 std::string error_msg;
Przemyslaw Szczepaniak5b8e6e32015-09-30 14:40:33 +0100285 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileNames()[0].c_str(), &checksum, &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700286 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800287 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700288}
289
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700290TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700291 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800292 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
293 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700294 EXPECT_EQ(2U, raw->NumClassDefs());
295
Brian Carlstromf615a612011-07-23 12:50:34 -0700296 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700297 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
298
Brian Carlstromf615a612011-07-23 12:50:34 -0700299 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700300 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700301}
302
Ian Rogersd91d6d62013-09-25 20:26:14 -0700303TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700304 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800305 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
306 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700307 EXPECT_EQ(1U, raw->NumClassDefs());
308
309 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700310 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700311
Ian Rogers13735952014-10-08 12:43:28 -0700312 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700313 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800314 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700315
Ian Rogers0571d352011-11-03 19:51:38 -0700316 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700317
Ian Rogers0571d352011-11-03 19:51:38 -0700318 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700319 {
Ian Rogers0571d352011-11-03 19:51:38 -0700320 ASSERT_EQ(1U, it.NumDirectMethods());
321 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700322 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700323 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700324 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700325 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700326 }
327
328 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700329 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700330 {
Ian Rogers0571d352011-11-03 19:51:38 -0700331 it.Next();
332 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700333
Ian Rogers0571d352011-11-03 19:51:38 -0700334 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700335 ASSERT_STREQ("m1", name);
336
Ian Rogersd91d6d62013-09-25 20:26:14 -0700337 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700338 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700339 }
340
341 {
Ian Rogers0571d352011-11-03 19:51:38 -0700342 it.Next();
343 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700344
Ian Rogers0571d352011-11-03 19:51:38 -0700345 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700346 ASSERT_STREQ("m2", name);
347
Ian Rogersd91d6d62013-09-25 20:26:14 -0700348 std::string signature(raw->GetMethodSignature(method_id).ToString());
349 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700350 }
351}
352
353TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700354 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800355 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
356 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700357 EXPECT_EQ(1U, raw->NumClassDefs());
358
Ian Rogersd91d6d62013-09-25 20:26:14 -0700359 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700360 "D", "I", "J", nullptr };
361 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700362 const char* str = strings[i];
363 const DexFile::StringId* str_id = raw->FindStringId(str);
364 const char* dex_str = raw->GetStringData(*str_id);
365 EXPECT_STREQ(dex_str, str);
366 }
367}
368
369TEST_F(DexFileTest, FindTypeId) {
370 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
371 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
372 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700373 ASSERT_TRUE(type_str_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700374 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
375 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700376 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700377 ASSERT_TRUE(type_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700378 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
379 }
380}
381
382TEST_F(DexFileTest, FindProtoId) {
383 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
384 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
385 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
386 std::vector<uint16_t> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700387 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700388 for (size_t j = 0; j < to_find_tl->Size(); j++) {
389 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
390 }
391 }
392 const DexFile::ProtoId* found =
393 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700394 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700395 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
396 }
397}
398
399TEST_F(DexFileTest, FindMethodId) {
400 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
401 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
402 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
403 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
404 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
405 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700406 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700407 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
408 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700409 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700410 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700411 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700412}
413
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800414TEST_F(DexFileTest, FindFieldId) {
415 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
416 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
417 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
418 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
419 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
420 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700421 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800422 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
423 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
424 << java_lang_dex_file_->GetStringData(name);
425 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
426 }
427}
428
Calin Juravle4e1d5792014-07-15 23:56:47 +0100429TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Andreas Gampe90e34042015-04-27 20:01:52 -0700430 ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
431 ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
432 ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
433 ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
434}
435
436TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100437 std::string dex_location_str = "/system/app/framework.jar";
438 const char* dex_location = dex_location_str.c_str();
Andreas Gampe90e34042015-04-27 20:01:52 -0700439 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
440 ASSERT_EQ("/system/app/framework.jar:classes2.dex",
441 DexFile::GetMultiDexLocation(1, dex_location));
442 ASSERT_EQ("/system/app/framework.jar:classes101.dex",
443 DexFile::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100444}
445
446TEST_F(DexFileTest, GetDexCanonicalLocation) {
447 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100448 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
449 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100450
Calin Juravle61281dc2014-08-07 11:54:36 +0100451 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Andreas Gampe90e34042015-04-27 20:01:52 -0700452 std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100453 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
454
455 std::string dex_location_sym = dex_location + "symlink";
456 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
457
458 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
459
Andreas Gampe90e34042015-04-27 20:01:52 -0700460 std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100461 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
462
463 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
464}
465
Richard Uhlere5fed032015-03-18 08:21:11 -0700466TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
467 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
468 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes2.dex"));
469 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes8.dex"));
470 EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
471 EXPECT_EQ(":classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes2.dex"));
472 EXPECT_EQ(":classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes8.dex"));
473}
474
Carl Shapiro1fb86202011-06-27 17:43:13 -0700475} // namespace art