blob: e2770d14643d96d455d54e91a29285878dd62ba5 [file] [log] [blame]
Andreas Gampedf10b322014-06-11 21:46:05 -07001/*
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 */
16
17#include "dex_file_verifier.h"
18
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070019#include <sys/mman.h>
20#include <zlib.h>
21
Andreas Gampee6215c02015-08-31 18:54:38 -070022#include <functional>
Ian Rogerse63db272014-07-15 15:36:11 -070023#include <memory>
Andreas Gampedf10b322014-06-11 21:46:05 -070024
Andreas Gampee6215c02015-08-31 18:54:38 -070025#include "base/bit_utils.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070026#include "base/macros.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070027#include "base/unix_file/fd_file.h"
Ian Rogerse63db272014-07-15 15:36:11 -070028#include "common_runtime_test.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070029#include "dex_file-inl.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080030#include "dex_file_types.h"
Andreas Gampee6215c02015-08-31 18:54:38 -070031#include "leb128.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070032#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070033#include "thread-current-inl.h"
Alex Light9c20a142016-08-23 15:05:12 -070034#include "utils.h"
Andreas Gampedf10b322014-06-11 21:46:05 -070035
36namespace art {
37
Alex Light0ed05212016-05-06 17:36:36 -070038// Make the Dex file version 37.
39static void MakeDexVersion37(DexFile* dex_file) {
40 size_t offset = OFFSETOF_MEMBER(DexFile::Header, magic_) + 6;
41 CHECK_EQ(*(dex_file->Begin() + offset), '5');
42 *(const_cast<uint8_t*>(dex_file->Begin()) + offset) = '7';
43}
44
Andreas Gampee6215c02015-08-31 18:54:38 -070045static void FixUpChecksum(uint8_t* dex_file) {
46 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(dex_file);
47 uint32_t expected_size = header->file_size_;
48 uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
49 const uint32_t non_sum = sizeof(DexFile::Header::magic_) + sizeof(DexFile::Header::checksum_);
50 const uint8_t* non_sum_ptr = dex_file + non_sum;
51 adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
52 header->checksum_ = adler_checksum;
53}
54
Andreas Gampee6215c02015-08-31 18:54:38 -070055class DexFileVerifierTest : public CommonRuntimeTest {
56 protected:
Aart Bik37d6a3b2016-06-21 18:30:10 -070057 DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
David Sehr733ddb22016-09-19 15:02:18 -070058 return new DexFile(dex_bytes, length, "tmp", 0, nullptr);
Aart Bik37d6a3b2016-06-21 18:30:10 -070059 }
60
Andreas Gampee6215c02015-08-31 18:54:38 -070061 void VerifyModification(const char* dex_file_base64_content,
62 const char* location,
Andreas Gampeca620d72016-11-08 08:09:33 -080063 const std::function<void(DexFile*)>& f,
Andreas Gampee6215c02015-08-31 18:54:38 -070064 const char* expected_error) {
Vladimir Marko59399ab2016-05-03 16:31:52 +010065 size_t length;
Alex Light9c20a142016-08-23 15:05:12 -070066 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(dex_file_base64_content, &length));
Vladimir Marko59399ab2016-05-03 16:31:52 +010067 CHECK(dex_bytes != nullptr);
68 // Note: `dex_file` will be destroyed before `dex_bytes`.
Aart Bik37d6a3b2016-06-21 18:30:10 -070069 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
Andreas Gampee6215c02015-08-31 18:54:38 -070070 f(dex_file.get());
71 FixUpChecksum(const_cast<uint8_t*>(dex_file->Begin()));
72
Aart Bik37d6a3b2016-06-21 18:30:10 -070073 static constexpr bool kVerifyChecksum = true;
Andreas Gampee6215c02015-08-31 18:54:38 -070074 std::string error_msg;
75 bool success = DexFileVerifier::Verify(dex_file.get(),
76 dex_file->Begin(),
77 dex_file->Size(),
78 location,
Aart Bik37d6a3b2016-06-21 18:30:10 -070079 kVerifyChecksum,
Andreas Gampee6215c02015-08-31 18:54:38 -070080 &error_msg);
81 if (expected_error == nullptr) {
82 EXPECT_TRUE(success) << error_msg;
83 } else {
84 EXPECT_FALSE(success) << "Expected " << expected_error;
85 if (!success) {
86 EXPECT_NE(error_msg.find(expected_error), std::string::npos) << error_msg;
87 }
88 }
89 }
Andreas Gampee6215c02015-08-31 18:54:38 -070090};
91
Richard Uhlerfbef44d2014-12-23 09:48:51 -080092static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
93 const char* location,
94 std::string* error_msg) {
Andreas Gampedf10b322014-06-11 21:46:05 -070095 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -070096 CHECK(base64 != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -070097 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -070098 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070099 CHECK(dex_bytes.get() != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -0700100
101 // write to provided file
102 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700103 CHECK(file.get() != nullptr);
Andreas Gampedf10b322014-06-11 21:46:05 -0700104 if (!file->WriteFully(dex_bytes.get(), length)) {
105 PLOG(FATAL) << "Failed to write base64 as dex file";
106 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800107 if (file->FlushCloseOrErase() != 0) {
108 PLOG(FATAL) << "Could not flush and close test file.";
109 }
Andreas Gampedf10b322014-06-11 21:46:05 -0700110 file.reset();
111
112 // read dex file
113 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800114 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700115 bool success = DexFile::Open(location, location, true, error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700116 CHECK(success) << error_msg;
117 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800118 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Andreas Gampe833a4852014-05-21 18:46:59 -0700119 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
120 EXPECT_TRUE(dex_file->IsReadOnly());
121 return dex_file;
Andreas Gampedf10b322014-06-11 21:46:05 -0700122}
123
Roland Levillain621b5ea2016-05-18 11:41:33 +0100124// To generate a base64 encoded Dex file (such as kGoodTestDex, below)
125// from Smali files, use:
126//
Ben Gruver14fc9db2017-04-28 15:30:49 -0700127// smali assemble -o classes.dex class1.smali [class2.smali ...]
Roland Levillain621b5ea2016-05-18 11:41:33 +0100128// base64 classes.dex >classes.dex.base64
129
Andreas Gampedf10b322014-06-11 21:46:05 -0700130// For reference.
131static const char kGoodTestDex[] =
132 "ZGV4CjAzNQDrVbyVkxX1HljTznNf95AglkUAhQuFtmKkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAN"
133 "AAAAcAAAAAYAAACkAAAAAgAAALwAAAABAAAA1AAAAAQAAADcAAAAAQAAAPwAAACIAQAAHAEAAFoB"
134 "AABiAQAAagEAAIEBAACVAQAAqQEAAL0BAADDAQAAzgEAANEBAADVAQAA2gEAAN8BAAABAAAAAgAA"
135 "AAMAAAAEAAAABQAAAAgAAAAIAAAABQAAAAAAAAAJAAAABQAAAFQBAAAEAAEACwAAAAAAAAAAAAAA"
136 "AAAAAAoAAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAcAAAAAAAAA8wEAAAAAAAAB"
137 "AAEAAQAAAOgBAAAEAAAAcBADAAAADgACAAAAAgAAAO0BAAAIAAAAYgAAABoBBgBuIAIAEAAOAAEA"
138 "AAADAAY8aW5pdD4ABkxUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09i"
139 "amVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AARUZXN0AAlUZXN0"
140 "LmphdmEAAVYAAlZMAANmb28AA291dAAHcHJpbnRsbgABAAcOAAMABw54AAAAAgAAgYAEnAIBCbQC"
141 "AAAADQAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAAAAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAQA"
142 "AAABAAAA1AAAAAUAAAAEAAAA3AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA"
143 "AAIgAAANAAAAWgEAAAMgAAACAAAA6AEAAAAgAAABAAAA8wEAAAAQAAABAAAABAIAAA==";
144
145TEST_F(DexFileVerifierTest, GoodDex) {
146 ScratchFile tmp;
147 std::string error_msg;
148 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex, tmp.GetFilename().c_str(),
149 &error_msg));
150 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
151}
152
Andreas Gampedf10b322014-06-11 21:46:05 -0700153TEST_F(DexFileVerifierTest, MethodId) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700154 // Class idx error.
155 VerifyModification(
156 kGoodTestDex,
157 "method_id_class_idx",
158 [](DexFile* dex_file) {
159 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
Andreas Gampea5b09a62016-11-17 15:21:22 -0800160 method_id->class_idx_ = dex::TypeIndex(0xFF);
Andreas Gampee6215c02015-08-31 18:54:38 -0700161 },
162 "could not find declaring class for direct method index 0");
163
164 // Proto idx error.
165 VerifyModification(
166 kGoodTestDex,
167 "method_id_proto_idx",
168 [](DexFile* dex_file) {
169 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
170 method_id->proto_idx_ = 0xFF;
171 },
172 "inter_method_id_item proto_idx");
173
174 // Name idx error.
175 VerifyModification(
176 kGoodTestDex,
177 "method_id_name_idx",
178 [](DexFile* dex_file) {
179 DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800180 method_id->name_idx_ = dex::StringIndex(0xFF);
Andreas Gampee6215c02015-08-31 18:54:38 -0700181 },
182 "String index not available for method flags verification");
183}
184
185// Method flags test class generated from the following smali code. The declared-synchronized
186// flags are there to enforce a 3-byte uLEB128 encoding so we don't have to relayout
187// the code, but we need to remove them before doing tests.
188//
189// .class public LMethodFlags;
190// .super Ljava/lang/Object;
191//
192// .method public static constructor <clinit>()V
193// .registers 1
194// return-void
195// .end method
196//
197// .method public constructor <init>()V
198// .registers 1
199// return-void
200// .end method
201//
202// .method private declared-synchronized foo()V
203// .registers 1
204// return-void
205// .end method
206//
207// .method public declared-synchronized bar()V
208// .registers 1
209// return-void
210// .end method
211
212static const char kMethodFlagsTestDex[] =
213 "ZGV4CjAzNQCyOQrJaDBwiIWv5MIuYKXhxlLLsQcx5SwgAgAAcAAAAHhWNBIAAAAAAAAAAJgBAAAH"
214 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAA8AQAA5AAAAOQA"
215 "AADuAAAA9gAAAAUBAAAZAQAAHAEAACEBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
216 "AAAAAAABAAAAAAAAAAUAAAAAAAAABgAAAAAAAAABAAAAAQAAAAAAAAD/////AAAAAHoBAAAAAAAA"
217 "CDxjbGluaXQ+AAY8aW5pdD4ADUxNZXRob2RGbGFnczsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgAD"
218 "YmFyAANmb28AAAAAAAAAAQAAAAAAAAAAAAAAAQAAAA4AAAABAAEAAAAAAAAAAAABAAAADgAAAAEA"
219 "AQAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAADAQCJgASsAgGBgATAAgKCgAjU"
220 "AgKBgAjoAgAACwAAAAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAADAAAAjAAAAAMAAAABAAAA"
221 "mAAAAAUAAAAEAAAApAAAAAYAAAABAAAAxAAAAAIgAAAHAAAA5AAAAAMQAAABAAAAKAEAAAEgAAAE"
222 "AAAALAEAAAAgAAABAAAAegEAAAAQAAABAAAAmAEAAA==";
223
224// Find the method data for the first method with the given name (from class 0). Note: the pointer
225// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
226// delta.
Vladimir Marko59399ab2016-05-03 16:31:52 +0100227static const uint8_t* FindMethodData(const DexFile* dex_file,
228 const char* name,
229 /*out*/ uint32_t* method_idx = nullptr) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700230 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
231 const uint8_t* class_data = dex_file->GetClassData(class_def);
232
233 ClassDataItemIterator it(*dex_file, class_data);
234
235 const uint8_t* trailing = class_data;
236 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
237 // element has already been loaded into the iterator.
238 DecodeUnsignedLeb128(&trailing);
239 DecodeUnsignedLeb128(&trailing);
240 DecodeUnsignedLeb128(&trailing);
241 DecodeUnsignedLeb128(&trailing);
242
243 // Skip all fields.
244 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
245 trailing = it.DataPointer();
246 it.Next();
Andreas Gampedf10b322014-06-11 21:46:05 -0700247 }
248
Andreas Gampee6215c02015-08-31 18:54:38 -0700249 while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
250 uint32_t method_index = it.GetMemberIndex();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800251 dex::StringIndex name_index = dex_file->GetMethodId(method_index).name_idx_;
Andreas Gampee6215c02015-08-31 18:54:38 -0700252 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
253 const char* str = dex_file->GetStringData(string_id);
254 if (strcmp(name, str) == 0) {
Vladimir Marko59399ab2016-05-03 16:31:52 +0100255 if (method_idx != nullptr) {
256 *method_idx = method_index;
257 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700258 DecodeUnsignedLeb128(&trailing);
259 return trailing;
260 }
261
262 trailing = it.DataPointer();
263 it.Next();
Andreas Gampedf10b322014-06-11 21:46:05 -0700264 }
265
Andreas Gampee6215c02015-08-31 18:54:38 -0700266 return nullptr;
267}
268
269// Set the method flags to the given value.
270static void SetMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
271 uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
272 CHECK(method_flags_ptr != nullptr) << method;
273
274 // Unroll this, as we only have three bytes, anyways.
275 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
276 *(method_flags_ptr++) = (base1 | 0x80);
277 mask >>= 7;
278
279 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
280 *(method_flags_ptr++) = (base2 | 0x80);
281 mask >>= 7;
282
283 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
284 *method_flags_ptr = base3;
285}
286
287static uint32_t GetMethodFlags(DexFile* dex_file, const char* method) {
288 const uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
289 CHECK(method_flags_ptr != nullptr) << method;
290 return DecodeUnsignedLeb128(&method_flags_ptr);
291}
292
293// Apply the given mask to method flags.
294static void ApplyMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
295 uint32_t value = GetMethodFlags(dex_file, method);
296 value &= mask;
297 SetMethodFlags(dex_file, method, value);
298}
299
300// Apply the given mask to method flags.
301static void OrMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
302 uint32_t value = GetMethodFlags(dex_file, method);
303 value |= mask;
304 SetMethodFlags(dex_file, method, value);
305}
306
307// Set code_off to 0 for the method.
308static void RemoveCode(DexFile* dex_file, const char* method) {
309 const uint8_t* ptr = FindMethodData(dex_file, method);
310 // Next is flags, pass.
311 DecodeUnsignedLeb128(&ptr);
312
313 // Figure out how many bytes the code_off is.
314 const uint8_t* tmp = ptr;
315 DecodeUnsignedLeb128(&tmp);
316 size_t bytes = tmp - ptr;
317
318 uint8_t* mod = const_cast<uint8_t*>(ptr);
319 for (size_t i = 1; i < bytes; ++i) {
320 *(mod++) = 0x80;
Andreas Gampedf10b322014-06-11 21:46:05 -0700321 }
Andreas Gampee6215c02015-08-31 18:54:38 -0700322 *mod = 0x00;
323}
324
325TEST_F(DexFileVerifierTest, MethodAccessFlagsBase) {
326 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
327 VerifyModification(
328 kMethodFlagsTestDex,
329 "method_flags_ok",
330 [](DexFile* dex_file) {
331 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
332 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
333 },
334 nullptr);
335}
336
337TEST_F(DexFileVerifierTest, MethodAccessFlagsConstructors) {
338 // Make sure we still accept constructors without their flags.
339 VerifyModification(
340 kMethodFlagsTestDex,
341 "method_flags_missing_constructor_tag_ok",
342 [](DexFile* dex_file) {
343 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
344 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
345
346 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccConstructor);
347 ApplyMaskToMethodFlags(dex_file, "<clinit>", ~kAccConstructor);
348 },
349 nullptr);
350
351 constexpr const char* kConstructors[] = { "<clinit>", "<init>"};
352 for (size_t i = 0; i < 2; ++i) {
353 // Constructor with code marked native.
354 VerifyModification(
355 kMethodFlagsTestDex,
356 "method_flags_constructor_native",
357 [&](DexFile* dex_file) {
358 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
359 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
360
361 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
362 },
363 "has code, but is marked native or abstract");
364 // Constructor with code marked abstract.
365 VerifyModification(
366 kMethodFlagsTestDex,
367 "method_flags_constructor_abstract",
368 [&](DexFile* dex_file) {
369 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
370 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
371
372 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
373 },
374 "has code, but is marked native or abstract");
375 // Constructor as-is without code.
376 VerifyModification(
377 kMethodFlagsTestDex,
378 "method_flags_constructor_nocode",
379 [&](DexFile* dex_file) {
380 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
381 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
382
383 RemoveCode(dex_file, kConstructors[i]);
384 },
385 "has no code, but is not marked native or abstract");
386 // Constructor without code marked native.
387 VerifyModification(
388 kMethodFlagsTestDex,
389 "method_flags_constructor_native_nocode",
390 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700391 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700392 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
393 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
394
395 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
396 RemoveCode(dex_file, kConstructors[i]);
397 },
398 "must not be abstract or native");
399 // Constructor without code marked abstract.
400 VerifyModification(
401 kMethodFlagsTestDex,
402 "method_flags_constructor_abstract_nocode",
403 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700404 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700405 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
406 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
407
408 OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
409 RemoveCode(dex_file, kConstructors[i]);
410 },
411 "must not be abstract or native");
412 }
413 // <init> may only have (modulo ignored):
414 // kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic
415 static constexpr uint32_t kInitAllowed[] = {
416 0,
417 kAccPrivate,
418 kAccProtected,
419 kAccPublic,
420 kAccStrict,
421 kAccVarargs,
422 kAccSynthetic
423 };
424 for (size_t i = 0; i < arraysize(kInitAllowed); ++i) {
425 VerifyModification(
426 kMethodFlagsTestDex,
427 "init_allowed_flags",
428 [&](DexFile* dex_file) {
429 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
430 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
431
432 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
433 OrMaskToMethodFlags(dex_file, "<init>", kInitAllowed[i]);
434 },
435 nullptr);
436 }
437 // Only one of public-private-protected.
438 for (size_t i = 1; i < 8; ++i) {
439 if (POPCOUNT(i) < 2) {
440 continue;
441 }
442 // Technically the flags match, but just be defensive here.
443 uint32_t mask = ((i & 1) != 0 ? kAccPrivate : 0) |
444 ((i & 2) != 0 ? kAccProtected : 0) |
445 ((i & 4) != 0 ? kAccPublic : 0);
446 VerifyModification(
447 kMethodFlagsTestDex,
448 "init_one_of_ppp",
449 [&](DexFile* dex_file) {
450 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
451 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
452
453 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
454 OrMaskToMethodFlags(dex_file, "<init>", mask);
455 },
456 "Method may have only one of public/protected/private");
457 }
458 // <init> doesn't allow
459 // kAccStatic | kAccFinal | kAccSynchronized | kAccBridge
460 // Need to handle static separately as it has its own error message.
461 VerifyModification(
462 kMethodFlagsTestDex,
463 "init_not_allowed_flags",
464 [&](DexFile* dex_file) {
Alex Light0ed05212016-05-06 17:36:36 -0700465 MakeDexVersion37(dex_file);
Andreas Gampee6215c02015-08-31 18:54:38 -0700466 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
467 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
468
469 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
470 OrMaskToMethodFlags(dex_file, "<init>", kAccStatic);
471 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800472 "Constructor 1(LMethodFlags;.<init>) is not flagged correctly wrt/ static");
Andreas Gampee6215c02015-08-31 18:54:38 -0700473 static constexpr uint32_t kInitNotAllowed[] = {
474 kAccFinal,
475 kAccSynchronized,
476 kAccBridge
477 };
478 for (size_t i = 0; i < arraysize(kInitNotAllowed); ++i) {
479 VerifyModification(
480 kMethodFlagsTestDex,
481 "init_not_allowed_flags",
482 [&](DexFile* dex_file) {
483 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
484 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
485
486 ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
487 OrMaskToMethodFlags(dex_file, "<init>", kInitNotAllowed[i]);
488 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800489 "Constructor 1(LMethodFlags;.<init>) flagged inappropriately");
Andreas Gampee6215c02015-08-31 18:54:38 -0700490 }
491}
492
493TEST_F(DexFileVerifierTest, MethodAccessFlagsMethods) {
494 constexpr const char* kMethods[] = { "foo", "bar"};
495 for (size_t i = 0; i < arraysize(kMethods); ++i) {
496 // Make sure we reject non-constructors marked as constructors.
497 VerifyModification(
498 kMethodFlagsTestDex,
499 "method_flags_non_constructor",
500 [&](DexFile* dex_file) {
501 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
502 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
503
504 OrMaskToMethodFlags(dex_file, kMethods[i], kAccConstructor);
505 },
506 "is marked constructor, but doesn't match name");
507
508 VerifyModification(
509 kMethodFlagsTestDex,
510 "method_flags_native_with_code",
511 [&](DexFile* dex_file) {
512 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
513 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
514
515 OrMaskToMethodFlags(dex_file, kMethods[i], kAccNative);
516 },
517 "has code, but is marked native or abstract");
518
519 VerifyModification(
520 kMethodFlagsTestDex,
521 "method_flags_abstract_with_code",
522 [&](DexFile* dex_file) {
523 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
524 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
525
526 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract);
527 },
528 "has code, but is marked native or abstract");
529
530 VerifyModification(
531 kMethodFlagsTestDex,
532 "method_flags_non_abstract_native_no_code",
533 [&](DexFile* dex_file) {
534 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
535 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
536
537 RemoveCode(dex_file, kMethods[i]);
538 },
539 "has no code, but is not marked native or abstract");
540
541 // Abstract methods may not have the following flags.
542 constexpr uint32_t kAbstractDisallowed[] = {
543 kAccPrivate,
544 kAccStatic,
545 kAccFinal,
546 kAccNative,
547 kAccStrict,
548 kAccSynchronized,
549 };
550 for (size_t j = 0; j < arraysize(kAbstractDisallowed); ++j) {
551 VerifyModification(
552 kMethodFlagsTestDex,
553 "method_flags_abstract_and_disallowed_no_code",
554 [&](DexFile* dex_file) {
555 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
556 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
557
558 RemoveCode(dex_file, kMethods[i]);
559
560 // Can't check private and static with foo, as it's in the virtual list and gives a
561 // different error.
562 if (((GetMethodFlags(dex_file, kMethods[i]) & kAccPublic) != 0) &&
563 ((kAbstractDisallowed[j] & (kAccPrivate | kAccStatic)) != 0)) {
564 // Use another breaking flag.
565 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAccFinal);
566 } else {
567 OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAbstractDisallowed[j]);
568 }
569 },
570 "has disallowed access flags");
571 }
572
573 // Only one of public-private-protected.
574 for (size_t j = 1; j < 8; ++j) {
575 if (POPCOUNT(j) < 2) {
576 continue;
577 }
578 // Technically the flags match, but just be defensive here.
579 uint32_t mask = ((j & 1) != 0 ? kAccPrivate : 0) |
580 ((j & 2) != 0 ? kAccProtected : 0) |
581 ((j & 4) != 0 ? kAccPublic : 0);
582 VerifyModification(
583 kMethodFlagsTestDex,
584 "method_flags_one_of_ppp",
585 [&](DexFile* dex_file) {
586 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
587 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
588
589 ApplyMaskToMethodFlags(dex_file, kMethods[i], ~kAccPublic);
590 OrMaskToMethodFlags(dex_file, kMethods[i], mask);
591 },
592 "Method may have only one of public/protected/private");
593 }
594 }
595}
596
597TEST_F(DexFileVerifierTest, MethodAccessFlagsIgnoredOK) {
598 constexpr const char* kMethods[] = { "<clinit>", "<init>", "foo", "bar"};
599 for (size_t i = 0; i < arraysize(kMethods); ++i) {
600 // All interesting method flags, other flags are to be ignored.
601 constexpr uint32_t kAllMethodFlags =
602 kAccPublic |
603 kAccPrivate |
604 kAccProtected |
605 kAccStatic |
606 kAccFinal |
607 kAccSynchronized |
608 kAccBridge |
609 kAccVarargs |
610 kAccNative |
611 kAccAbstract |
612 kAccStrict |
613 kAccSynthetic;
614 constexpr uint32_t kIgnoredMask = ~kAllMethodFlags & 0xFFFF;
615 VerifyModification(
616 kMethodFlagsTestDex,
617 "method_flags_ignored",
618 [&](DexFile* dex_file) {
619 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
620 ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
621
622 OrMaskToMethodFlags(dex_file, kMethods[i], kIgnoredMask);
623 },
624 nullptr);
625 }
626}
627
Vladimir Marko59399ab2016-05-03 16:31:52 +0100628TEST_F(DexFileVerifierTest, B28552165) {
629 // Regression test for bad error string retrieval in different situations.
630 // Using invalid access flags to trigger the error.
631 VerifyModification(
632 kMethodFlagsTestDex,
633 "b28552165",
634 [](DexFile* dex_file) {
635 OrMaskToMethodFlags(dex_file, "foo", kAccPublic | kAccProtected);
Vladimir Marko59399ab2016-05-03 16:31:52 +0100636 },
Orion Hodson6c4921b2016-09-21 15:41:06 +0100637 "Method may have only one of public/protected/private, LMethodFlags;.foo");
Vladimir Marko59399ab2016-05-03 16:31:52 +0100638}
639
Andreas Gampee6215c02015-08-31 18:54:38 -0700640// Set of dex files for interface method tests. As it's not as easy to mutate method names, it's
641// just easier to break up bad cases.
642
Andreas Gampee6215c02015-08-31 18:54:38 -0700643// Standard interface. Use declared-synchronized again for 3B encoding.
644//
645// .class public interface LInterfaceMethodFlags;
646// .super Ljava/lang/Object;
647//
648// .method public static constructor <clinit>()V
649// .registers 1
650// return-void
651// .end method
652//
653// .method public abstract declared-synchronized foo()V
654// .end method
655static const char kMethodFlagsInterface[] =
656 "ZGV4CjAzNQCOM0odZ5bws1d9GSmumXaK5iE/7XxFpOm8AQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
657 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADwAAAAzAAAAMwA"
658 "AADWAAAA7gAAAAIBAAAFAQAAAQAAAAIAAAADAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAA"
659 "AAAAAAABAgAAAQAAAAAAAAD/////AAAAACIBAAAAAAAACDxjbGluaXQ+ABZMSW50ZXJmYWNlTWV0"
660 "aG9kRmxhZ3M7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAA2ZvbwAAAAAAAAABAAAAAAAAAAAAAAAB"
661 "AAAADgAAAAEBAImABJACAYGICAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAMA"
662 "AACEAAAAAwAAAAEAAACQAAAABQAAAAIAAACcAAAABgAAAAEAAACsAAAAAiAAAAUAAADMAAAAAxAA"
663 "AAEAAAAMAQAAASAAAAEAAAAQAQAAACAAAAEAAAAiAQAAABAAAAEAAAA0AQAA";
664
665// To simplify generation of interesting "sub-states" of src_value, allow a "simple" mask to apply
666// to a src_value, such that mask bit 0 applies to the lowest set bit in src_value, and so on.
667static uint32_t ApplyMaskShifted(uint32_t src_value, uint32_t mask) {
668 uint32_t result = 0;
669 uint32_t mask_index = 0;
670 while (src_value != 0) {
671 uint32_t index = CTZ(src_value);
672 if (((src_value & (1 << index)) != 0) &&
673 ((mask & (1 << mask_index)) != 0)) {
674 result |= (1 << index);
675 }
676 src_value &= ~(1 << index);
677 mask_index++;
678 }
679 return result;
680}
681
682TEST_F(DexFileVerifierTest, MethodAccessFlagsInterfaces) {
Andreas Gampee6215c02015-08-31 18:54:38 -0700683 VerifyModification(
684 kMethodFlagsInterface,
685 "method_flags_interface_ok",
686 [](DexFile* dex_file) {
687 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
688 },
689 nullptr);
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700690 VerifyModification(
691 kMethodFlagsInterface,
692 "method_flags_interface_ok37",
693 [](DexFile* dex_file) {
694 MakeDexVersion37(dex_file);
695 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
696 },
697 nullptr);
Andreas Gampee6215c02015-08-31 18:54:38 -0700698
699 VerifyModification(
700 kMethodFlagsInterface,
701 "method_flags_interface_non_public",
702 [](DexFile* dex_file) {
703 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
704
705 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
706 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700707 nullptr); // Should be allowed in older dex versions for backwards compatibility.
708 VerifyModification(
709 kMethodFlagsInterface,
710 "method_flags_interface_non_public",
711 [](DexFile* dex_file) {
712 MakeDexVersion37(dex_file);
713 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
714
715 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
716 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700717 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700718
Andreas Gampee6215c02015-08-31 18:54:38 -0700719 VerifyModification(
720 kMethodFlagsInterface,
721 "method_flags_interface_non_abstract",
722 [](DexFile* dex_file) {
723 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
724
725 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccAbstract);
726 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800727 "Method 1(LInterfaceMethodFlags;.foo) has no code, but is not marked native or abstract");
Andreas Gampee6215c02015-08-31 18:54:38 -0700728
729 VerifyModification(
730 kMethodFlagsInterface,
731 "method_flags_interface_static",
732 [](DexFile* dex_file) {
733 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
734
735 OrMaskToMethodFlags(dex_file, "foo", kAccStatic);
736 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800737 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
Andreas Gampee6215c02015-08-31 18:54:38 -0700738 VerifyModification(
739 kMethodFlagsInterface,
740 "method_flags_interface_private",
741 [](DexFile* dex_file) {
742 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
743
744 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
745 OrMaskToMethodFlags(dex_file, "foo", kAccPrivate);
746 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800747 "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
Andreas Gampee6215c02015-08-31 18:54:38 -0700748
749 VerifyModification(
750 kMethodFlagsInterface,
751 "method_flags_interface_non_public",
752 [](DexFile* dex_file) {
753 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
754
755 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
756 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700757 nullptr); // Should be allowed in older dex versions for backwards compatibility.
758 VerifyModification(
759 kMethodFlagsInterface,
760 "method_flags_interface_non_public",
761 [](DexFile* dex_file) {
762 MakeDexVersion37(dex_file);
763 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
764
765 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
766 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700767 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700768
Andreas Gampee6215c02015-08-31 18:54:38 -0700769 VerifyModification(
770 kMethodFlagsInterface,
771 "method_flags_interface_protected",
772 [](DexFile* dex_file) {
773 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
774
775 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
776 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
777 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700778 nullptr); // Should be allowed in older dex versions for backwards compatibility.
779 VerifyModification(
780 kMethodFlagsInterface,
781 "method_flags_interface_protected",
782 [](DexFile* dex_file) {
783 MakeDexVersion37(dex_file);
784 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
785
786 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
787 OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
788 },
Alex Lightd7c10c22016-03-31 10:03:07 -0700789 "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");
Andreas Gampee6215c02015-08-31 18:54:38 -0700790
791 constexpr uint32_t kAllMethodFlags =
792 kAccPublic |
793 kAccPrivate |
794 kAccProtected |
795 kAccStatic |
796 kAccFinal |
797 kAccSynchronized |
798 kAccBridge |
799 kAccVarargs |
800 kAccNative |
801 kAccAbstract |
802 kAccStrict |
803 kAccSynthetic;
804 constexpr uint32_t kInterfaceMethodFlags =
805 kAccPublic | kAccAbstract | kAccVarargs | kAccBridge | kAccSynthetic;
806 constexpr uint32_t kInterfaceDisallowed = kAllMethodFlags &
807 ~kInterfaceMethodFlags &
808 // Already tested, needed to be separate.
809 ~kAccStatic &
810 ~kAccPrivate &
811 ~kAccProtected;
812 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
813
814 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
815 for (uint32_t i = 1; i < (1u << bits); ++i) {
816 VerifyModification(
817 kMethodFlagsInterface,
818 "method_flags_interface_non_abstract",
819 [&](DexFile* dex_file) {
820 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
821
822 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
823 if ((mask & kAccProtected) != 0) {
824 mask &= ~kAccProtected;
825 ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
826 }
827 OrMaskToMethodFlags(dex_file, "foo", mask);
828 },
Andreas Gampec9f0ba12016-02-09 09:21:04 -0800829 "Abstract method 1(LInterfaceMethodFlags;.foo) has disallowed access flags");
Andreas Gampee6215c02015-08-31 18:54:38 -0700830 }
831}
832
833///////////////////////////////////////////////////////////////////
834
835// Field flags.
836
837// Find the method data for the first method with the given name (from class 0). Note: the pointer
838// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
839// delta.
840static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
841 const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
842 const uint8_t* class_data = dex_file->GetClassData(class_def);
843
844 ClassDataItemIterator it(*dex_file, class_data);
845
846 const uint8_t* trailing = class_data;
847 // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
848 // element has already been loaded into the iterator.
849 DecodeUnsignedLeb128(&trailing);
850 DecodeUnsignedLeb128(&trailing);
851 DecodeUnsignedLeb128(&trailing);
852 DecodeUnsignedLeb128(&trailing);
853
854 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
855 uint32_t field_index = it.GetMemberIndex();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800856 dex::StringIndex name_index = dex_file->GetFieldId(field_index).name_idx_;
Andreas Gampee6215c02015-08-31 18:54:38 -0700857 const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
858 const char* str = dex_file->GetStringData(string_id);
859 if (strcmp(name, str) == 0) {
860 DecodeUnsignedLeb128(&trailing);
861 return trailing;
862 }
863
864 trailing = it.DataPointer();
865 it.Next();
866 }
867
868 return nullptr;
869}
870
871// Set the method flags to the given value.
872static void SetFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
873 uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
874 CHECK(field_flags_ptr != nullptr) << field;
875
876 // Unroll this, as we only have three bytes, anyways.
877 uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
878 *(field_flags_ptr++) = (base1 | 0x80);
879 mask >>= 7;
880
881 uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
882 *(field_flags_ptr++) = (base2 | 0x80);
883 mask >>= 7;
884
885 uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
886 *field_flags_ptr = base3;
887}
888
889static uint32_t GetFieldFlags(DexFile* dex_file, const char* field) {
890 const uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
891 CHECK(field_flags_ptr != nullptr) << field;
892 return DecodeUnsignedLeb128(&field_flags_ptr);
893}
894
895// Apply the given mask to method flags.
896static void ApplyMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
897 uint32_t value = GetFieldFlags(dex_file, field);
898 value &= mask;
899 SetFieldFlags(dex_file, field, value);
900}
901
902// Apply the given mask to method flags.
903static void OrMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
904 uint32_t value = GetFieldFlags(dex_file, field);
905 value |= mask;
906 SetFieldFlags(dex_file, field, value);
907}
908
909// Standard class. Use declared-synchronized again for 3B encoding.
910//
911// .class public LFieldFlags;
912// .super Ljava/lang/Object;
913//
914// .field declared-synchronized public foo:I
915//
916// .field declared-synchronized public static bar:I
917
918static const char kFieldFlagsTestDex[] =
919 "ZGV4CjAzNQBtLw7hydbfv4TdXidZyzAB70W7w3vnYJRwAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAF"
920 "AAAAcAAAAAMAAACEAAAAAAAAAAAAAAACAAAAkAAAAAAAAAAAAAAAAQAAAKAAAACwAAAAwAAAAMAA"
921 "AADDAAAA0QAAAOUAAADqAAAAAAAAAAEAAAACAAAAAQAAAAMAAAABAAAABAAAAAEAAAABAAAAAgAA"
922 "AAAAAAD/////AAAAAPQAAAAAAAAAAUkADExGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7"
923 "AANiYXIAA2ZvbwAAAAAAAAEBAAAAiYAIAYGACAkAAAAAAAAAAQAAAAAAAAABAAAABQAAAHAAAAAC"
924 "AAAAAwAAAIQAAAAEAAAAAgAAAJAAAAAGAAAAAQAAAKAAAAACIAAABQAAAMAAAAADEAAAAQAAAPAA"
925 "AAAAIAAAAQAAAPQAAAAAEAAAAQAAAAABAAA=";
926
927TEST_F(DexFileVerifierTest, FieldAccessFlagsBase) {
928 // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
929 VerifyModification(
930 kFieldFlagsTestDex,
931 "field_flags_ok",
932 [](DexFile* dex_file) {
933 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
934 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
935 },
936 nullptr);
937}
938
939TEST_F(DexFileVerifierTest, FieldAccessFlagsWrongList) {
940 // Mark the field so that it should appear in the opposite list (instance vs static).
941 VerifyModification(
942 kFieldFlagsTestDex,
943 "field_flags_wrong_list",
944 [](DexFile* dex_file) {
945 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
946 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
947
948 OrMaskToFieldFlags(dex_file, "foo", kAccStatic);
949 },
950 "Static/instance field not in expected list");
951 VerifyModification(
952 kFieldFlagsTestDex,
953 "field_flags_wrong_list",
954 [](DexFile* dex_file) {
955 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
956 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
957
958 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccStatic);
959 },
960 "Static/instance field not in expected list");
961}
962
963TEST_F(DexFileVerifierTest, FieldAccessFlagsPPP) {
964 static const char* kFields[] = { "foo", "bar" };
965 for (size_t i = 0; i < arraysize(kFields); ++i) {
966 // Should be OK to remove public.
967 VerifyModification(
968 kFieldFlagsTestDex,
969 "field_flags_non_public",
970 [&](DexFile* dex_file) {
971 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
972 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
973
974 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
975 },
976 nullptr);
977 constexpr uint32_t kAccFlags = kAccPublic | kAccPrivate | kAccProtected;
978 uint32_t bits = POPCOUNT(kAccFlags);
979 for (uint32_t j = 1; j < (1u << bits); ++j) {
980 if (POPCOUNT(j) < 2) {
981 continue;
982 }
983 VerifyModification(
984 kFieldFlagsTestDex,
985 "field_flags_ppp",
986 [&](DexFile* dex_file) {
987 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
988 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
989
990 ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
991 uint32_t mask = ApplyMaskShifted(kAccFlags, j);
992 OrMaskToFieldFlags(dex_file, kFields[i], mask);
993 },
994 "Field may have only one of public/protected/private");
995 }
996 }
997}
998
999TEST_F(DexFileVerifierTest, FieldAccessFlagsIgnoredOK) {
1000 constexpr const char* kFields[] = { "foo", "bar"};
1001 for (size_t i = 0; i < arraysize(kFields); ++i) {
1002 // All interesting method flags, other flags are to be ignored.
1003 constexpr uint32_t kAllFieldFlags =
1004 kAccPublic |
1005 kAccPrivate |
1006 kAccProtected |
1007 kAccStatic |
1008 kAccFinal |
1009 kAccVolatile |
1010 kAccTransient |
1011 kAccSynthetic |
1012 kAccEnum;
1013 constexpr uint32_t kIgnoredMask = ~kAllFieldFlags & 0xFFFF;
1014 VerifyModification(
1015 kFieldFlagsTestDex,
1016 "field_flags_ignored",
1017 [&](DexFile* dex_file) {
1018 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1019 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1020
1021 OrMaskToFieldFlags(dex_file, kFields[i], kIgnoredMask);
1022 },
1023 nullptr);
1024 }
1025}
1026
1027TEST_F(DexFileVerifierTest, FieldAccessFlagsVolatileFinal) {
1028 constexpr const char* kFields[] = { "foo", "bar"};
1029 for (size_t i = 0; i < arraysize(kFields); ++i) {
1030 VerifyModification(
1031 kFieldFlagsTestDex,
1032 "field_flags_final_and_volatile",
1033 [&](DexFile* dex_file) {
1034 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1035 ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
1036
1037 OrMaskToFieldFlags(dex_file, kFields[i], kAccVolatile | kAccFinal);
1038 },
1039 "Fields may not be volatile and final");
1040 }
1041}
1042
1043// Standard interface. Needs to be separate from class as interfaces do not allow instance fields.
1044// Use declared-synchronized again for 3B encoding.
1045//
1046// .class public interface LInterfaceFieldFlags;
1047// .super Ljava/lang/Object;
1048//
1049// .field declared-synchronized public static final foo:I
1050
1051static const char kFieldFlagsInterfaceTestDex[] =
1052 "ZGV4CjAzNQCVMHfEimR1zZPk6hl6O9GPAYqkl3u0umFkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1053 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1054 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1055 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1056 "b28AAAAAAAABAAAAAJmACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1057 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1058 "AAAAEAAAAQAAAPQAAAA=";
1059
1060TEST_F(DexFileVerifierTest, FieldAccessFlagsInterface) {
1061 VerifyModification(
1062 kFieldFlagsInterfaceTestDex,
1063 "field_flags_interface",
1064 [](DexFile* dex_file) {
1065 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1066 },
1067 nullptr);
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001068 VerifyModification(
1069 kFieldFlagsInterfaceTestDex,
1070 "field_flags_interface",
1071 [](DexFile* dex_file) {
1072 MakeDexVersion37(dex_file);
1073 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1074 },
1075 nullptr);
Andreas Gampee6215c02015-08-31 18:54:38 -07001076
1077 VerifyModification(
1078 kFieldFlagsInterfaceTestDex,
1079 "field_flags_interface_non_public",
1080 [](DexFile* dex_file) {
1081 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1082
1083 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1084 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001085 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1086 VerifyModification(
1087 kFieldFlagsInterfaceTestDex,
1088 "field_flags_interface_non_public",
1089 [](DexFile* dex_file) {
1090 MakeDexVersion37(dex_file);
1091 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1092
1093 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1094 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001095 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001096
Andreas Gampee6215c02015-08-31 18:54:38 -07001097 VerifyModification(
1098 kFieldFlagsInterfaceTestDex,
1099 "field_flags_interface_non_final",
1100 [](DexFile* dex_file) {
1101 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1102
1103 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1104 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001105 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1106 VerifyModification(
1107 kFieldFlagsInterfaceTestDex,
1108 "field_flags_interface_non_final",
1109 [](DexFile* dex_file) {
1110 MakeDexVersion37(dex_file);
1111 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1112
1113 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
1114 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001115 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001116
Andreas Gampee6215c02015-08-31 18:54:38 -07001117 VerifyModification(
1118 kFieldFlagsInterfaceTestDex,
1119 "field_flags_interface_protected",
1120 [](DexFile* dex_file) {
1121 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1122
1123 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1124 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1125 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001126 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1127 VerifyModification(
1128 kFieldFlagsInterfaceTestDex,
1129 "field_flags_interface_protected",
1130 [](DexFile* dex_file) {
1131 MakeDexVersion37(dex_file);
1132 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1133
1134 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1135 OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
1136 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001137 "Interface field is not public final static");
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001138
Andreas Gampee6215c02015-08-31 18:54:38 -07001139 VerifyModification(
1140 kFieldFlagsInterfaceTestDex,
1141 "field_flags_interface_private",
1142 [](DexFile* dex_file) {
1143 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1144
1145 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1146 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1147 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001148 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1149 VerifyModification(
1150 kFieldFlagsInterfaceTestDex,
1151 "field_flags_interface_private",
1152 [](DexFile* dex_file) {
1153 MakeDexVersion37(dex_file);
1154 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1155
1156 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1157 OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
1158 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001159 "Interface field is not public final static");
1160
1161 VerifyModification(
1162 kFieldFlagsInterfaceTestDex,
1163 "field_flags_interface_synthetic",
1164 [](DexFile* dex_file) {
1165 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1166
1167 OrMaskToFieldFlags(dex_file, "foo", kAccSynthetic);
1168 },
1169 nullptr);
1170
1171 constexpr uint32_t kAllFieldFlags =
1172 kAccPublic |
1173 kAccPrivate |
1174 kAccProtected |
1175 kAccStatic |
1176 kAccFinal |
1177 kAccVolatile |
1178 kAccTransient |
1179 kAccSynthetic |
1180 kAccEnum;
1181 constexpr uint32_t kInterfaceFieldFlags = kAccPublic | kAccStatic | kAccFinal | kAccSynthetic;
1182 constexpr uint32_t kInterfaceDisallowed = kAllFieldFlags &
1183 ~kInterfaceFieldFlags &
1184 ~kAccProtected &
1185 ~kAccPrivate;
1186 static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");
1187
1188 uint32_t bits = POPCOUNT(kInterfaceDisallowed);
1189 for (uint32_t i = 1; i < (1u << bits); ++i) {
1190 VerifyModification(
1191 kFieldFlagsInterfaceTestDex,
1192 "field_flags_interface_disallowed",
1193 [&](DexFile* dex_file) {
1194 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1195
1196 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1197 if ((mask & kAccProtected) != 0) {
1198 mask &= ~kAccProtected;
1199 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1200 }
1201 OrMaskToFieldFlags(dex_file, "foo", mask);
1202 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001203 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1204 VerifyModification(
1205 kFieldFlagsInterfaceTestDex,
1206 "field_flags_interface_disallowed",
1207 [&](DexFile* dex_file) {
1208 MakeDexVersion37(dex_file);
1209 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1210
1211 uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
1212 if ((mask & kAccProtected) != 0) {
1213 mask &= ~kAccProtected;
1214 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
1215 }
1216 OrMaskToFieldFlags(dex_file, "foo", mask);
1217 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001218 "Interface field has disallowed flag");
1219 }
1220}
1221
1222// Standard bad interface. Needs to be separate from class as interfaces do not allow instance
1223// fields. Use declared-synchronized again for 3B encoding.
1224//
1225// .class public interface LInterfaceFieldFlags;
1226// .super Ljava/lang/Object;
1227//
1228// .field declared-synchronized public final foo:I
1229
1230static const char kFieldFlagsInterfaceBadTestDex[] =
1231 "ZGV4CjAzNQByMUnqYKHBkUpvvNp+9CnZ2VyDkKnRN6VkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
1232 "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
1233 "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
1234 "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
1235 "b28AAAAAAAAAAQAAAJGACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
1236 "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
1237 "AAAAEAAAAQAAAPQAAAA=";
1238
1239TEST_F(DexFileVerifierTest, FieldAccessFlagsInterfaceNonStatic) {
1240 VerifyModification(
1241 kFieldFlagsInterfaceBadTestDex,
1242 "field_flags_interface_non_static",
1243 [](DexFile* dex_file) {
1244 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1245 },
Andreas Gampe76ed99d2016-03-28 18:31:29 -07001246 nullptr); // Should be allowed in older dex versions for backwards compatibility.
1247 VerifyModification(
1248 kFieldFlagsInterfaceBadTestDex,
1249 "field_flags_interface_non_static",
1250 [](DexFile* dex_file) {
1251 MakeDexVersion37(dex_file);
1252 ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
1253 },
Andreas Gampee6215c02015-08-31 18:54:38 -07001254 "Interface field is not public final static");
Andreas Gampedf10b322014-06-11 21:46:05 -07001255}
1256
Logan Chiendd3208d2015-04-19 23:27:52 +08001257// Generated from:
1258//
1259// .class public LTest;
1260// .super Ljava/lang/Object;
1261// .source "Test.java"
1262//
1263// .method public constructor <init>()V
1264// .registers 1
1265//
1266// .prologue
1267// .line 1
1268// invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1269//
1270// return-void
1271// .end method
1272//
1273// .method public static main()V
1274// .registers 2
1275//
1276// const-string v0, "a"
1277// const-string v0, "b"
1278// const-string v0, "c"
1279// const-string v0, "d"
1280// const-string v0, "e"
1281// const-string v0, "f"
1282// const-string v0, "g"
1283// const-string v0, "h"
1284// const-string v0, "i"
1285// const-string v0, "j"
1286// const-string v0, "k"
1287//
1288// .local v1, "local_var":Ljava/lang/String;
1289// const-string v1, "test"
1290// .end method
1291
1292static const char kDebugInfoTestDex[] =
1293 "ZGV4CjAzNQCHRkHix2eIMQgvLD/0VGrlllZLo0Rb6VyUAgAAcAAAAHhWNBIAAAAAAAAAAAwCAAAU"
1294 "AAAAcAAAAAQAAADAAAAAAQAAANAAAAAAAAAAAAAAAAMAAADcAAAAAQAAAPQAAACAAQAAFAEAABQB"
1295 "AAAcAQAAJAEAADgBAABMAQAAVwEAAFoBAABdAQAAYAEAAGMBAABmAQAAaQEAAGwBAABvAQAAcgEA"
1296 "AHUBAAB4AQAAewEAAIYBAACMAQAAAQAAAAIAAAADAAAABQAAAAUAAAADAAAAAAAAAAAAAAAAAAAA"
1297 "AAAAABIAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAEAAAAAAAAAPwBAAAAAAAABjxpbml0PgAG"
1298 "TFRlc3Q7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAJVGVzdC5qYXZh"
1299 "AAFWAAFhAAFiAAFjAAFkAAFlAAFmAAFnAAFoAAFpAAFqAAFrAAlsb2NhbF92YXIABG1haW4ABHRl"
1300 "c3QAAAABAAcOAAAAARYDARIDAAAAAQABAAEAAACUAQAABAAAAHAQAgAAAA4AAgAAAAAAAACZAQAA"
1301 "GAAAABoABgAaAAcAGgAIABoACQAaAAoAGgALABoADAAaAA0AGgAOABoADwAaABAAGgETAAAAAgAA"
1302 "gYAEpAMBCbwDAAALAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAQAAADAAAAAAwAAAAEA"
1303 "AADQAAAABQAAAAMAAADcAAAABgAAAAEAAAD0AAAAAiAAABQAAAAUAQAAAyAAAAIAAACUAQAAASAA"
1304 "AAIAAACkAQAAACAAAAEAAAD8AQAAABAAAAEAAAAMAgAA";
1305
1306TEST_F(DexFileVerifierTest, DebugInfoTypeIdxTest) {
1307 {
1308 // The input dex file should be good before modification.
1309 ScratchFile tmp;
1310 std::string error_msg;
1311 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kDebugInfoTestDex,
1312 tmp.GetFilename().c_str(),
1313 &error_msg));
1314 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1315 }
1316
Andreas Gampee6215c02015-08-31 18:54:38 -07001317 // Modify the debug information entry.
1318 VerifyModification(
1319 kDebugInfoTestDex,
1320 "debug_start_type_idx",
1321 [](DexFile* dex_file) {
1322 *(const_cast<uint8_t*>(dex_file->Begin()) + 416) = 0x14U;
1323 },
1324 "DBG_START_LOCAL type_idx");
Logan Chiendd3208d2015-04-19 23:27:52 +08001325}
1326
Andreas Gampeb512c0e2016-02-19 19:45:34 -08001327TEST_F(DexFileVerifierTest, SectionAlignment) {
1328 {
1329 // The input dex file should be good before modification. Any file is fine, as long as it
1330 // uses all sections.
1331 ScratchFile tmp;
1332 std::string error_msg;
1333 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex,
1334 tmp.GetFilename().c_str(),
1335 &error_msg));
1336 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1337 }
1338
1339 // Modify all section offsets to be unaligned.
1340 constexpr size_t kSections = 7;
1341 for (size_t i = 0; i < kSections; ++i) {
1342 VerifyModification(
1343 kGoodTestDex,
1344 "section_align",
1345 [&](DexFile* dex_file) {
1346 DexFile::Header* header = const_cast<DexFile::Header*>(
1347 reinterpret_cast<const DexFile::Header*>(dex_file->Begin()));
1348 uint32_t* off_ptr;
1349 switch (i) {
1350 case 0:
1351 off_ptr = &header->map_off_;
1352 break;
1353 case 1:
1354 off_ptr = &header->string_ids_off_;
1355 break;
1356 case 2:
1357 off_ptr = &header->type_ids_off_;
1358 break;
1359 case 3:
1360 off_ptr = &header->proto_ids_off_;
1361 break;
1362 case 4:
1363 off_ptr = &header->field_ids_off_;
1364 break;
1365 case 5:
1366 off_ptr = &header->method_ids_off_;
1367 break;
1368 case 6:
1369 off_ptr = &header->class_defs_off_;
1370 break;
1371
1372 static_assert(kSections == 7, "kSections is wrong");
1373 default:
1374 LOG(FATAL) << "Unexpected section";
1375 UNREACHABLE();
1376 }
1377 ASSERT_TRUE(off_ptr != nullptr);
1378 ASSERT_NE(*off_ptr, 0U) << i; // Should already contain a value (in use).
1379 (*off_ptr)++; // Add one, which should misalign it (all the sections
1380 // above are aligned by 4).
1381 },
1382 "should be aligned by 4 for");
1383 }
1384}
1385
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001386// Generated from
1387//
1388// .class LOverloading;
1389//
1390// .super Ljava/lang/Object;
1391//
1392// .method public static foo()V
1393// .registers 1
1394// return-void
1395// .end method
1396//
1397// .method public static foo(I)V
1398// .registers 1
1399// return-void
1400// .end method
1401static const char kProtoOrderingTestDex[] =
1402 "ZGV4CjAzNQA1L+ABE6voQ9Lr4Ci//efB53oGnDr5PinsAQAAcAAAAHhWNBIAAAAAAAAAAFgBAAAG"
1403 "AAAAcAAAAAQAAACIAAAAAgAAAJgAAAAAAAAAAAAAAAIAAACwAAAAAQAAAMAAAAAMAQAA4AAAAOAA"
1404 "AADjAAAA8gAAAAYBAAAJAQAADQEAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAAAAAAEAAAAAwAA"
1405 "ABQBAAABAAAABQAAAAEAAQAFAAAAAQAAAAAAAAACAAAAAAAAAP////8AAAAASgEAAAAAAAABSQAN"
1406 "TE92ZXJsb2FkaW5nOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAJWSQADZm9vAAAAAQAAAAAAAAAA"
1407 "AAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAACAAAJpAIBCbgC"
1408 "AAAMAAAAAAAAAAEAAAAAAAAAAQAAAAYAAABwAAAAAgAAAAQAAACIAAAAAwAAAAIAAACYAAAABQAA"
1409 "AAIAAACwAAAABgAAAAEAAADAAAAAAiAAAAYAAADgAAAAARAAAAEAAAAUAQAAAxAAAAIAAAAcAQAA"
1410 "ASAAAAIAAAAkAQAAACAAAAEAAABKAQAAABAAAAEAAABYAQAA";
1411
1412TEST_F(DexFileVerifierTest, ProtoOrdering) {
1413 {
1414 // The input dex file should be good before modification.
1415 ScratchFile tmp;
1416 std::string error_msg;
1417 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kProtoOrderingTestDex,
1418 tmp.GetFilename().c_str(),
1419 &error_msg));
1420 ASSERT_TRUE(raw.get() != nullptr) << error_msg;
1421 }
1422
1423 // Modify the order of the ProtoIds for two overloads of "foo" with the
1424 // same return type and one having longer parameter list than the other.
1425 for (size_t i = 0; i != 2; ++i) {
1426 VerifyModification(
1427 kProtoOrderingTestDex,
1428 "proto_ordering",
1429 [i](DexFile* dex_file) {
1430 uint32_t method_idx;
1431 const uint8_t* data = FindMethodData(dex_file, "foo", &method_idx);
1432 CHECK(data != nullptr);
1433 // There should be 2 methods called "foo".
1434 CHECK_LT(method_idx + 1u, dex_file->NumMethodIds());
1435 CHECK_EQ(dex_file->GetMethodId(method_idx).name_idx_,
1436 dex_file->GetMethodId(method_idx + 1).name_idx_);
1437 CHECK_EQ(dex_file->GetMethodId(method_idx).proto_idx_ + 1u,
1438 dex_file->GetMethodId(method_idx + 1).proto_idx_);
1439 // Their return types should be the same.
1440 uint32_t proto1_idx = dex_file->GetMethodId(method_idx).proto_idx_;
1441 const DexFile::ProtoId& proto1 = dex_file->GetProtoId(proto1_idx);
1442 const DexFile::ProtoId& proto2 = dex_file->GetProtoId(proto1_idx + 1u);
1443 CHECK_EQ(proto1.return_type_idx_, proto2.return_type_idx_);
1444 // And the first should not have any parameters while the second should have some.
1445 CHECK(!DexFileParameterIterator(*dex_file, proto1).HasNext());
1446 CHECK(DexFileParameterIterator(*dex_file, proto2).HasNext());
1447 if (i == 0) {
1448 // Swap the proto parameters and shorties to break the ordering.
1449 std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
1450 const_cast<uint32_t&>(proto2.parameters_off_));
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001451 std::swap(const_cast<dex::StringIndex&>(proto1.shorty_idx_),
1452 const_cast<dex::StringIndex&>(proto2.shorty_idx_));
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001453 } else {
1454 // Copy the proto parameters and shorty to create duplicate proto id.
1455 const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001456 const_cast<dex::StringIndex&>(proto1.shorty_idx_) = proto2.shorty_idx_;
Vladimir Marko0ca8add2016-05-03 17:17:50 +01001457 }
1458 },
1459 "Out-of-order proto_id arguments");
1460 }
1461}
1462
Roland Levillain621b5ea2016-05-18 11:41:33 +01001463// To generate a base64 encoded Dex file version 037 from Smali files, use:
1464//
Ben Gruver14fc9db2017-04-28 15:30:49 -07001465// smali assemble --api 24 -o classes.dex class1.smali [class2.smali ...]
Roland Levillain621b5ea2016-05-18 11:41:33 +01001466// base64 classes.dex >classes.dex.base64
1467
1468// Dex file version 037 generated from:
1469//
1470// .class public LB28685551;
1471// .super LB28685551;
1472
1473static const char kClassExtendsItselfTestDex[] =
1474 "ZGV4CjAzNwDeGbgRg1kb6swszpcTWrrOAALB++F4OPT0AAAAcAAAAHhWNBIAAAAAAAAAAKgAAAAB"
1475 "AAAAcAAAAAEAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHgAAABcAAAAmAAAAJgA"
1476 "AAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAALTEIyODY4NTU1MTsAAAAABgAA"
1477 "AAAAAAABAAAAAAAAAAEAAAABAAAAcAAAAAIAAAABAAAAdAAAAAYAAAABAAAAeAAAAAIgAAABAAAA"
1478 "mAAAAAAQAAABAAAAqAAAAA==";
1479
1480TEST_F(DexFileVerifierTest, ClassExtendsItself) {
1481 VerifyModification(
1482 kClassExtendsItselfTestDex,
1483 "class_extends_itself",
1484 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1485 "Class with same type idx as its superclass: '0'");
1486}
1487
1488// Dex file version 037 generated from:
1489//
1490// .class public LFoo;
1491// .super LBar;
1492//
1493// and:
1494//
1495// .class public LBar;
1496// .super LFoo;
1497
1498static const char kClassesExtendOneAnotherTestDex[] =
1499 "ZGV4CjAzNwBXHSrwpDMwRBkg+L+JeQCuFNRLhQ86duEcAQAAcAAAAHhWNBIAAAAAAAAAANAAAAAC"
1500 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAABcAAAAwAAAAMAA"
1501 "AADHAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAABAAAAAQAA"
1502 "AAAAAAD/////AAAAAAAAAAAAAAAABUxCYXI7AAVMRm9vOwAAAAYAAAAAAAAAAQAAAAAAAAABAAAA"
1503 "AgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAgAAAIAAAAACIAAAAgAAAMAAAAAAEAAAAQAAANAAAAA=";
1504
1505TEST_F(DexFileVerifierTest, ClassesExtendOneAnother) {
1506 VerifyModification(
1507 kClassesExtendOneAnotherTestDex,
1508 "classes_extend_one_another",
1509 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1510 "Invalid class definition ordering: class with type idx: '1' defined before"
1511 " superclass with type idx: '0'");
1512}
1513
1514// Dex file version 037 generated from:
1515//
1516// .class public LAll;
1517// .super LYour;
1518//
1519// and:
1520//
1521// .class public LYour;
1522// .super LBase;
1523//
1524// and:
1525//
1526// .class public LBase;
1527// .super LAll;
1528
1529static const char kCircularClassInheritanceTestDex[] =
1530 "ZGV4CjAzNwBMJxgP0SJz6oLXnKfl+J7lSEORLRwF5LNMAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAD"
1531 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAIgAAABkAAAA6AAAAOgA"
1532 "AADvAAAA9wAAAAAAAAABAAAAAgAAAAEAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAgAA"
1533 "AAEAAAABAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAA/////wAAAAAAAAAA"
1534 "AAAAAAVMQWxsOwAGTEJhc2U7AAZMWW91cjsAAAYAAAAAAAAAAQAAAAAAAAABAAAAAwAAAHAAAAAC"
1535 "AAAAAwAAAHwAAAAGAAAAAwAAAIgAAAACIAAAAwAAAOgAAAAAEAAAAQAAAAABAAA=";
1536
1537TEST_F(DexFileVerifierTest, CircularClassInheritance) {
1538 VerifyModification(
1539 kCircularClassInheritanceTestDex,
1540 "circular_class_inheritance",
1541 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1542 "Invalid class definition ordering: class with type idx: '1' defined before"
1543 " superclass with type idx: '0'");
1544}
1545
1546// Dex file version 037 generated from:
1547//
1548// .class public abstract interface LInterfaceImplementsItself;
1549// .super Ljava/lang/Object;
1550// .implements LInterfaceImplementsItself;
1551
1552static const char kInterfaceImplementsItselfTestDex[] =
1553 "ZGV4CjAzNwCKKrjatp8XbXl5S/bEVJnqaBhjZkQY4440AQAAcAAAAHhWNBIAAAAAAAAAANwAAAAC"
1554 "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIAAAACUAAAAoAAAAKAA"
1555 "AAC9AAAAAAAAAAEAAAAAAAAAAQYAAAEAAADUAAAA/////wAAAAAAAAAAAAAAABtMSW50ZXJmYWNl"
1556 "SW1wbGVtZW50c0l0c2VsZjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAAABAAAAAAAAAAcAAAAAAAAA"
1557 "AQAAAAAAAAABAAAAAgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAQAAAIAAAAACIAAAAgAAAKAAAAAB"
1558 "EAAAAQAAANQAAAAAEAAAAQAAANwAAAA=";
1559
1560TEST_F(DexFileVerifierTest, InterfaceImplementsItself) {
1561 VerifyModification(
1562 kInterfaceImplementsItselfTestDex,
1563 "interface_implements_itself",
1564 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1565 "Class with same type idx as implemented interface: '0'");
1566}
1567
1568// Dex file version 037 generated from:
1569//
1570// .class public abstract interface LPing;
1571// .super Ljava/lang/Object;
1572// .implements LPong;
1573//
1574// and:
1575//
1576// .class public abstract interface LPong;
1577// .super Ljava/lang/Object;
1578// .implements LPing;
1579
1580static const char kInterfacesImplementOneAnotherTestDex[] =
1581 "ZGV4CjAzNwD0Kk9sxlYdg3Dy1Cff0gQCuJAQfEP6ohZUAQAAcAAAAHhWNBIAAAAAAAAAAPwAAAAD"
1582 "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIgAAACMAAAAyAAAAMgA"
1583 "AADQAAAA2AAAAAAAAAABAAAAAgAAAAEAAAABBgAAAgAAAOwAAAD/////AAAAAAAAAAAAAAAAAAAA"
1584 "AAEGAAACAAAA9AAAAP////8AAAAAAAAAAAAAAAAGTFBpbmc7AAZMUG9uZzsAEkxqYXZhL2xhbmcv"
1585 "T2JqZWN0OwABAAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAADAAAAcAAAAAIAAAAD"
1586 "AAAAfAAAAAYAAAACAAAAiAAAAAIgAAADAAAAyAAAAAEQAAACAAAA7AAAAAAQAAABAAAA/AAAAA==";
1587
1588TEST_F(DexFileVerifierTest, InterfacesImplementOneAnother) {
1589 VerifyModification(
1590 kInterfacesImplementOneAnotherTestDex,
1591 "interfaces_implement_one_another",
1592 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1593 "Invalid class definition ordering: class with type idx: '1' defined before"
1594 " implemented interface with type idx: '0'");
1595}
1596
1597// Dex file version 037 generated from:
1598//
1599// .class public abstract interface LA;
1600// .super Ljava/lang/Object;
1601// .implements LB;
1602//
1603// and:
1604//
1605// .class public abstract interface LB;
1606// .super Ljava/lang/Object;
1607// .implements LC;
1608//
1609// and:
1610//
1611// .class public abstract interface LC;
1612// .super Ljava/lang/Object;
1613// .implements LA;
1614
1615static const char kCircularInterfaceImplementationTestDex[] =
1616 "ZGV4CjAzNwCzKmD5Fol6XAU6ichYHcUTIP7Z7MdTcEmEAQAAcAAAAHhWNBIAAAAAAAAAACwBAAAE"
1617 "AAAAcAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAJAAAACUAAAA8AAAAPAA"
1618 "AAD1AAAA+gAAAP8AAAAAAAAAAQAAAAIAAAADAAAAAgAAAAEGAAADAAAAHAEAAP////8AAAAAAAAA"
1619 "AAAAAAABAAAAAQYAAAMAAAAUAQAA/////wAAAAAAAAAAAAAAAAAAAAABBgAAAwAAACQBAAD/////"
1620 "AAAAAAAAAAAAAAAAA0xBOwADTEI7AANMQzsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAQAAAAIAAAAB"
1621 "AAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAAEAAAAcAAAAAIAAAAEAAAAgAAAAAYA"
1622 "AAADAAAAkAAAAAIgAAAEAAAA8AAAAAEQAAADAAAAFAEAAAAQAAABAAAALAEAAA==";
1623
1624TEST_F(DexFileVerifierTest, CircularInterfaceImplementation) {
1625 VerifyModification(
1626 kCircularInterfaceImplementationTestDex,
1627 "circular_interface_implementation",
1628 [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
1629 "Invalid class definition ordering: class with type idx: '2' defined before"
1630 " implemented interface with type idx: '0'");
1631}
1632
Aart Bik37d6a3b2016-06-21 18:30:10 -07001633TEST_F(DexFileVerifierTest, Checksum) {
1634 size_t length;
Alex Light9c20a142016-08-23 15:05:12 -07001635 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kGoodTestDex, &length));
Aart Bik37d6a3b2016-06-21 18:30:10 -07001636 CHECK(dex_bytes != nullptr);
1637 // Note: `dex_file` will be destroyed before `dex_bytes`.
1638 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1639 std::string error_msg;
1640
1641 // Good checksum: all pass.
1642 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1643 dex_file->Begin(),
1644 dex_file->Size(),
1645 "good checksum, no verify",
1646 /*verify_checksum*/ false,
1647 &error_msg));
1648 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1649 dex_file->Begin(),
1650 dex_file->Size(),
1651 "good checksum, verify",
1652 /*verify_checksum*/ true,
1653 &error_msg));
1654
1655 // Bad checksum: !verify_checksum passes verify_checksum fails.
1656 DexFile::Header* header = reinterpret_cast<DexFile::Header*>(
1657 const_cast<uint8_t*>(dex_file->Begin()));
1658 header->checksum_ = 0;
1659 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
1660 dex_file->Begin(),
1661 dex_file->Size(),
1662 "bad checksum, no verify",
1663 /*verify_checksum*/ false,
1664 &error_msg));
1665 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1666 dex_file->Begin(),
1667 dex_file->Size(),
1668 "bad checksum, verify",
1669 /*verify_checksum*/ true,
1670 &error_msg));
1671 EXPECT_NE(error_msg.find("Bad checksum"), std::string::npos) << error_msg;
1672}
1673
Orion Hodson6c4921b2016-09-21 15:41:06 +01001674TEST_F(DexFileVerifierTest, BadStaticMethodName) {
1675 // Generated DEX file version (037) from:
1676 //
1677 // .class public LBadName;
1678 // .super Ljava/lang/Object;
1679 //
1680 // .method public static <bad_name> (II)V
1681 // .registers 2
1682 // .prologue
1683 // return-void
1684 // .end method
1685 //
1686 // .method public constructor <init>()V
1687 // .registers 1
1688 // .prologue
1689 // .line 1
1690 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1691 // return-void
1692 // .end method
1693 //
1694 static const char kDexBase64[] =
1695 "ZGV4CjAzNwC2NYlwyxEc/h6hv+hMeUVQPtiX6MQBcfgwAgAAcAAAAHhWNBIAAAAAAAAAAJABAAAI"
1696 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAABAAQAA8AAAAPAA"
1697 "AAD8AAAABAEAABIBAAAVAQAAIAEAADQBAAA3AQAAAwAAAAQAAAAFAAAABgAAAAYAAAADAAAAAAAA"
1698 "AAcAAAADAAAAPAEAAAEAAQAAAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAACAAAA"
1699 "AAAAAIABAAAAAAAACjxiYWRfbmFtZT4ABjxpbml0PgAMQmFkTmFtZS5qYXZhAAFJAAlMQmFkTmFt"
1700 "ZTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgADVklJAAIAAAAAAAAAAAAAAAACAAAHAAEABw4AAAIA"
1701 "AgAAAAAASAEAAAEAAAAOAAAAAQABAAEAAABOAQAABAAAAHAQAgAAAA4AAAACAAAJ1AIBgYAE6AIA"
1702 "AA0AAAAAAAAAAQAAAAAAAAABAAAACAAAAHAAAAACAAAABAAAAJAAAAADAAAAAgAAAKAAAAAFAAAA"
1703 "AwAAALgAAAAGAAAAAQAAANAAAAACIAAACAAAAPAAAAABEAAAAQAAADwBAAADEAAAAQAAAEQBAAAD"
1704 "IAAAAgAAAEgBAAABIAAAAgAAAFQBAAAAIAAAAQAAAIABAAAAEAAAAQAAAJABAAA=";
1705
1706 size_t length;
1707 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1708 CHECK(dex_bytes != nullptr);
1709 // Note: `dex_file` will be destroyed before `dex_bytes`.
1710 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1711 std::string error_msg;
1712 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1713 dex_file->Begin(),
1714 dex_file->Size(),
1715 "bad static method name",
1716 /*verify_checksum*/ true,
1717 &error_msg));
1718}
1719
1720TEST_F(DexFileVerifierTest, BadVirtualMethodName) {
1721 // Generated DEX file version (037) from:
1722 //
1723 // .class public LBadVirtualName;
1724 // .super Ljava/lang/Object;
1725 //
1726 // .method public <bad_name> (II)V
1727 // .registers 2
1728 // return-void
1729 // .end method
1730 //
1731 // .method public constructor <init>()V
1732 // .registers 1
1733 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1734 // return-void
1735 // .end method
1736 //
1737 static const char kDexBase64[] =
1738 "ZGV4CjAzNwDcPC8B2E7kYTZmeHX2u2IqrpWV9EXBHpE8AgAAcAAAAHhWNBIAAAAAAAAAAJwBAAAI"
1739 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAABMAQAA8AAAAPAA"
1740 "AAD8AAAABAEAABkBAAAcAQAALgEAAEIBAABFAQAAAwAAAAQAAAAFAAAABgAAAAYAAAADAAAAAAAA"
1741 "AAcAAAADAAAATAEAAAEAAQAAAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAACAAAA"
1742 "AAAAAI4BAAAAAAAACjxiYWRfbmFtZT4ABjxpbml0PgATQmFkVmlydHVhbE5hbWUuamF2YQABSQAQ"
1743 "TEJhZFZpcnR1YWxOYW1lOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAANWSUkAAAACAAAAAAAAAAAA"
1744 "AAABAAcOAAACAAAHAAABAAEAAQAAAFgBAAAEAAAAcBACAAAADgADAAMAAAAAAF0BAAABAAAADgAA"
1745 "AAEBAYGABOQCAAH8Ag0AAAAAAAAAAQAAAAAAAAABAAAACAAAAHAAAAACAAAABAAAAJAAAAADAAAA"
1746 "AgAAAKAAAAAFAAAAAwAAALgAAAAGAAAAAQAAANAAAAACIAAACAAAAPAAAAABEAAAAQAAAEwBAAAD"
1747 "EAAAAQAAAFQBAAADIAAAAgAAAFgBAAABIAAAAgAAAGQBAAAAIAAAAQAAAI4BAAAAEAAAAQAAAJwB"
1748 "AAA=";
1749
1750 size_t length;
1751 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1752 CHECK(dex_bytes != nullptr);
1753 // Note: `dex_file` will be destroyed before `dex_bytes`.
1754 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1755 std::string error_msg;
1756 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1757 dex_file->Begin(),
1758 dex_file->Size(),
1759 "bad virtual method name",
1760 /*verify_checksum*/ true,
1761 &error_msg));
1762}
1763
1764TEST_F(DexFileVerifierTest, BadClinitSignature) {
1765 // Generated DEX file version (037) from:
1766 //
1767 // .class public LOneClinitBadSig;
1768 // .super Ljava/lang/Object;
1769 //
1770 // .method public static constructor <clinit>(II)V
1771 // .registers 2
1772 // return-void
1773 // .end method
1774 //
1775 // .method public constructor <init>()V
1776 // .registers 1
1777 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1778 // return-void
1779 // .end method
1780 //
1781 static const char kDexBase64[] =
1782 "ZGV4CjAzNwBNOwTbfJmWq5eMOlxUY4EICGiEGJMVg8RAAgAAcAAAAHhWNBIAAAAAAAAAAKABAAAI"
1783 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAABQAQAA8AAAAPAA"
1784 "AAD6AAAAAgEAAAUBAAAYAQAALAEAAEIBAABFAQAAAgAAAAMAAAAEAAAABgAAAAYAAAADAAAAAAAA"
1785 "AAcAAAADAAAATAEAAAEAAQAAAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAAFAAAA"
1786 "AAAAAJABAAAAAAAACDxjbGluaXQ+AAY8aW5pdD4AAUkAEUxPbmVDbGluaXRCYWRTaWc7ABJMamF2"
1787 "YS9sYW5nL09iamVjdDsAFE9uZUNsaW5pdEJhZFNpZy5qYXZhAAFWAANWSUkAAAACAAAAAAAAAAAA"
1788 "AAAAAgAABwABAAcOAAACAAIAAAAAAFgBAAABAAAADgAAAAEAAQABAAAAXgEAAAQAAABwEAIAAAAO"
1789 "AAAAAgAAiYAE5AIBgYAE+AINAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQAAACQAAAA"
1790 "AwAAAAIAAACgAAAABQAAAAMAAAC4AAAABgAAAAEAAADQAAAAAiAAAAgAAADwAAAAARAAAAEAAABM"
1791 "AQAAAxAAAAEAAABUAQAAAyAAAAIAAABYAQAAASAAAAIAAABkAQAAACAAAAEAAACQAQAAABAAAAEA"
1792 "AACgAQAA";
1793
1794 size_t length;
1795 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1796 CHECK(dex_bytes != nullptr);
1797 // Note: `dex_file` will be destroyed before `dex_bytes`.
1798 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1799 std::string error_msg;
1800 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1801 dex_file->Begin(),
1802 dex_file->Size(),
1803 "bad clinit signature",
1804 /*verify_checksum*/ true,
1805 &error_msg));
1806}
1807
1808TEST_F(DexFileVerifierTest, BadClinitSignatureAgain) {
1809 // Generated DEX file version (037) from:
1810 //
1811 // .class public LOneClinitBadSigAgain;
1812 // .super Ljava/lang/Object;
1813 //
1814 // .method public static constructor <clinit>()I
1815 // .registers 1
1816 // const/4 v0, 1
1817 // return v0
1818 // .end method
1819 //
1820 // .method public constructor <init>()V
1821 // .registers 1
1822 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1823 // return-void
1824 // .end method
1825 //
1826 static const char kDexBase64[] =
1827 "ZGV4CjAzNwBfPcPu5NVwKUqZIu/YR8xqVlVD5UzTk0gEAgAAcAAAAHhWNBIAAAAAAAAAAIgBAAAH"
1828 "AAAAcAAAAAQAAACMAAAAAgAAAJwAAAAAAAAAAAAAAAMAAAC0AAAAAQAAAMwAAAAYAQAA7AAAAOwA"
1829 "AAD2AAAA/gAAAAEBAAAZAQAALQEAAEgBAAACAAAAAwAAAAQAAAAGAAAAAgAAAAAAAAAAAAAABgAA"
1830 "AAMAAAAAAAAAAQAAAAAAAAABAAEAAQAAAAIAAQABAAAAAQAAAAEAAAACAAAAAAAAAAUAAAAAAAAA"
1831 "eAEAAAAAAAAIPGNsaW5pdD4ABjxpbml0PgABSQAWTE9uZUNsaW5pdEJhZFNpZ0FnYWluOwASTGph"
1832 "dmEvbGFuZy9PYmplY3Q7ABlPbmVDbGluaXRCYWRTaWdBZ2Fpbi5qYXZhAAFWAAABAAAAAAAAAAAA"
1833 "AAACAAAAEhAPAAEAAQABAAAAAAAAAAQAAABwEAIAAAAOAAAAAgAAiYAEzAIBgYAE4AIKAAAAAAAA"
1834 "AAEAAAAAAAAAAQAAAAcAAABwAAAAAgAAAAQAAACMAAAAAwAAAAIAAACcAAAABQAAAAMAAAC0AAAA"
1835 "BgAAAAEAAADMAAAAAiAAAAcAAADsAAAAASAAAAIAAABMAQAAACAAAAEAAAB4AQAAABAAAAEAAACI"
1836 "AQAA";
1837
1838 size_t length;
1839 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1840 CHECK(dex_bytes != nullptr);
1841 // Note: `dex_file` will be destroyed before `dex_bytes`.
1842 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1843 std::string error_msg;
1844 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1845 dex_file->Begin(),
1846 dex_file->Size(),
1847 "bad clinit signature",
1848 /*verify_checksum*/ true,
1849 &error_msg));
1850}
1851
1852TEST_F(DexFileVerifierTest, BadInitSignature) {
1853 // Generated DEX file version (037) from:
1854 //
1855 // .class public LBadInitSig;
1856 // .super Ljava/lang/Object;
1857 //
1858 // .method public constructor <init>()I
1859 // .registers 1
1860 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
1861 // const v0, 1
1862 // return v0
1863 // .end method
1864 //
1865 static const char kDexBase64[] =
1866 "ZGV4CjAzNwCdMdeh1KoHWamF2Prq32LF39YZ78fV7q+wAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
1867 "AAAAcAAAAAQAAACEAAAAAgAAAJQAAAAAAAAAAAAAAAIAAACsAAAAAQAAALwAAADUAAAA3AAAANwA"
1868 "AADkAAAA5wAAAPUAAAAJAQAAAQAAAAIAAAADAAAABAAAAAEAAAAAAAAAAAAAAAQAAAADAAAAAAAA"
1869 "AAEAAAAAAAAAAgABAAAAAAABAAAAAQAAAAIAAAAAAAAA/////wAAAAAqAQAAAAAAAAY8aW5pdD4A"
1870 "AUkADExCYWRJbml0U2lnOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAEAAQABAAAAAAAAAAcAAABw"
1871 "EAEAAAAUAAEAAAAPAAAAAQAAgYAEjAIKAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAQA"
1872 "AACEAAAAAwAAAAIAAACUAAAABQAAAAIAAACsAAAABgAAAAEAAAC8AAAAAiAAAAUAAADcAAAAASAA"
1873 "AAEAAAAMAQAAACAAAAEAAAAqAQAAABAAAAEAAAA0AQAA";
1874
1875 size_t length;
1876 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
1877 CHECK(dex_bytes != nullptr);
1878 // Note: `dex_file` will be destroyed before `dex_bytes`.
1879 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
1880 std::string error_msg;
1881 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
1882 dex_file->Begin(),
1883 dex_file->Size(),
1884 "bad init signature",
1885 /*verify_checksum*/ true,
1886 &error_msg));
1887}
1888
Orion Hodson12f4ff42017-01-13 16:43:12 +00001889static const char* kInvokeCustomDexFiles[] = {
1890 // TODO(oth): Revisit this test when we have smali / dx support.
1891 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test001/Tests.java
1892 "ZGV4CjAzOAAEj12s/acmmdGuDL92SWSBh6iLBjxgomWkCAAAcAAAAHhWNBIAAAAAAAAAALwHAAAx"
1893 "AAAAcAAAABYAAAA0AQAACQAAAIwBAAADAAAA+AEAAAsAAAAQAgAAAQAAAHACAAAMBgAAmAIAAMID"
1894 "AADKAwAAzQMAANIDAADhAwAA5AMAAOoDAAAfBAAAUgQAAIMEAAC4BAAA1AQAAOsEAAD+BAAAEgUA"
1895 "ACYFAAA6BQAAUQUAAG4FAACTBQAAtAUAAN0FAAD/BQAAHgYAADgGAABKBgAAVgYAAFkGAABdBgAA"
1896 "YgYAAGYGAAB7BgAAgAYAAI8GAACdBgAAtAYAAMMGAADSBgAA3gYAAPIGAAD4BgAABgcAAA4HAAAU"
1897 "BwAAGgcAAB8HAAAoBwAANAcAADoHAAABAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A"
1898 "AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoAAAAeAAAAAgAA"
1899 "AAAAAACMAwAABQAAAAwAAACUAwAABQAAAA4AAACgAwAABAAAAA8AAAAAAAAAGgAAABQAAAAAAAAA"
1900 "GwAAABQAAACsAwAAHAAAABQAAACMAwAAHQAAABQAAAC0AwAAHQAAABQAAAC8AwAAAwADAAMAAAAE"
1901 "AAwAJAAAAAoABgAsAAAABAAEAAAAAAAEAAAAHwAAAAQAAQAoAAAABAAIACoAAAAEAAQALwAAAAYA"
1902 "BQAtAAAACAAEAAAAAAANAAcAAAAAAA8AAgAlAAAAEAADACkAAAASAAYAIQAAAJYHAACWBwAABAAA"
1903 "AAEAAAAIAAAAAAAAABkAAABkAwAAnQcAAAAAAAAEAAAAAgAAAAEAAABjBwAAAQAAAIsHAAACAAAA"
1904 "iwcAAJMHAAABAAEAAQAAAEEHAAAEAAAAcBAGAAAADgADAAIAAAAAAEYHAAADAAAAkAABAg8AAAAF"
1905 "AAMABAAAAE0HAAAQAAAAcQAJAAAADAAcAQQAbkAIABBDDAAiAQ0AcCAHAAEAEQEEAAEAAgAAAFYH"
1906 "AAAMAAAAYgACABIhEjL8IAAAIQAKAW4gBQAQAA4AAwABAAIAAABdBwAACwAAABIgEjH8IAEAEAAK"
1907 "ABJRcSAKAAEADgAAAAAAAAAAAAAAAwAAAAAAAAABAAAAmAIAAAIAAACgAgAABAAAAKgCAAACAAAA"
1908 "AAAAAAMAAAAPAAkAEQAAAAMAAAAHAAkAEQAAAAEAAAAAAAAAAQAAAA4AAAABAAAAFQAGPGluaXQ+"
1909 "AAFJAANJSUkADUlOVk9LRV9TVEFUSUMAAUwABExMTEwAM0xjb20vYW5kcm9pZC9qYWNrL2Fubm90"
1910 "YXRpb25zL0NhbGxlZEJ5SW52b2tlQ3VzdG9tOwAxTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlv"
1911 "bnMvTGlua2VyTWV0aG9kSGFuZGxlOwAvTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMvTWV0"
1912 "aG9kSGFuZGxlS2luZDsAM0xjb20vYW5kcm9pZC9qYWNrL2phdmE3L2ludm9rZWN1c3RvbS90ZXN0"
1913 "MDAxL1Rlc3RzOwAaTGRhbHZpay9hbm5vdGF0aW9uL1Rocm93czsAFUxqYXZhL2lvL1ByaW50U3Ry"
1914 "ZWFtOwARTGphdmEvbGFuZy9DbGFzczsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9T"
1915 "dHJpbmc7ABJMamF2YS9sYW5nL1N5c3RlbTsAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwAbTGphdmEv"
1916 "bGFuZy9pbnZva2UvQ2FsbFNpdGU7ACNMamF2YS9sYW5nL2ludm9rZS9Db25zdGFudENhbGxTaXRl"
1917 "OwAfTGphdmEvbGFuZy9pbnZva2UvTWV0aG9kSGFuZGxlOwAnTGphdmEvbGFuZy9pbnZva2UvTWV0"
1918 "aG9kSGFuZGxlcyRMb29rdXA7ACBMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzOwAdTGph"
1919 "dmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTsAGExqdW5pdC9mcmFtZXdvcmsvQXNzZXJ0OwAQTG9y"
1920 "Zy9qdW5pdC9UZXN0OwAKVGVzdHMuamF2YQABVgACVkkAA1ZJSQACVkwAE1tMamF2YS9sYW5nL1N0"
1921 "cmluZzsAA2FkZAANYXJndW1lbnRUeXBlcwAMYXNzZXJ0RXF1YWxzABVlbWl0dGVyOiBqYWNrLTQu"
1922 "MC1lbmcADWVuY2xvc2luZ1R5cGUADWZpZWxkQ2FsbFNpdGUACmZpbmRTdGF0aWMAEmludm9rZU1l"
1923 "dGhvZEhhbmRsZQAEa2luZAAMbGlua2VyTWV0aG9kAAZsb29rdXAABG1haW4ABG5hbWUAA291dAAH"
1924 "cHJpbnRsbgAKcmV0dXJuVHlwZQAEdGVzdAAFdmFsdWUAIgAHDgAvAgAABw4ANQMAAAAHDqUAPwEA"
1925 "Bw60ADsABw6lAAABBCAcAhgAGAAmHAEdAgQgHAMYDxgJGBEjGAQnGwArFygrFx8uGAACBQEwHAEY"
1926 "CwETAAMWABcfFQABAAQBAQkAgYAEtAUBCswFAQrkBQEJlAYEAbwGAAAAEwAAAAAAAAABAAAAAAAA"
1927 "AAEAAAAxAAAAcAAAAAIAAAAWAAAANAEAAAMAAAAJAAAAjAEAAAQAAAADAAAA+AEAAAUAAAALAAAA"
1928 "EAIAAAcAAAACAAAAaAIAAAYAAAABAAAAcAIAAAgAAAABAAAAkAIAAAMQAAADAAAAmAIAAAEgAAAF"
1929 "AAAAtAIAAAYgAAABAAAAZAMAAAEQAAAGAAAAjAMAAAIgAAAxAAAAwgMAAAMgAAAFAAAAQQcAAAQg"
1930 "AAADAAAAYwcAAAUgAAABAAAAlgcAAAAgAAABAAAAnQcAAAAQAAABAAAAvAcAAA==",
1931 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test002/Tests.java
1932 "ZGV4CjAzOAAzq3aGAwKhT4QQj4lqNfZJAO8Tm24uTyNICQAAcAAAAHhWNBIAAAAAAAAAAGAIAAA2"
1933 "AAAAcAAAABgAAABIAQAACQAAAKgBAAAEAAAAFAIAAA0AAAA0AgAAAQAAAKQCAAB8BgAAzAIAACYE"
1934 "AAAwBAAAOAQAAEQEAABHBAAATAQAAE8EAABVBAAAigQAALwEAADtBAAAIgUAAD4FAABVBQAAaAUA"
1935 "AH0FAACRBQAApQUAALkFAADQBQAA7QUAABIGAAAzBgAAXAYAAH4GAACdBgAAtwYAAMkGAADPBgAA"
1936 "2wYAAN4GAADiBgAA5wYAAOsGAAD/BgAAFAcAABkHAAAoBwAANgcAAE0HAABcBwAAawcAAH4HAACK"
1937 "BwAAkAcAAJgHAACeBwAAqgcAALAHAAC1BwAAxgcAAM8HAADbBwAA4QcAAAMAAAAHAAAACAAAAAkA"
1938 "AAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAA"
1939 "ABgAAAAZAAAAGgAAAB0AAAAhAAAAIgAAAAQAAAAAAAAA8AMAAAYAAAAPAAAA+AMAAAUAAAAQAAAA"
1940 "AAAAAAYAAAASAAAABAQAAB0AAAAVAAAAAAAAAB4AAAAVAAAAEAQAAB8AAAAVAAAA8AMAACAAAAAV"
1941 "AAAAGAQAACAAAAAVAAAAIAQAAAMAAwACAAAABAANACgAAAAIAAcAGwAAAAsABgAwAAAABAAEAAAA"
1942 "AAAEAAQAAQAAAAQAAAAjAAAABAAIAC0AAAAEAAQANAAAAAYABQAyAAAACQAEAAEAAAAMAAQAMQAA"
1943 "AA4ABwABAAAAEAABACoAAAARAAIALAAAABIAAwAuAAAAEwAGACUAAAA4CAAAOAgAAAQAAAABAAAA"
1944 "CQAAAAAAAAAcAAAA0AMAAD8IAAAAAAAAAQAAAAEAAAABAAAADggAAAIAAAAtCAAANQgAAAgAAAAE"
1945 "AAEA6AcAACoAAABxAAoAAAAMABwBBAAbAiMAAABiAwIAYgQCABIVI1UWAGIGAgASB00GBQdxMAsA"
1946 "QwUMA25ACQAQMgwAIgEOAHAgCAABAGkBAQAOAA0AbhAHAAAAKPsAAAAAJAABAAEBDCUBAAEAAQAA"
1947 "APUHAAAEAAAAcBAGAAAADgADAAIAAAAAAPoHAAADAAAAkAABAg8AAAAEAAEAAgAAAAEIAAAMAAAA"
1948 "YgADABIhEjL8IAAAIQAKAW4gBQAQAA4AAwABAAIAAAAICAAACwAAABIgEjH8IAEAEAAKABJRcSAM"
1949 "AAEADgAAAAAAAAAAAAAAAgAAAAAAAAACAAAAzAIAAAQAAADUAgAAAgAAAAAAAAADAAAABwAKABIA"
1950 "AAADAAAABwAHABYAAAABAAAAAAAAAAEAAAAPAAAAAQAAABcACDxjbGluaXQ+AAY8aW5pdD4ACkdF"
1951 "VF9TVEFUSUMAAUkAA0lJSQABTAAETExMTAAzTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMv"
1952 "Q2FsbGVkQnlJbnZva2VDdXN0b207ADBMY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9MaW5r"
1953 "ZXJGaWVsZEhhbmRsZTsAL0xjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL01ldGhvZEhhbmRs"
1954 "ZUtpbmQ7ADNMY29tL2FuZHJvaWQvamFjay9qYXZhNy9pbnZva2VjdXN0b20vdGVzdDAwMi9UZXN0"
1955 "czsAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEUxq"
1956 "YXZhL2xhbmcvQ2xhc3M7ABNMamF2YS9sYW5nL0ludGVnZXI7ABJMamF2YS9sYW5nL09iamVjdDsA"
1957 "EkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07ABVMamF2YS9sYW5nL1Rocm93"
1958 "YWJsZTsAG0xqYXZhL2xhbmcvaW52b2tlL0NhbGxTaXRlOwAjTGphdmEvbGFuZy9pbnZva2UvQ29u"
1959 "c3RhbnRDYWxsU2l0ZTsAH0xqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZTsAJ0xqYXZhL2xh"
1960 "bmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwOwAgTGphdmEvbGFuZy9pbnZva2UvTWV0aG9k"
1961 "SGFuZGxlczsAHUxqYXZhL2xhbmcvaW52b2tlL01ldGhvZFR5cGU7ABhManVuaXQvZnJhbWV3b3Jr"
1962 "L0Fzc2VydDsAEExvcmcvanVuaXQvVGVzdDsABFRZUEUAClRlc3RzLmphdmEAAVYAAlZJAANWSUkA"
1963 "AlZMABJbTGphdmEvbGFuZy9DbGFzczsAE1tMamF2YS9sYW5nL1N0cmluZzsAA2FkZAANYXJndW1l"
1964 "bnRUeXBlcwAMYXNzZXJ0RXF1YWxzABVlbWl0dGVyOiBqYWNrLTQuMC1lbmcADWVuY2xvc2luZ1R5"
1965 "cGUADWZpZWxkQ2FsbFNpdGUAEWZpZWxkTWV0aG9kSGFuZGxlAApmaW5kU3RhdGljAARraW5kAAZs"
1966 "b29rdXAABG1haW4ACm1ldGhvZFR5cGUABG5hbWUAA291dAAPcHJpbnRTdGFja1RyYWNlAAdwcmlu"
1967 "dGxuAApyZXR1cm5UeXBlAAR0ZXN0AAV2YWx1ZQAoAAcOAR0PAnh3Jh4AIQAHDgA2AgAABw4APwEA"
1968 "Bw60ADsABw6lAAABBCQcAhgAGAApHAEdAgMnGAQrGwAvFygvFyMzGAACBQE1HAEYDAEUAAMWABcj"
1969 "FQABAAQBAQkAiIAE4AUBgYAE0AYBCugGAQmABwQBqAcAAAATAAAAAAAAAAEAAAAAAAAAAQAAADYA"
1970 "AABwAAAAAgAAABgAAABIAQAAAwAAAAkAAACoAQAABAAAAAQAAAAUAgAABQAAAA0AAAA0AgAABwAA"
1971 "AAIAAACcAgAABgAAAAEAAACkAgAACAAAAAEAAADEAgAAAxAAAAIAAADMAgAAASAAAAUAAADgAgAA"
1972 "BiAAAAEAAADQAwAAARAAAAYAAADwAwAAAiAAADYAAAAmBAAAAyAAAAUAAADoBwAABCAAAAMAAAAO"
1973 "CAAABSAAAAEAAAA4CAAAACAAAAEAAAA/CAAAABAAAAEAAABgCAAA",
1974 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test003/Tests.java
1975 "ZGV4CjAzOABjnhkFatj30/7cHTCJsfr7vAjz9/p+Y+TcCAAAcAAAAHhWNBIAAAAAAAAAAPQHAAAx"
1976 "AAAAcAAAABYAAAA0AQAACQAAAIwBAAADAAAA+AEAAAsAAAAQAgAAAQAAAHACAABEBgAAmAIAAOoD"
1977 "AADyAwAA9QMAAP4DAAANBAAAEAQAABYEAABLBAAAfgQAAK8EAADkBAAAAAUAABcFAAAqBQAAPgUA"
1978 "AFIFAABmBQAAfQUAAJoFAAC/BQAA4AUAAAkGAAArBgAASgYAAGQGAAB2BgAAggYAAIUGAACJBgAA"
1979 "jgYAAJIGAACnBgAArAYAALsGAADJBgAA4AYAAO8GAAD+BgAACgcAAB4HAAAkBwAAMgcAADoHAABA"
1980 "BwAARgcAAEsHAABUBwAAYAcAAGYHAAABAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A"
1981 "AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoAAAAeAAAAAgAA"
1982 "AAAAAACkAwAABQAAAAwAAAC0AwAABQAAAA4AAADAAwAABAAAAA8AAAAAAAAAGgAAABQAAAAAAAAA"
1983 "GwAAABQAAADMAwAAHAAAABQAAADUAwAAHQAAABQAAADcAwAAHQAAABQAAADkAwAAAwADAAMAAAAE"
1984 "AAwAJAAAAAoABgAsAAAABAAEAAAAAAAEAAAAHwAAAAQAAQAoAAAABAAIACoAAAAEAAQALwAAAAYA"
1985 "BQAtAAAACAAEAAAAAAANAAcAAAAAAA8AAgAlAAAAEAADACkAAAASAAYAIQAAAM4HAADOBwAABAAA"
1986 "AAEAAAAIAAAAAAAAABkAAAB8AwAA1QcAAAAAAAAEAAAAAgAAAAEAAACTBwAAAQAAAMMHAAACAAAA"
1987 "wwcAAMsHAAABAAEAAQAAAG0HAAAEAAAAcBAGAAAADgAHAAYAAAAAAHIHAAAHAAAAkAABArAwsECw"
1988 "ULBgDwAAAAUAAwAEAAAAfQcAABAAAABxAAkAAAAMABwBBABuQAgAEEMMACIBDQBwIAcAAQARAQgA"
1989 "AQACAAAAhgcAABAAAABiBgIAEhASIRIyEkMSVBJl/QYAAAAACgBuIAUABgAOAAcAAQACAAAAjQcA"
1990 "ABAAAAASEBIhEjISQxJUEmX9BgEAAAAKABMBFQBxIAoAAQAOAAAAAAAAAAAAAwAAAAAAAAABAAAA"
1991 "mAIAAAIAAACgAgAABAAAAKgCAAAGAAAAAAAAAAAAAAAAAAAAAwAAAA8ACQARAAAAAwAAAAcACQAR"
1992 "AAAAAQAAAAAAAAACAAAAAAAAAAEAAAAOAAAAAQAAABUABjxpbml0PgABSQAHSUlJSUlJSQANSU5W"
1993 "T0tFX1NUQVRJQwABTAAETExMTAAzTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMvQ2FsbGVk"
1994 "QnlJbnZva2VDdXN0b207ADFMY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9MaW5rZXJNZXRo"
1995 "b2RIYW5kbGU7AC9MY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9NZXRob2RIYW5kbGVLaW5k"
1996 "OwAzTGNvbS9hbmRyb2lkL2phY2svamF2YTcvaW52b2tlY3VzdG9tL3Rlc3QwMDMvVGVzdHM7ABpM"
1997 "ZGFsdmlrL2Fubm90YXRpb24vVGhyb3dzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABFMamF2YS9s"
1998 "YW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZh"
1999 "L2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABtMamF2YS9sYW5nL2ludm9rZS9D"
2000 "YWxsU2l0ZTsAI0xqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGU7AB9MamF2YS9sYW5n"
2001 "L2ludm9rZS9NZXRob2RIYW5kbGU7ACdMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExv"
2002 "b2t1cDsAIExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXM7AB1MamF2YS9sYW5nL2ludm9r"
2003 "ZS9NZXRob2RUeXBlOwAYTGp1bml0L2ZyYW1ld29yay9Bc3NlcnQ7ABBMb3JnL2p1bml0L1Rlc3Q7"
2004 "AApUZXN0cy5qYXZhAAFWAAJWSQADVklJAAJWTAATW0xqYXZhL2xhbmcvU3RyaW5nOwADYWRkAA1h"
2005 "cmd1bWVudFR5cGVzAAxhc3NlcnRFcXVhbHMAFWVtaXR0ZXI6IGphY2stNC4wLWVuZwANZW5jbG9z"
2006 "aW5nVHlwZQANZmllbGRDYWxsU2l0ZQAKZmluZFN0YXRpYwASaW52b2tlTWV0aG9kSGFuZGxlAARr"
2007 "aW5kAAxsaW5rZXJNZXRob2QABmxvb2t1cAAEbWFpbgAEbmFtZQADb3V0AAdwcmludGxuAApyZXR1"
2008 "cm5UeXBlAAR0ZXN0AAV2YWx1ZQAiAAcOAC8GAAAAAAAABw4ANQMAAAAHDqUAPwEABw7wADsABw7w"
2009 "AAABBCAcBhgAGAAYABgAGAAYACYcAR0CBCAcAxgPGAkYESMYBCcbACsXKCsXHy4YAAIFATAcARgL"
2010 "ARMAAxYAFx8VAAEABAEBCQCBgAS0BQEKzAUBCuwFAQmcBgQBzAYAAAATAAAAAAAAAAEAAAAAAAAA"
2011 "AQAAADEAAABwAAAAAgAAABYAAAA0AQAAAwAAAAkAAACMAQAABAAAAAMAAAD4AQAABQAAAAsAAAAQ"
2012 "AgAABwAAAAIAAABoAgAABgAAAAEAAABwAgAACAAAAAEAAACQAgAAAxAAAAMAAACYAgAAASAAAAUA"
2013 "AAC0AgAABiAAAAEAAAB8AwAAARAAAAcAAACkAwAAAiAAADEAAADqAwAAAyAAAAUAAABtBwAABCAA"
2014 "AAMAAACTBwAABSAAAAEAAADOBwAAACAAAAEAAADVBwAAABAAAAEAAAD0BwAA",
2015 // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test004/Tests.java
2016 "ZGV4CjAzOABvUVfbV74qWbSOEsgKP+EzahlNQLW2/8TMDAAAcAAAAHhWNBIAAAAAAAAAAOQLAABS"
2017 "AAAAcAAAAB8AAAC4AQAAEAAAADQCAAADAAAA9AIAABIAAAAMAwAAAQAAAKQDAAAACQAAzAMAANYF"
2018 "AADZBQAA4QUAAOkFAADsBQAA7wUAAPIFAAD1BQAA/AUAAP8FAAAEBgAAEwYAABYGAAAZBgAAHwYA"
2019 "AC8GAABkBgAAjQYAAMAGAADxBgAAJgcAAEUHAABhBwAAeAcAAIoHAACdBwAAsQcAAMUHAADZBwAA"
2020 "8AcAAA0IAAAyCAAAUwgAAHwIAACeCAAAvQgAANcIAADpCAAA7AgAAPgIAAD7CAAAAAkAAAYJAAAM"
2021 "CQAAEAkAABUJAAAaCQAAHgkAACMJAAAnCQAAKgkAADMJAABICQAATQkAAFwJAABqCQAAdgkAAIQJ"
2022 "AACPCQAAmgkAAKYJAACzCQAAygkAANkJAADoCQAA9AkAAAAKAAAKCgAAHgoAACQKAAAyCgAAPQoA"
2023 "AEUKAABLCgAAYgoAAGgKAABtCgAAdgoAAIIKAACOCgAAmwoAAKEKAAADAAAABAAAAAUAAAAGAAAA"
2024 "CAAAAAsAAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABgAAAAZAAAAGgAAABsAAAAc"
2025 "AAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJwAAADEAAAAzAAAACQAAAAQA"
2026 "AABMBQAADgAAABMAAABUBQAADQAAABUAAAB0BQAADAAAABYAAAAAAAAAJwAAABwAAAAAAAAAKAAA"
2027 "ABwAAACABQAAKQAAABwAAACIBQAAKgAAABwAAACUBQAAKwAAABwAAACgBQAALAAAABwAAABMBQAA"
2028 "LQAAABwAAACoBQAALwAAABwAAACwBQAALwAAABwAAAC4BQAALgAAABwAAADABQAAMAAAABwAAADI"
2029 "BQAALgAAABwAAADQBQAACQAJAAoAAAAKABMAPwAAABEADQBLAAAACgAEAAIAAAAKAAAANAAAAAoA"
2030 "AQBFAAAACgAPAEgAAAAKAAQAUAAAAA0ACABMAAAADwAEAAIAAAAUAA0AAgAAABYAAgBAAAAAFwAD"
2031 "AEcAAAAZAAUANgAAABkABgA2AAAAGQAHADYAAAAZAAkANgAAABkACgA2AAAAGQALADYAAAAZAAwA"
2032 "NgAAABkADgA3AAAAnQsAAJ0LAAAKAAAAAQAAAA8AAAAAAAAAJgAAACQFAADGCwAAAAAAAAQAAAAC"
2033 "AAAAAQAAAN4KAAACAAAAegsAAJILAAACAAAAkgsAAJoLAAABAAEAAQAAAKgKAAAEAAAAcBAGAAAA"
2034 "DgADAAIAAAAAAK0KAAADAAAAkAABAg8AAAAYAA8ABgAAALQKAABTAAAAcRARAAwAEhJxIA0A0gAT"
2035 "AmEAcSAKAOIAEwIABHEgDQDyABISAgAQAHEgDQACABICFAOamTFBAgARAHEwDAADAhYGAAAYApqZ"
2036 "mZmZmQFABQQSAHcGCwACABsCBwAAAAgAFABxIBAAAgAcAgoACAAVAHEgDwACABcCFc1bBwUAFgBx"
2037 "QA4AMhBxAAkAAAAMAhwDCgBuQAgAMroMAiIDFABwIAcAIwARAwAABAABAAIAAADRCgAADAAAAGIA"
2038 "AgASIRIy/CAAACEACgFuIAUAEAAOAAMAAQACAAAA2AoAAAsAAAASIBIx/CABABAACgASUXEgDQAB"
2039 "AA4AAAAAAAAAAAAAAAMAAAAAAAAAAQAAAMwDAAACAAAA1AMAAAQAAADgAwAAAgAAAAQABAANAAAA"
2040 "FgAQABgAHQAAAAEAGwAEAAMAAgAQAA4ABQAAAAMAAAAOABAAGAAAAAIAAAABAAEAAwAAAAIAAgAC"
2041 "AAAAAwAAAAMAAwADAAAAAQAAAAQAAAACAAAABQAFAAIAAAAPAA8AAgAAABAAEAABAAAAFQAAAAEA"
2042 "AAAdAAAAAQAAAB4AASgABjwqPjtKKQAGPGluaXQ+AAFCAAFDAAFEAAFGAAVIZWxsbwABSQADSUlJ"
2043 "AA1JTlZPS0VfU1RBVElDAAFKAAFMAARMTExMAA5MTExMWkJDU0lGRExMSgAzTGNvbS9hbmRyb2lk"
2044 "L2phY2svYW5ub3RhdGlvbnMvQ2FsbGVkQnlJbnZva2VDdXN0b207ACdMY29tL2FuZHJvaWQvamFj"
2045 "ay9hbm5vdGF0aW9ucy9Db25zdGFudDsAMUxjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL0xp"
2046 "bmtlck1ldGhvZEhhbmRsZTsAL0xjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL01ldGhvZEhh"
2047 "bmRsZUtpbmQ7ADNMY29tL2FuZHJvaWQvamFjay9qYXZhNy9pbnZva2VjdXN0b20vdGVzdDAwNC9U"
2048 "ZXN0czsAHUxkYWx2aWsvYW5ub3RhdGlvbi9TaWduYXR1cmU7ABpMZGFsdmlrL2Fubm90YXRpb24v"
2049 "VGhyb3dzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABBMamF2YS9sYW5nL0NsYXNzABFMamF2YS9s"
2050 "YW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZh"
2051 "L2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABtMamF2YS9sYW5nL2ludm9rZS9D"
2052 "YWxsU2l0ZTsAI0xqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGU7AB9MamF2YS9sYW5n"
2053 "L2ludm9rZS9NZXRob2RIYW5kbGU7ACdMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExv"
2054 "b2t1cDsAIExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXM7AB1MamF2YS9sYW5nL2ludm9r"
2055 "ZS9NZXRob2RUeXBlOwAYTGp1bml0L2ZyYW1ld29yay9Bc3NlcnQ7ABBMb3JnL2p1bml0L1Rlc3Q7"
2056 "AAFTAApUZXN0cy5qYXZhAAFWAANWQ0MABFZEREQABFZGRkYAAlZJAANWSUkAA1ZKSgACVkwAA1ZM"
2057 "TAACVloAAVoAB1pCQ1NJRkQAE1tMamF2YS9sYW5nL1N0cmluZzsAA2FkZAANYXJndW1lbnRUeXBl"
2058 "cwAMYXNzZXJ0RXF1YWxzAAphc3NlcnRUcnVlAAxib29sZWFuVmFsdWUACWJ5dGVWYWx1ZQAJY2hh"
2059 "clZhbHVlAApjbGFzc1ZhbHVlAAtkb3VibGVWYWx1ZQAVZW1pdHRlcjogamFjay00LjAtZW5nAA1l"
2060 "bmNsb3NpbmdUeXBlAA1maWVsZENhbGxTaXRlAApmaW5kU3RhdGljAApmbG9hdFZhbHVlAAhpbnRW"
2061 "YWx1ZQASaW52b2tlTWV0aG9kSGFuZGxlAARraW5kAAxsaW5rZXJNZXRob2QACWxvbmdWYWx1ZQAG"
2062 "bG9va3VwAARtYWluABVtZXRob2RIYW5kbGVFeHRyYUFyZ3MABG5hbWUAA291dAAHcHJpbnRsbgAK"
2063 "cmV0dXJuVHlwZQAKc2hvcnRWYWx1ZQALc3RyaW5nVmFsdWUABHRlc3QABXZhbHVlACMABw4ANwIA"
2064 "AAcOAD4NAAAAAAAAAAAAAAAAAAcOPEtaWmmWw4d4h6UAUgEABw60AE4ABw6lAAAGBTUcAhgEGARD"
2065 "HAEdCAQ1HA0YFhgQGBgYHRgAGAEYGxgEGAMYAhgQGA4YBT4YCkQbAEoXRUkcCh0HATgcAT8dBwE5"
2066 "HAEAAR0HATocAQNhHQcBThwBIgAEHQcBQhwBBAEdBwFBHAFwmpkxQR0HATwcAfGamZmZmZkBQB0H"
2067 "AU8cARcHHQcBOxwBGAodBwFGHAFmFc1bB0oXNE0YBAILAVEcCRcAFyAXGhciFzIXGhcXFwEXHQIM"
2068 "AVEcARgSARoADRYAFzQVAAQBBAEEYSQABAQBcJqZMUHxmpmZmZmZAUAXBxgKZhXNWwcBAAQBAQkA"
2069 "gYAE7AcBCoQIAQqcCAEJ1AkEAfwJAAATAAAAAAAAAAEAAAAAAAAAAQAAAFIAAABwAAAAAgAAAB8A"
2070 "AAC4AQAAAwAAABAAAAA0AgAABAAAAAMAAAD0AgAABQAAABIAAAAMAwAABwAAAAIAAACcAwAABgAA"
2071 "AAEAAACkAwAACAAAAAEAAADEAwAAAxAAAAMAAADMAwAAASAAAAUAAADsAwAABiAAAAEAAAAkBQAA"
2072 "ARAAAA0AAABMBQAAAiAAAFIAAADWBQAAAyAAAAUAAACoCgAABCAAAAQAAADeCgAABSAAAAEAAACd"
2073 "CwAAACAAAAEAAADGCwAAABAAAAEAAADkCwAA"
2074};
2075
2076TEST_F(DexFileVerifierTest, InvokeCustomDexSamples) {
2077 for (size_t i = 0; i < arraysize(kInvokeCustomDexFiles); ++i) {
2078 size_t length;
2079 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kInvokeCustomDexFiles[i], &length));
2080 CHECK(dex_bytes != nullptr);
2081 // Note: `dex_file` will be destroyed before `dex_bytes`.
2082 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
2083 std::string error_msg;
2084 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
2085 dex_file->Begin(),
2086 dex_file->Size(),
2087 "good checksum, verify",
2088 /*verify_checksum*/ true,
2089 &error_msg));
2090 // TODO(oth): Test corruptions (b/35308502)
2091 }
2092}
2093
Jeff Hao326c1a22017-05-04 14:12:56 -07002094TEST_F(DexFileVerifierTest, BadStaticFieldInitialValuesArray) {
2095 // Generated DEX file version (037) from:
2096 //
2097 // .class public LBadStaticFieldInitialValuesArray;
2098 // .super Ljava/lang/Object;
2099 //
2100 // # static fields
2101 // .field static final c:C = 'c'
2102 // .field static final i:I = 0x1
2103 // .field static final s:Ljava/lang/String; = "s"
2104 //
2105 // # direct methods
2106 // .method public constructor <init>()V
2107 // .registers 1
2108 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
2109 // return-void
2110 // .end method
2111 //
2112 // Output file was hex edited so that static field "i" has string typing in initial values array.
2113 static const char kDexBase64[] =
2114 "ZGV4CjAzNQBrMi4cCPcMvvXNRw0uI6RRubwMPwgEYXIsAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAL"
2115 "AAAAcAAAAAYAAACcAAAAAQAAALQAAAADAAAAwAAAAAIAAADYAAAAAQAAAOgAAAAkAQAACAEAACAB"
2116 "AAAoAQAAMAEAADMBAAA2AQAAOwEAAE8BAABjAQAAZgEAAGkBAABsAQAAAgAAAAMAAAAEAAAABQAA"
2117 "AAYAAAAHAAAABwAAAAUAAAAAAAAAAgAAAAgAAAACAAEACQAAAAIABAAKAAAAAgAAAAAAAAADAAAA"
2118 "AAAAAAIAAAABAAAAAwAAAAAAAAABAAAAAAAAAHsBAAB0AQAAAQABAAEAAABvAQAABAAAAHAQAQAA"
2119 "AA4ABjxpbml0PgAGQS5qYXZhAAFDAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEv"
2120 "bGFuZy9TdHJpbmc7AAFWAAFjAAFpAAFzAAEABw4AAwNjFwoXCgMAAQAAGAEYARgAgYAEiAIADQAA"
2121 "AAAAAAABAAAAAAAAAAEAAAALAAAAcAAAAAIAAAAGAAAAnAAAAAMAAAABAAAAtAAAAAQAAAADAAAA"
2122 "wAAAAAUAAAACAAAA2AAAAAYAAAABAAAA6AAAAAEgAAABAAAACAEAAAIgAAALAAAAIAEAAAMgAAAB"
2123 "AAAAbwEAAAUgAAABAAAAdAEAAAAgAAABAAAAewEAAAAQAAABAAAAjAEAAA==";
2124
2125 size_t length;
2126 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
2127 CHECK(dex_bytes != nullptr);
2128 // Note: `dex_file` will be destroyed before `dex_bytes`.
2129 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
2130 std::string error_msg;
2131 EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
2132 dex_file->Begin(),
2133 dex_file->Size(),
2134 "bad static field initial values array",
2135 /*verify_checksum*/ true,
2136 &error_msg));
2137}
2138
2139TEST_F(DexFileVerifierTest, GoodStaticFieldInitialValuesArray) {
2140 // Generated DEX file version (037) from:
2141 //
2142 // .class public LGoodStaticFieldInitialValuesArray;
2143 // .super Ljava/lang/Object;
2144 //
2145 // # static fields
2146 // .field static final b:B = 0x1t
2147 // .field static final c:C = 'c'
2148 // .field static final d:D = 0.6
2149 // .field static final f:F = 0.5f
2150 // .field static final i:I = 0x3
2151 // .field static final j:J = 0x4L
2152 // .field static final l1:Ljava/lang/String;
2153 // .field static final l2:Ljava/lang/String; = "s"
2154 // .field static final l3:Ljava/lang/Class; = Ljava/lang/String;
2155 // .field static final s:S = 0x2s
2156 // .field static final z:Z = true
2157 //
2158 // # direct methods
2159 // .method public constructor <init>()V
2160 // .registers 1
2161 // invoke-direct {p0}, Ljava/lang/Object;-><init>()V
2162 // return-void
2163 // .end method
2164 static const char kDexBase64[] =
2165 "ZGV4CjAzNQAwWxLbdhFa1NGiFWjsy5fhUCHxe5QHtPY8AwAAcAAAAHhWNBIAAAAAAAAAAJwCAAAZ"
2166 "AAAAcAAAAA0AAADUAAAAAQAAAAgBAAALAAAAFAEAAAIAAABsAQAAAQAAAHwBAACgAQAAnAEAAJwB"
2167 "AACkAQAApwEAAKoBAACtAQAAsAEAALMBAAC2AQAA2wEAAO4BAAACAgAAFgIAABkCAAAcAgAAHwIA"
2168 "ACICAAAlAgAAKAIAACsCAAAuAgAAMQIAADUCAAA5AgAAPQIAAEACAAABAAAAAgAAAAMAAAAEAAAA"
2169 "BQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADAAAAAsAAAAAAAAABgAAAA4AAAAG"
2170 "AAEADwAAAAYAAgAQAAAABgADABEAAAAGAAQAEgAAAAYABQATAAAABgAJABQAAAAGAAkAFQAAAAYA"
2171 "BwAWAAAABgAKABcAAAAGAAwAGAAAAAYAAAAAAAAACAAAAAAAAAAGAAAAAQAAAAgAAAAAAAAA////"
2172 "/wAAAAB8AgAARAIAAAY8aW5pdD4AAUIAAUMAAUQAAUYAAUkAAUoAI0xHb29kU3RhdGljRmllbGRJ"
2173 "bml0aWFsVmFsdWVzQXJyYXk7ABFMamF2YS9sYW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7"
2174 "ABJMamF2YS9sYW5nL1N0cmluZzsAAVMAAVYAAVoAAWIAAWMAAWQAAWYAAWkAAWoAAmwxAAJsMgAC"
2175 "bDMAAXMAAXoAAAsAAQNj8TMzMzMzM+M/ED8EAwYEHhcXGAkCAj8AAAAAAQABAAEAAAAAAAAABAAA"
2176 "AHAQAQAAAA4ACwABAAAYARgBGAEYARgBGAEYARgBGAEYARgAgYAE5AQNAAAAAAAAAAEAAAAAAAAA"
2177 "AQAAABkAAABwAAAAAgAAAA0AAADUAAAAAwAAAAEAAAAIAQAABAAAAAsAAAAUAQAABQAAAAIAAABs"
2178 "AQAABgAAAAEAAAB8AQAAAiAAABkAAACcAQAABSAAAAEAAABEAgAAAxAAAAEAAABgAgAAASAAAAEA"
2179 "AABkAgAAACAAAAEAAAB8AgAAABAAAAEAAACcAgAA";
2180
2181 size_t length;
2182 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kDexBase64, &length));
2183 CHECK(dex_bytes != nullptr);
2184 // Note: `dex_file` will be destroyed before `dex_bytes`.
2185 std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
2186 std::string error_msg;
2187 EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
2188 dex_file->Begin(),
2189 dex_file->Size(),
2190 "good static field initial values array",
2191 /*verify_checksum*/ true,
2192 &error_msg));
2193}
2194
Andreas Gampedf10b322014-06-11 21:46:05 -07002195} // namespace art