blob: 1a73062068cd90370fd24f72b90f8ecf77e3fd0e [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Carl Shapiro1fb86202011-06-27 17:43:13 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "dex_file.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070018
Andreas Gamped4901292017-05-30 18:41:34 -070019#include <sys/mman.h>
20
Ian Rogers700a4022014-05-19 16:49:03 -070021#include <memory>
22
Ian Rogerse63db272014-07-15 15:36:11 -070023#include "base/stl_util.h"
24#include "base/unix_file/fd_file.h"
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080025#include "common_runtime_test.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080026#include "dex_file-inl.h"
Orion Hodsona4c2a052016-08-17 10:51:42 +010027#include "mem_map.h"
Ian Rogerse63db272014-07-15 15:36:11 -070028#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070029#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070030#include "thread-current-inl.h"
Alex Light9c20a142016-08-23 15:05:12 -070031#include "utils.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070032
Carl Shapiro1fb86202011-06-27 17:43:13 -070033namespace art {
34
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080035class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070036
37TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070038 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080039 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070040 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070041}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070042
Alex Light9c20a142016-08-23 15:05:12 -070043static inline std::vector<uint8_t> DecodeBase64Vec(const char* src) {
44 std::vector<uint8_t> res;
45 size_t size;
46 std::unique_ptr<uint8_t[]> data(DecodeBase64(src, &size));
47 res.resize(size);
48 memcpy(res.data(), data.get(), size);
49 return res;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080050}
51
Brian Carlstrom9f30b382011-08-28 22:41:38 -070052// Although this is the same content logically as the Nested test dex,
53// the DexFileHeader test is sensitive to subtle changes in the
54// contents due to the checksum etc, so we embed the exact input here.
55//
56// class Nested {
57// class Inner {
58// }
59// }
60static const char kRawDex[] =
61 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
62 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
63 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
64 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
65 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
66 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
67 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
68 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
69 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
70 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
71 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
72 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
73 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
74 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
75 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
76 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
77
Narayan Kamath52e66502016-08-01 14:20:31 +010078// kRawDex38 and 39 are dex'ed versions of the following Java source :
79//
80// public class Main {
81// public static void main(String[] foo) {
82// }
83// }
84//
85// The dex file was manually edited to change its dex version code to 38
86// or 39, respectively.
87static const char kRawDex38[] =
88 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
89 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
90 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
91 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
92 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
93 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
94 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
95 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
96 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
97 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
98
99static const char kRawDex39[] =
100 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
101 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
102 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
103 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
104 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
105 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
106 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
107 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
108 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
109 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
110
ganxiaolincd16d0a2016-07-18 11:21:44 +0800111static const char kRawDexZeroLength[] =
112 "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
113 "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
114 "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
115 "AA==";
116
David Sehr9fddd362016-09-22 14:05:37 -0700117static const char kRawZipClassesDexPresent[] =
118 "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VXdXgL"
119 "AAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMDQ0WY"
120 "iRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEIEEcA"
121 "cS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu4IOa"
122 "wczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhHIykL"
123 "LinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkVIGpA"
124 "Yc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEBAAAg"
125 "AgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEABIgTAABQ"
126 "SwUGAAAAAAEAAQBRAAAAdgEAAAAA";
127
128static const char kRawZipClassesDexAbsent[] =
129 "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAAOABwAbm90Y2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VX"
130 "dXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMD"
131 "Q0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEI"
132 "EEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu"
133 "4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhH"
134 "IykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkV"
135 "IGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEB"
136 "AAAgAgAADgAYAAAAAAAAAAAAoIEAAAAAbm90Y2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEA"
137 "BIgTAABQSwUGAAAAAAEAAQBUAAAAeQEAAAAA";
138
139static const char kRawZipThreeDexFiles[] =
140 "UEsDBBQAAAAIAP1WN0ms99lIMQEAACACAAAMABwAY2xhc3NlczIuZGV4VVQJAAOtbOVXrWzlV3V4"
141 "CwABBOQDAQAEiBMAAEtJreAyMLZg2GHVfXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NF"
142 "mIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBAAGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBH"
143 "AHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiDHWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCD"
144 "msHMwGaTmZdZYsfA5uObmJlnzSDkk5VYlqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMp"
145 "Cy4pysxLt2ZgyQUqAzmYj4EZTIL909jA8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBq"
146 "QGHOKAARB4UbkwLETFA8MEPVgMKCQQGiBhxOUPWgeAYAUEsDBBQAAAAIAABXN0ms99lIMQEAACAC"
147 "AAAMABwAY2xhc3NlczMuZGV4VVQJAAOvbOVXr2zlV3V4CwABBOQDAQAEiBMAAEtJreAyMLZg2GHV"
148 "fXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NFmIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBA"
149 "AGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBHAHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiD"
150 "HWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCDmsHMwGaTmZdZYsfA5uObmJlnzSDkk5VY"
151 "lqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMpCy4pysxLt2ZgyQUqAzmYj4EZTIL909jA"
152 "8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBqQGHOKAARB4UbkwLETFA8MEPVgMKCQQGi"
153 "BhxOUPWgeAYAUEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj"
154 "5VetbOVXdXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQC"
155 "EwNDAQMDQ0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGx"
156 "GxAHAnEIEEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8"
157 "UFGgP6Fu4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYx"
158 "MIX5MAhHIykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHC"
159 "mg0pvBkVIGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACAD9VjdJ"
160 "rPfZSDEBAAAgAgAADAAYAAAAAAAAAAAAoIEAAAAAY2xhc3NlczIuZGV4VVQFAAOtbOVXdXgLAAEE"
161 "5AMBAASIEwAAUEsBAh4DFAAAAAgAAFc3Saz32UgxAQAAIAIAAAwAGAAAAAAAAAAAAKCBdwEAAGNs"
162 "YXNzZXMzLmRleFVUBQADr2zlV3V4CwABBOQDAQAEiBMAAFBLAQIeAxQAAAAIANVRN0ms99lIMQEA"
163 "ACACAAALABgAAAAAAAAAAACgge4CAABjbGFzc2VzLmRleFVUBQADAWPlV3V4CwABBOQDAQAEiBMA"
164 "AFBLBQYAAAAAAwADAPUAAABkBAAAAAA=";
165
Jeff Haoa4cd6772017-04-13 14:36:29 -0700166static const char kRawDexBadMapOffset[] =
167 "ZGV4CjAzNQAZKGSz85r+tXJ1I24FYi+FpQtWbXtelAmoAQAAcAAAAHhWNBIAAAAAAAAAAEAwIBAF"
168 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADcAAAAzAAAAOQA"
169 "AADsAAAA9AAAAPkAAAANAQAAAgAAAAMAAAAEAAAABAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAA"
170 "AAAAAAABAAAAAQAAAAAAAAABAAAAAAAAABUBAAAAAAAAAQABAAEAAAAQAQAABAAAAHAQAQAAAA4A"
171 "Bjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABAAcOAAAAAQAAgYAE"
172 "zAEACwAAAAAAAAABAAAAAAAAAAEAAAAFAAAAcAAAAAIAAAADAAAAhAAAAAMAAAABAAAAkAAAAAUA"
173 "AAACAAAAnAAAAAYAAAABAAAArAAAAAEgAAABAAAAzAAAAAIgAAAFAAAA5AAAAAMgAAABAAAAEAEA"
174 "AAAgAAABAAAAFQEAAAAQAAABAAAAIAEAAA==";
175
Jeff Haoc1225362017-05-01 17:29:35 -0700176static const char kRawDexDebugInfoLocalNullType[] =
177 "ZGV4CjAzNQA+Kwj2g6OZMH88OvK9Ey6ycdIsFCt18ED8AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
178 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
179 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
180 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
181 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
182 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
183 "Bw4AAwAHDh4DAAcAAAAAAQEAgYAE8AEBAIgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
184 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
185 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
186
Narayan Kamath52e66502016-08-01 14:20:31 +0100187static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700188 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700189 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700190 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100191 CHECK_NE(dex_bytes.size(), 0u);
Ian Rogers33e95662013-05-20 20:29:14 -0700192
193 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700194 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700195 CHECK(file.get() != nullptr);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100196 if (!file->WriteFully(dex_bytes.data(), dex_bytes.size())) {
Ian Rogers33e95662013-05-20 20:29:14 -0700197 PLOG(FATAL) << "Failed to write base64 as dex file";
198 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800199 if (file->FlushCloseOrErase() != 0) {
200 PLOG(FATAL) << "Could not flush and close test file.";
201 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100202}
203
David Sehr9fddd362016-09-22 14:05:37 -0700204static bool OpenDexFilesBase64(const char* base64,
205 const char* location,
206 std::vector<std::unique_ptr<const DexFile>>* dex_files,
207 std::string* error_msg) {
Narayan Kamath52e66502016-08-01 14:20:31 +0100208 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700209
David Sehr9fddd362016-09-22 14:05:37 -0700210 // read dex file(s)
Ian Rogers33e95662013-05-20 20:29:14 -0700211 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700212 static constexpr bool kVerifyChecksum = true;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800213 std::vector<std::unique_ptr<const DexFile>> tmp;
David Sehr9fddd362016-09-22 14:05:37 -0700214 bool success = DexFile::Open(location, location, kVerifyChecksum, error_msg, &tmp);
215 if (success) {
216 for (std::unique_ptr<const DexFile>& dex_file : tmp) {
217 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
218 EXPECT_TRUE(dex_file->IsReadOnly());
219 }
220 *dex_files = std::move(tmp);
221 }
222 return success;
223}
224
225static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
226 const char* location) {
227 // read dex files.
228 std::string error_msg;
229 std::vector<std::unique_ptr<const DexFile>> dex_files;
230 bool success = OpenDexFilesBase64(base64, location, &dex_files, &error_msg);
Andreas Gampe833a4852014-05-21 18:46:59 -0700231 CHECK(success) << error_msg;
David Sehr9fddd362016-09-22 14:05:37 -0700232 EXPECT_EQ(1U, dex_files.size());
233 return std::move(dex_files[0]);
Ian Rogers33e95662013-05-20 20:29:14 -0700234}
235
Orion Hodsona4c2a052016-08-17 10:51:42 +0100236static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
237 const char* location,
Jeff Haoa4cd6772017-04-13 14:36:29 -0700238 uint32_t location_checksum,
239 bool expect_success) {
Orion Hodsona4c2a052016-08-17 10:51:42 +0100240 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700241 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100242 CHECK_NE(dex_bytes.size(), 0u);
243
244 std::string error_message;
245 std::unique_ptr<MemMap> region(MemMap::MapAnonymous("test-region",
246 nullptr,
247 dex_bytes.size(),
248 PROT_READ | PROT_WRITE,
249 /* low_4gb */ false,
250 /* reuse */ false,
251 &error_message));
252 memcpy(region->Begin(), dex_bytes.data(), dex_bytes.size());
253 std::unique_ptr<const DexFile> dex_file(DexFile::Open(location,
254 location_checksum,
255 std::move(region),
256 /* verify */ true,
257 /* verify_checksum */ true,
258 &error_message));
Jeff Haoa4cd6772017-04-13 14:36:29 -0700259 if (expect_success) {
260 CHECK(dex_file != nullptr) << error_message;
261 } else {
262 CHECK(dex_file == nullptr) << "Expected dex file open to fail.";
263 }
Orion Hodsona4c2a052016-08-17 10:51:42 +0100264 return dex_file;
265}
266
Orion Hodsoncffc5292016-09-05 13:43:11 +0100267static void ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file) {
268 static const uint8_t kExpectedDexFileMagic[8] = {
269 /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
270 /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
271 };
272 static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
273 0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
274 0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
275 0x2e, 0xf2, 0x8c, 0x3d,
276 };
Orion Hodsona4c2a052016-08-17 10:51:42 +0100277
Orion Hodsoncffc5292016-09-05 13:43:11 +0100278 const DexFile::Header& header = dex_file->GetHeader();
279 EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100280 EXPECT_EQ(0x00d87910U, header.checksum_);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100281 EXPECT_EQ(*kExpectedSha1, *header.signature_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100282 EXPECT_EQ(904U, header.file_size_);
283 EXPECT_EQ(112U, header.header_size_);
284 EXPECT_EQ(0U, header.link_size_);
285 EXPECT_EQ(0U, header.link_off_);
286 EXPECT_EQ(15U, header.string_ids_size_);
287 EXPECT_EQ(112U, header.string_ids_off_);
288 EXPECT_EQ(7U, header.type_ids_size_);
289 EXPECT_EQ(172U, header.type_ids_off_);
290 EXPECT_EQ(2U, header.proto_ids_size_);
291 EXPECT_EQ(200U, header.proto_ids_off_);
292 EXPECT_EQ(1U, header.field_ids_size_);
293 EXPECT_EQ(224U, header.field_ids_off_);
294 EXPECT_EQ(3U, header.method_ids_size_);
295 EXPECT_EQ(232U, header.method_ids_off_);
296 EXPECT_EQ(2U, header.class_defs_size_);
297 EXPECT_EQ(256U, header.class_defs_off_);
298 EXPECT_EQ(584U, header.data_size_);
299 EXPECT_EQ(320U, header.data_off_);
300
Orion Hodsoncffc5292016-09-05 13:43:11 +0100301 EXPECT_EQ(header.checksum_, dex_file->GetLocationChecksum());
302}
303
304TEST_F(DexFileTest, Header) {
305 ScratchFile tmp;
306 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
307 ValidateDexFileHeader(std::move(raw));
Orion Hodsona4c2a052016-08-17 10:51:42 +0100308}
309
310TEST_F(DexFileTest, HeaderInMemory) {
311 ScratchFile tmp;
312 std::unique_ptr<const DexFile> raw =
Jeff Haoa4cd6772017-04-13 14:36:29 -0700313 OpenDexFileInMemoryBase64(kRawDex, tmp.GetFilename().c_str(), 0x00d87910U, true);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100314 ValidateDexFileHeader(std::move(raw));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800315}
316
Narayan Kamath52e66502016-08-01 14:20:31 +0100317TEST_F(DexFileTest, Version38Accepted) {
318 ScratchFile tmp;
319 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
320 ASSERT_TRUE(raw.get() != nullptr);
321
322 const DexFile::Header& header = raw->GetHeader();
323 EXPECT_EQ(38u, header.GetVersion());
324}
325
326TEST_F(DexFileTest, Version39Rejected) {
327 ScratchFile tmp;
328 const char* location = tmp.GetFilename().c_str();
329 DecodeAndWriteDexFile(kRawDex39, location);
330
331 ScopedObjectAccess soa(Thread::Current());
332 static constexpr bool kVerifyChecksum = true;
333 std::string error_msg;
334 std::vector<std::unique_ptr<const DexFile>> dex_files;
335 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
336}
337
ganxiaolincd16d0a2016-07-18 11:21:44 +0800338TEST_F(DexFileTest, ZeroLengthDexRejected) {
339 ScratchFile tmp;
340 const char* location = tmp.GetFilename().c_str();
341 DecodeAndWriteDexFile(kRawDexZeroLength, location);
342
343 ScopedObjectAccess soa(Thread::Current());
344 static constexpr bool kVerifyChecksum = true;
345 std::string error_msg;
346 std::vector<std::unique_ptr<const DexFile>> dex_files;
347 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
348}
349
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800350TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700351 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800352 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800353 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
354}
355
356TEST_F(DexFileTest, GetChecksum) {
Richard Uhler84f50ae2017-02-06 15:12:45 +0000357 std::vector<uint32_t> checksums;
Ian Rogers33e95662013-05-20 20:29:14 -0700358 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700359 std::string error_msg;
Richard Uhler84f50ae2017-02-06 15:12:45 +0000360 EXPECT_TRUE(DexFile::GetMultiDexChecksums(GetLibCoreDexFileNames()[0].c_str(), &checksums, &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700361 << error_msg;
Richard Uhler84f50ae2017-02-06 15:12:45 +0000362 ASSERT_EQ(1U, checksums.size());
363 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksums[0]);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700364}
365
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000366TEST_F(DexFileTest, GetMultiDexChecksums) {
367 std::string error_msg;
368 std::vector<uint32_t> checksums;
369 std::string multidex_file = GetTestDexFileName("MultiDex");
370 EXPECT_TRUE(DexFile::GetMultiDexChecksums(multidex_file.c_str(),
371 &checksums,
372 &error_msg)) << error_msg;
373
Richard Uhler84f50ae2017-02-06 15:12:45 +0000374 std::vector<std::unique_ptr<const DexFile>> dexes = OpenTestDexFiles("MultiDex");
375 ASSERT_EQ(2U, dexes.size());
376 ASSERT_EQ(2U, checksums.size());
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000377
Richard Uhler84f50ae2017-02-06 15:12:45 +0000378 EXPECT_EQ(dexes[0]->GetLocation(), DexFile::GetMultiDexLocation(0, multidex_file.c_str()));
379 EXPECT_EQ(dexes[0]->GetLocationChecksum(), checksums[0]);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000380
Richard Uhler84f50ae2017-02-06 15:12:45 +0000381 EXPECT_EQ(dexes[1]->GetLocation(), DexFile::GetMultiDexLocation(1, multidex_file.c_str()));
382 EXPECT_EQ(dexes[1]->GetLocationChecksum(), checksums[1]);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000383}
384
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700385TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700386 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800387 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
388 ASSERT_TRUE(raw.get() != nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800389 EXPECT_EQ(3U, raw->NumClassDefs());
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700390
Brian Carlstromf615a612011-07-23 12:50:34 -0700391 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800392 EXPECT_STREQ("LNested$1;", raw->GetClassDescriptor(c0));
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700393
Brian Carlstromf615a612011-07-23 12:50:34 -0700394 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800395 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c1));
396
397 const DexFile::ClassDef& c2 = raw->GetClassDef(2);
398 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c2));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700399}
400
Ian Rogersd91d6d62013-09-25 20:26:14 -0700401TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700402 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800403 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
404 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700405 EXPECT_EQ(1U, raw->NumClassDefs());
406
407 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700408 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700409
Ian Rogers13735952014-10-08 12:43:28 -0700410 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700411 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800412 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700413
Ian Rogers0571d352011-11-03 19:51:38 -0700414 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700415
Ian Rogers0571d352011-11-03 19:51:38 -0700416 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700417 {
Ian Rogers0571d352011-11-03 19:51:38 -0700418 ASSERT_EQ(1U, it.NumDirectMethods());
419 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700420 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700421 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700422 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700423 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700424 }
425
426 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700427 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700428 {
Ian Rogers0571d352011-11-03 19:51:38 -0700429 it.Next();
430 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700431
Ian Rogers0571d352011-11-03 19:51:38 -0700432 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700433 ASSERT_STREQ("m1", name);
434
Ian Rogersd91d6d62013-09-25 20:26:14 -0700435 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700436 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700437 }
438
439 {
Ian Rogers0571d352011-11-03 19:51:38 -0700440 it.Next();
441 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700442
Ian Rogers0571d352011-11-03 19:51:38 -0700443 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700444 ASSERT_STREQ("m2", name);
445
Ian Rogersd91d6d62013-09-25 20:26:14 -0700446 std::string signature(raw->GetMethodSignature(method_id).ToString());
447 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700448 }
449}
450
451TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700452 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800453 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
454 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700455 EXPECT_EQ(1U, raw->NumClassDefs());
456
Ian Rogersd91d6d62013-09-25 20:26:14 -0700457 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700458 "D", "I", "J", nullptr };
459 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700460 const char* str = strings[i];
461 const DexFile::StringId* str_id = raw->FindStringId(str);
462 const char* dex_str = raw->GetStringData(*str_id);
463 EXPECT_STREQ(dex_str, str);
464 }
465}
466
467TEST_F(DexFileTest, FindTypeId) {
468 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800469 const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i));
Ian Rogers0571d352011-11-03 19:51:38 -0700470 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700471 ASSERT_TRUE(type_str_id != nullptr);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800472 dex::StringIndex type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
Ian Rogers0571d352011-11-03 19:51:38 -0700473 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700474 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700475 ASSERT_TRUE(type_id != nullptr);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800476 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i);
Ian Rogers0571d352011-11-03 19:51:38 -0700477 }
478}
479
480TEST_F(DexFileTest, FindProtoId) {
481 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
482 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
483 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800484 std::vector<dex::TypeIndex> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700485 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700486 for (size_t j = 0; j < to_find_tl->Size(); j++) {
487 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
488 }
489 }
490 const DexFile::ProtoId* found =
491 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700492 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700493 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
494 }
495}
496
497TEST_F(DexFileTest, FindMethodId) {
498 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
499 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
500 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
501 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
502 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
503 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700504 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700505 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
506 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700507 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700508 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700509 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700510}
511
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800512TEST_F(DexFileTest, FindFieldId) {
513 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
514 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
515 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
516 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
517 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
518 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700519 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800520 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
521 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
522 << java_lang_dex_file_->GetStringData(name);
523 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
524 }
525}
526
Calin Juravle4e1d5792014-07-15 23:56:47 +0100527TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Andreas Gampe90e34042015-04-27 20:01:52 -0700528 ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
529 ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
530 ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
531 ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
532}
533
534TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100535 std::string dex_location_str = "/system/app/framework.jar";
536 const char* dex_location = dex_location_str.c_str();
Andreas Gampe90e34042015-04-27 20:01:52 -0700537 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
Calin Juravlea308a322017-07-18 16:51:51 -0700538 ASSERT_EQ("/system/app/framework.jar!classes2.dex",
Andreas Gampe90e34042015-04-27 20:01:52 -0700539 DexFile::GetMultiDexLocation(1, dex_location));
Calin Juravlea308a322017-07-18 16:51:51 -0700540 ASSERT_EQ("/system/app/framework.jar!classes101.dex",
Andreas Gampe90e34042015-04-27 20:01:52 -0700541 DexFile::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100542}
543
544TEST_F(DexFileTest, GetDexCanonicalLocation) {
545 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100546 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
547 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100548
Calin Juravle61281dc2014-08-07 11:54:36 +0100549 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Andreas Gampe90e34042015-04-27 20:01:52 -0700550 std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100551 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
552
553 std::string dex_location_sym = dex_location + "symlink";
554 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
555
556 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
557
Andreas Gampe90e34042015-04-27 20:01:52 -0700558 std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100559 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
560
561 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
562}
563
Richard Uhlere5fed032015-03-18 08:21:11 -0700564TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
565 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
Calin Juravlea308a322017-07-18 16:51:51 -0700566 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar!classes2.dex"));
567 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar!classes8.dex"));
Richard Uhlere5fed032015-03-18 08:21:11 -0700568 EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
Calin Juravlea308a322017-07-18 16:51:51 -0700569 EXPECT_EQ("!classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar!classes2.dex"));
570 EXPECT_EQ("!classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar!classes8.dex"));
Richard Uhlere5fed032015-03-18 08:21:11 -0700571}
572
David Sehr9fddd362016-09-22 14:05:37 -0700573TEST_F(DexFileTest, ZipOpenClassesPresent) {
574 ScratchFile tmp;
575 std::vector<std::unique_ptr<const DexFile>> dex_files;
576 std::string error_msg;
577 ASSERT_TRUE(OpenDexFilesBase64(kRawZipClassesDexPresent, tmp.GetFilename().c_str(), &dex_files,
578 &error_msg));
579 EXPECT_EQ(dex_files.size(), 1u);
580}
581
582TEST_F(DexFileTest, ZipOpenClassesAbsent) {
583 ScratchFile tmp;
584 std::vector<std::unique_ptr<const DexFile>> dex_files;
585 std::string error_msg;
586 ASSERT_FALSE(OpenDexFilesBase64(kRawZipClassesDexAbsent, tmp.GetFilename().c_str(), &dex_files,
587 &error_msg));
588 EXPECT_EQ(dex_files.size(), 0u);
589}
590
591TEST_F(DexFileTest, ZipOpenThreeDexFiles) {
592 ScratchFile tmp;
593 std::vector<std::unique_ptr<const DexFile>> dex_files;
594 std::string error_msg;
595 ASSERT_TRUE(OpenDexFilesBase64(kRawZipThreeDexFiles, tmp.GetFilename().c_str(), &dex_files,
596 &error_msg));
597 EXPECT_EQ(dex_files.size(), 3u);
598}
599
Jeff Haoa4cd6772017-04-13 14:36:29 -0700600TEST_F(DexFileTest, OpenDexBadMapOffset) {
601 ScratchFile tmp;
602 std::unique_ptr<const DexFile> raw =
603 OpenDexFileInMemoryBase64(kRawDexBadMapOffset, tmp.GetFilename().c_str(), 0xb3642819U, false);
604 EXPECT_EQ(raw, nullptr);
605}
606
Jeff Hao120504f2017-04-14 14:33:52 -0700607TEST_F(DexFileTest, GetStringWithNoIndex) {
608 ScratchFile tmp;
609 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
610 dex::TypeIndex idx;
611 EXPECT_EQ(raw->StringByTypeIdx(idx), nullptr);
612}
613
Jeff Haoc1225362017-05-01 17:29:35 -0700614static void Callback(void* context ATTRIBUTE_UNUSED,
615 const DexFile::LocalInfo& entry ATTRIBUTE_UNUSED) {
616}
617
618TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) {
619 ScratchFile tmp;
620 std::unique_ptr<const DexFile> raw = OpenDexFileInMemoryBase64(
621 kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true);
622 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
623 const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1));
624 ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, true, 1, Callback, nullptr));
625}
626
Carl Shapiro1fb86202011-06-27 17:43:13 -0700627} // namespace art