1 /*
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.h"
18 
19 #include <memory>
20 
21 #include "base64_test_util.h"
22 #include "code_item_accessors-inl.h"
23 #include "descriptors_names.h"
24 #include "dex_file-inl.h"
25 #include "dex_file_loader.h"
26 #include "gtest/gtest.h"
27 
28 namespace art {
29 
30 class DexFileLoaderTest : public testing::Test {};
31 
32 static constexpr char kLocationString[] = "/a/dex/file/location";
33 
DecodeBase64Vec(const char * src)34 static inline std::vector<uint8_t> DecodeBase64Vec(const char* src) {
35   std::vector<uint8_t> res;
36   size_t size;
37   std::unique_ptr<uint8_t[]> data(DecodeBase64(src, &size));
38   res.resize(size);
39   memcpy(res.data(), data.get(), size);
40   return res;
41 }
42 
43 // Although this is the same content logically as the Nested test dex,
44 // the DexFileHeader test is sensitive to subtle changes in the
45 // contents due to the checksum etc, so we embed the exact input here.
46 //
47 // class Nested {
48 //     class Inner {
49 //     }
50 // }
51 static const char kRawDex[] =
52   "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
53   "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
54   "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
55   "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
56   "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
57   "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
58   "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
59   "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
60   "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
61   "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
62   "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
63   "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
64   "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
65   "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
66   "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
67   "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
68 
69 // kRawDex{38,39,40,41} are dex'ed versions of the following Java source :
70 //
71 // public class Main {
72 //     public static void main(String[] foo) {
73 //     }
74 // }
75 //
76 // The dex file was manually edited to change its dex version code to 38
77 // or 39, respectively.
78 static const char kRawDex38[] =
79   "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
80   "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
81   "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
82   "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
83   "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
84   "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
85   "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
86   "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
87   "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
88   "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
89 
90 static const char kRawDex39[] =
91   "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
92   "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
93   "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
94   "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
95   "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
96   "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
97   "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
98   "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
99   "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
100   "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
101 
102 static const char kRawDex40[] =
103   "ZGV4CjA0MAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
104   "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
105   "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
106   "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
107   "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
108   "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
109   "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
110   "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
111   "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
112   "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
113 
114 static const char kRawDex41[] =
115   "ZGV4CjA0MQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
116   "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
117   "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
118   "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
119   "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
120   "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
121   "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
122   "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
123   "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
124   "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
125 
126 static const char kRawDexZeroLength[] =
127   "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
128   "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
129   "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
130   "AA==";
131 
132 static const char kRawZipClassesDexPresent[] =
133   "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VXdXgL"
134   "AAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMDQ0WY"
135   "iRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEIEEcA"
136   "cS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu4IOa"
137   "wczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhHIykL"
138   "LinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkVIGpA"
139   "Yc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEBAAAg"
140   "AgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEABIgTAABQ"
141   "SwUGAAAAAAEAAQBRAAAAdgEAAAAA";
142 
143 static const char kRawZipClassesDexAbsent[] =
144   "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAAOABwAbm90Y2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VX"
145   "dXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMD"
146   "Q0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEI"
147   "EEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu"
148   "4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhH"
149   "IykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkV"
150   "IGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEB"
151   "AAAgAgAADgAYAAAAAAAAAAAAoIEAAAAAbm90Y2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEA"
152   "BIgTAABQSwUGAAAAAAEAAQBUAAAAeQEAAAAA";
153 
154 static const char kRawZipThreeDexFiles[] =
155   "UEsDBBQAAAAIAP1WN0ms99lIMQEAACACAAAMABwAY2xhc3NlczIuZGV4VVQJAAOtbOVXrWzlV3V4"
156   "CwABBOQDAQAEiBMAAEtJreAyMLZg2GHVfXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NF"
157   "mIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBAAGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBH"
158   "AHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiDHWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCD"
159   "msHMwGaTmZdZYsfA5uObmJlnzSDkk5VYlqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMp"
160   "Cy4pysxLt2ZgyQUqAzmYj4EZTIL909jA8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBq"
161   "QGHOKAARB4UbkwLETFA8MEPVgMKCQQGiBhxOUPWgeAYAUEsDBBQAAAAIAABXN0ms99lIMQEAACAC"
162   "AAAMABwAY2xhc3NlczMuZGV4VVQJAAOvbOVXr2zlV3V4CwABBOQDAQAEiBMAAEtJreAyMLZg2GHV"
163   "fXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NFmIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBA"
164   "AGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBHAHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiD"
165   "HWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCDmsHMwGaTmZdZYsfA5uObmJlnzSDkk5VY"
166   "lqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMpCy4pysxLt2ZgyQUqAzmYj4EZTIL909jA"
167   "8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBqQGHOKAARB4UbkwLETFA8MEPVgMKCQQGi"
168   "BhxOUPWgeAYAUEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj"
169   "5VetbOVXdXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQC"
170   "EwNDAQMDQ0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGx"
171   "GxAHAnEIEEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8"
172   "UFGgP6Fu4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYx"
173   "MIX5MAhHIykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHC"
174   "mg0pvBkVIGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACAD9VjdJ"
175   "rPfZSDEBAAAgAgAADAAYAAAAAAAAAAAAoIEAAAAAY2xhc3NlczIuZGV4VVQFAAOtbOVXdXgLAAEE"
176   "5AMBAASIEwAAUEsBAh4DFAAAAAgAAFc3Saz32UgxAQAAIAIAAAwAGAAAAAAAAAAAAKCBdwEAAGNs"
177   "YXNzZXMzLmRleFVUBQADr2zlV3V4CwABBOQDAQAEiBMAAFBLAQIeAxQAAAAIANVRN0ms99lIMQEA"
178   "ACACAAALABgAAAAAAAAAAACgge4CAABjbGFzc2VzLmRleFVUBQADAWPlV3V4CwABBOQDAQAEiBMA"
179   "AFBLBQYAAAAAAwADAPUAAABkBAAAAAA=";
180 
181 static const char kRawDexBadMapOffset[] =
182   "ZGV4CjAzNQAZKGSz85r+tXJ1I24FYi+FpQtWbXtelAmoAQAAcAAAAHhWNBIAAAAAAAAAAEAwIBAF"
183   "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADcAAAAzAAAAOQA"
184   "AADsAAAA9AAAAPkAAAANAQAAAgAAAAMAAAAEAAAABAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAA"
185   "AAAAAAABAAAAAQAAAAAAAAABAAAAAAAAABUBAAAAAAAAAQABAAEAAAAQAQAABAAAAHAQAQAAAA4A"
186   "Bjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABAAcOAAAAAQAAgYAE"
187   "zAEACwAAAAAAAAABAAAAAAAAAAEAAAAFAAAAcAAAAAIAAAADAAAAhAAAAAMAAAABAAAAkAAAAAUA"
188   "AAACAAAAnAAAAAYAAAABAAAArAAAAAEgAAABAAAAzAAAAAIgAAAFAAAA5AAAAAMgAAABAAAAEAEA"
189   "AAAgAAABAAAAFQEAAAAQAAABAAAAIAEAAA==";
190 
191 static const char kRawDexDebugInfoLocalNullType[] =
192     "ZGV4CjAzNQA+Kwj2g6OZMH88OvK9Ey6ycdIsFCt18ED8AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
193     "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
194     "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
195     "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
196     "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
197     "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
198     "Bw4AAwAHDh4DAAcAAAAAAQEAgYAE8AEBAIgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
199     "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
200     "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
201 
DecodeDexFile(const char * base64,std::vector<uint8_t> * dex_bytes)202 static void DecodeDexFile(const char* base64, std::vector<uint8_t>* dex_bytes) {
203   // decode base64
204   CHECK(base64 != nullptr);
205   *dex_bytes = DecodeBase64Vec(base64);
206   CHECK_NE(dex_bytes->size(), 0u);
207 }
208 
OpenDexFilesBase64(const char * base64,const char * location,std::vector<uint8_t> * dex_bytes,std::vector<std::unique_ptr<const DexFile>> * dex_files,DexFileLoaderErrorCode * error_code,std::string * error_msg)209 static bool OpenDexFilesBase64(const char* base64,
210                                const char* location,
211                                std::vector<uint8_t>* dex_bytes,
212                                std::vector<std::unique_ptr<const DexFile>>* dex_files,
213                                DexFileLoaderErrorCode* error_code,
214                                std::string* error_msg) {
215   DecodeDexFile(base64, dex_bytes);
216 
217   // read dex file(s)
218   static constexpr bool kVerifyChecksum = true;
219   std::vector<std::unique_ptr<const DexFile>> tmp;
220   const DexFileLoader dex_file_loader;
221   bool success = dex_file_loader.OpenAll(dex_bytes->data(),
222                                          dex_bytes->size(),
223                                          location,
224                                          /* verify= */ true,
225                                          kVerifyChecksum,
226                                          error_code,
227                                          error_msg,
228                                          dex_files);
229   return success;
230 }
231 
OpenDexFileBase64(const char * base64,const char * location,std::vector<uint8_t> * dex_bytes)232 static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
233                                                         const char* location,
234                                                         std::vector<uint8_t>* dex_bytes) {
235   // read dex files.
236   DexFileLoaderErrorCode error_code;
237   std::string error_msg;
238   std::vector<std::unique_ptr<const DexFile>> dex_files;
239   bool success = OpenDexFilesBase64(base64, location, dex_bytes, &dex_files, &error_code,
240                                     &error_msg);
241   CHECK(success) << error_msg;
242   EXPECT_EQ(1U, dex_files.size());
243   return std::move(dex_files[0]);
244 }
245 
OpenDexFileInMemoryBase64(const char * base64,const char * location,uint32_t location_checksum,bool expect_success,std::vector<uint8_t> * dex_bytes)246 static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
247                                                                 const char* location,
248                                                                 uint32_t location_checksum,
249                                                                 bool expect_success,
250                                                                 std::vector<uint8_t>* dex_bytes) {
251   DecodeDexFile(base64, dex_bytes);
252 
253   std::string error_message;
254   const DexFileLoader dex_file_loader;
255   std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(dex_bytes->data(),
256                                                                dex_bytes->size(),
257                                                                location,
258                                                                location_checksum,
259                                                                /* oat_dex_file= */ nullptr,
260                                                                /* verify= */ true,
261                                                                /* verify_checksum= */ true,
262                                                                &error_message));
263   if (expect_success) {
264     CHECK(dex_file != nullptr) << error_message;
265   } else {
266     CHECK(dex_file == nullptr) << "Expected dex file open to fail.";
267   }
268   return dex_file;
269 }
270 
ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file)271 static void ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file) {
272   static const uint8_t kExpectedDexFileMagic[8] = {
273     /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
274     /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
275   };
276   static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
277     0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
278     0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
279     0x2e, 0xf2, 0x8c, 0x3d,
280   };
281 
282   const DexFile::Header& header = dex_file->GetHeader();
283   EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
284   EXPECT_EQ(0x00d87910U, header.checksum_);
285   EXPECT_EQ(*kExpectedSha1, *header.signature_);
286   EXPECT_EQ(904U, header.file_size_);
287   EXPECT_EQ(112U, header.header_size_);
288   EXPECT_EQ(0U, header.link_size_);
289   EXPECT_EQ(0U, header.link_off_);
290   EXPECT_EQ(15U, header.string_ids_size_);
291   EXPECT_EQ(112U, header.string_ids_off_);
292   EXPECT_EQ(7U, header.type_ids_size_);
293   EXPECT_EQ(172U, header.type_ids_off_);
294   EXPECT_EQ(2U, header.proto_ids_size_);
295   EXPECT_EQ(200U, header.proto_ids_off_);
296   EXPECT_EQ(1U, header.field_ids_size_);
297   EXPECT_EQ(224U, header.field_ids_off_);
298   EXPECT_EQ(3U, header.method_ids_size_);
299   EXPECT_EQ(232U, header.method_ids_off_);
300   EXPECT_EQ(2U, header.class_defs_size_);
301   EXPECT_EQ(256U, header.class_defs_off_);
302   EXPECT_EQ(584U, header.data_size_);
303   EXPECT_EQ(320U, header.data_off_);
304 
305   EXPECT_EQ(header.checksum_, dex_file->GetLocationChecksum());
306 }
307 
TEST_F(DexFileLoaderTest,Header)308 TEST_F(DexFileLoaderTest, Header) {
309   std::vector<uint8_t> dex_bytes;
310   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, kLocationString, &dex_bytes));
311   ValidateDexFileHeader(std::move(raw));
312 }
313 
TEST_F(DexFileLoaderTest,HeaderInMemory)314 TEST_F(DexFileLoaderTest, HeaderInMemory) {
315   std::vector<uint8_t> dex_bytes;
316   std::unique_ptr<const DexFile> raw =
317       OpenDexFileInMemoryBase64(kRawDex, kLocationString, 0x00d87910U, true, &dex_bytes);
318   ValidateDexFileHeader(std::move(raw));
319 }
320 
TEST_F(DexFileLoaderTest,Version38Accepted)321 TEST_F(DexFileLoaderTest, Version38Accepted) {
322   std::vector<uint8_t> dex_bytes;
323   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, kLocationString, &dex_bytes));
324   ASSERT_TRUE(raw.get() != nullptr);
325 
326   const DexFile::Header& header = raw->GetHeader();
327   EXPECT_EQ(38u, header.GetVersion());
328 }
329 
TEST_F(DexFileLoaderTest,Version39Accepted)330 TEST_F(DexFileLoaderTest, Version39Accepted) {
331   std::vector<uint8_t> dex_bytes;
332   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex39, kLocationString, &dex_bytes));
333   ASSERT_TRUE(raw.get() != nullptr);
334 
335   const DexFile::Header& header = raw->GetHeader();
336   EXPECT_EQ(39u, header.GetVersion());
337 }
338 
TEST_F(DexFileLoaderTest,Version40Accepted)339 TEST_F(DexFileLoaderTest, Version40Accepted) {
340   std::vector<uint8_t> dex_bytes;
341   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex40, kLocationString, &dex_bytes));
342   ASSERT_TRUE(raw.get() != nullptr);
343 
344   const DexFile::Header& header = raw->GetHeader();
345   EXPECT_EQ(40u, header.GetVersion());
346 }
347 
TEST_F(DexFileLoaderTest,Version41Rejected)348 TEST_F(DexFileLoaderTest, Version41Rejected) {
349   std::vector<uint8_t> dex_bytes;
350   DecodeDexFile(kRawDex41, &dex_bytes);
351 
352   static constexpr bool kVerifyChecksum = true;
353   DexFileLoaderErrorCode error_code;
354   std::string error_msg;
355   std::vector<std::unique_ptr<const DexFile>> dex_files;
356   const DexFileLoader dex_file_loader;
357   ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(),
358                                        dex_bytes.size(),
359                                        kLocationString,
360                                        /* verify= */ true,
361                                        kVerifyChecksum,
362                                        &error_code,
363                                        &error_msg,
364                                        &dex_files));
365 }
366 
TEST_F(DexFileLoaderTest,ZeroLengthDexRejected)367 TEST_F(DexFileLoaderTest, ZeroLengthDexRejected) {
368   std::vector<uint8_t> dex_bytes;
369   DecodeDexFile(kRawDexZeroLength, &dex_bytes);
370 
371   static constexpr bool kVerifyChecksum = true;
372   DexFileLoaderErrorCode error_code;
373   std::string error_msg;
374   std::vector<std::unique_ptr<const DexFile>> dex_files;
375   const DexFileLoader dex_file_loader;
376   ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(),
377                                        dex_bytes.size(),
378                                        kLocationString,
379                                        /* verify= */ true,
380                                        kVerifyChecksum,
381                                        &error_code,
382                                        &error_msg,
383                                        &dex_files));
384 }
385 
TEST_F(DexFileLoaderTest,GetMultiDexClassesDexName)386 TEST_F(DexFileLoaderTest, GetMultiDexClassesDexName) {
387   ASSERT_EQ("classes.dex", DexFileLoader::GetMultiDexClassesDexName(0));
388   ASSERT_EQ("classes2.dex", DexFileLoader::GetMultiDexClassesDexName(1));
389   ASSERT_EQ("classes3.dex", DexFileLoader::GetMultiDexClassesDexName(2));
390   ASSERT_EQ("classes100.dex", DexFileLoader::GetMultiDexClassesDexName(99));
391 }
392 
TEST_F(DexFileLoaderTest,GetMultiDexLocation)393 TEST_F(DexFileLoaderTest, GetMultiDexLocation) {
394   std::string dex_location_str = "/system/app/framework.jar";
395   const char* dex_location = dex_location_str.c_str();
396   ASSERT_EQ("/system/app/framework.jar", DexFileLoader::GetMultiDexLocation(0, dex_location));
397   ASSERT_EQ("/system/app/framework.jar!classes2.dex",
398             DexFileLoader::GetMultiDexLocation(1, dex_location));
399   ASSERT_EQ("/system/app/framework.jar!classes101.dex",
400             DexFileLoader::GetMultiDexLocation(100, dex_location));
401 }
402 
TEST(DexFileUtilsTest,GetBaseLocationAndMultiDexSuffix)403 TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
404   EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar"));
405   EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar!classes2.dex"));
406   EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar!classes8.dex"));
407   EXPECT_EQ("", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar"));
408   EXPECT_EQ("!classes2.dex", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar!classes2.dex"));
409   EXPECT_EQ("!classes8.dex", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar!classes8.dex"));
410 }
411 
TEST_F(DexFileLoaderTest,ZipOpenClassesPresent)412 TEST_F(DexFileLoaderTest, ZipOpenClassesPresent) {
413   std::vector<uint8_t> dex_bytes;
414   std::vector<std::unique_ptr<const DexFile>> dex_files;
415   DexFileLoaderErrorCode error_code;
416   std::string error_msg;
417   ASSERT_TRUE(OpenDexFilesBase64(kRawZipClassesDexPresent,
418                                  kLocationString,
419                                  &dex_bytes,
420                                  &dex_files,
421                                  &error_code,
422                                  &error_msg));
423   EXPECT_EQ(dex_files.size(), 1u);
424 }
425 
TEST_F(DexFileLoaderTest,ZipOpenClassesAbsent)426 TEST_F(DexFileLoaderTest, ZipOpenClassesAbsent) {
427   std::vector<uint8_t> dex_bytes;
428   std::vector<std::unique_ptr<const DexFile>> dex_files;
429   DexFileLoaderErrorCode error_code;
430   std::string error_msg;
431   ASSERT_FALSE(OpenDexFilesBase64(kRawZipClassesDexAbsent,
432                                   kLocationString,
433                                   &dex_bytes,
434                                   &dex_files,
435                                   &error_code,
436                                   &error_msg));
437   EXPECT_EQ(error_code, DexFileLoaderErrorCode::kEntryNotFound);
438   EXPECT_EQ(dex_files.size(), 0u);
439 }
440 
TEST_F(DexFileLoaderTest,ZipOpenThreeDexFiles)441 TEST_F(DexFileLoaderTest, ZipOpenThreeDexFiles) {
442   std::vector<uint8_t> dex_bytes;
443   std::vector<std::unique_ptr<const DexFile>> dex_files;
444   DexFileLoaderErrorCode error_code;
445   std::string error_msg;
446   ASSERT_TRUE(OpenDexFilesBase64(kRawZipThreeDexFiles,
447                                  kLocationString,
448                                  &dex_bytes,
449                                  &dex_files,
450                                  &error_code,
451                                  &error_msg));
452   EXPECT_EQ(dex_files.size(), 3u);
453 }
454 
TEST_F(DexFileLoaderTest,OpenDexBadMapOffset)455 TEST_F(DexFileLoaderTest, OpenDexBadMapOffset) {
456   std::vector<uint8_t> dex_bytes;
457   std::unique_ptr<const DexFile> raw =
458       OpenDexFileInMemoryBase64(kRawDexBadMapOffset,
459                                 kLocationString,
460                                 0xb3642819U,
461                                 false,
462                                 &dex_bytes);
463   EXPECT_EQ(raw, nullptr);
464 }
465 
TEST_F(DexFileLoaderTest,GetStringWithNoIndex)466 TEST_F(DexFileLoaderTest, GetStringWithNoIndex) {
467   std::vector<uint8_t> dex_bytes;
468   std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, kLocationString, &dex_bytes));
469   dex::TypeIndex idx;
470   EXPECT_EQ(raw->StringByTypeIdx(idx), nullptr);
471 }
472 
TEST_F(DexFileLoaderTest,OpenDexDebugInfoLocalNullType)473 TEST_F(DexFileLoaderTest, OpenDexDebugInfoLocalNullType) {
474   std::vector<uint8_t> dex_bytes;
475   std::unique_ptr<const DexFile> raw = OpenDexFileInMemoryBase64(kRawDexDebugInfoLocalNullType,
476                                                                  kLocationString,
477                                                                  0xf25f2b38U,
478                                                                  true,
479                                                                  &dex_bytes);
480   const dex::ClassDef& class_def = raw->GetClassDef(0);
481   constexpr uint32_t kMethodIdx = 1;
482   const dex::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, kMethodIdx));
483   CodeItemDebugInfoAccessor accessor(*raw, code_item, kMethodIdx);
484   ASSERT_TRUE(accessor.DecodeDebugLocalInfo(true, 1, VoidFunctor()));
485 }
486 
487 }  // namespace art
488