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