12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
161fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_file.h"
181fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
19700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory>
20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers
21e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/stl_util.h"
22e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "base/unix_file/fd_file.h"
23a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_runtime_test.h"
24956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes#include "dex_file-inl.h"
25e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "os.h"
26e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
27e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "thread-inl.h"
2890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes
291fb8620309a4e94d11879aabc33364acfa733904Carl Shapironamespace art {
301fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
31a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass DexFileTest : public CommonRuntimeTest {};
329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
339f30b38d74990286ce27c3a45368f73dbe3638f0Brian CarlstromTEST_F(DexFileTest, Open) {
3433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
35fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
362cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  ASSERT_TRUE(dex.get() != nullptr);
377e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom}
387e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom
3913735955f39b3b304c37d2b2840663c131262c18Ian Rogersstatic const uint8_t kBase64Map[256] = {
40a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
44a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
45a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
46a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  // NOLINT
47a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom   19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,  // NOLINT
48a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
49a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom   37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  // NOLINT
50a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom   49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,  // NOLINT
51a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  255, 255, 255, 255
62a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom};
63a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
6413735955f39b3b304c37d2b2840663c131262c18Ian Rogersstatic inline uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
6513735955f39b3b304c37d2b2840663c131262c18Ian Rogers  std::vector<uint8_t> tmp;
66a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  uint32_t t = 0, y = 0;
67a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  int g = 3;
68a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  for (size_t i = 0; src[i] != '\0'; ++i) {
6913735955f39b3b304c37d2b2840663c131262c18Ian Rogers    uint8_t c = kBase64Map[src[i] & 0xFF];
70a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    if (c == 255) continue;
71a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    // the final = symbols are read and used to trim the remaining bytes
72a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    if (c == 254) {
73a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      c = 0;
74a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      // prevent g < 0 which would potentially allow an overflow later
75a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      if (--g < 0) {
76a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        *dst_size = 0;
77a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        return nullptr;
78a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      }
79a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    } else if (g != 3) {
80a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      // we only allow = to be at the end
81a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      *dst_size = 0;
82a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      return nullptr;
83a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    }
84a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    t = (t << 6) | c;
85a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    if (++y == 4) {
86a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      tmp.push_back((t >> 16) & 255);
87a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      if (g > 1) {
88a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        tmp.push_back((t >> 8) & 255);
89a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      }
90a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      if (g > 2) {
91a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom        tmp.push_back(t & 255);
92a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      }
93a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      y = t = 0;
94a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    }
95a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
96a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  if (y != 0) {
97a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dst_size = 0;
98a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    return nullptr;
99a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
10013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
101a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  if (dst_size != nullptr) {
102a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dst_size = tmp.size();
103a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  } else {
104a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dst_size = 0;
105a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
106a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  std::copy(tmp.begin(), tmp.end(), dst.get());
107a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  return dst.release();
108a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom}
109a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
1109f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// Although this is the same content logically as the Nested test dex,
1119f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// the DexFileHeader test is sensitive to subtle changes in the
1129f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// contents due to the checksum etc, so we embed the exact input here.
1139f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom//
1149f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// class Nested {
1159f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom//     class Inner {
1169f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom//     }
1179f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom// }
1189f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstromstatic const char kRawDex[] =
1199f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
1209f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
1219f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
1229f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
1239f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
1249f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
1259f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
1269f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
1279f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
1289f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
1299f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
1309f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
1319f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
1329f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
1339f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
1349f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom  "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
1359f30b38d74990286ce27c3a45368f73dbe3638f0Brian Carlstrom
136fbef44de596d298dc6430f482dffc933a046dd28Richard Uhlerstatic std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
137fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler                                                        const char* location) {
13833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  // decode base64
1392cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  CHECK(base64 != nullptr);
14033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  size_t length;
14113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
1422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  CHECK(dex_bytes.get() != nullptr);
14333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers
14433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  // write to provided file
145700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<File> file(OS::CreateEmptyFile(location));
1462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  CHECK(file.get() != nullptr);
14733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  if (!file->WriteFully(dex_bytes.get(), length)) {
14833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    PLOG(FATAL) << "Failed to write base64 as dex file";
14933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  }
1504303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  if (file->FlushCloseOrErase() != 0) {
1514303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe    PLOG(FATAL) << "Could not flush and close test file.";
1524303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe  }
15333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  file.reset();
15433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers
15533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  // read dex file
15633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
1578d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  std::string error_msg;
158fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::vector<std::unique_ptr<const DexFile>> tmp;
159833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  bool success = DexFile::Open(location, location, &error_msg, &tmp);
160833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  CHECK(success) << error_msg;
161833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe  EXPECT_EQ(1U, tmp.size());
162fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
163e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom  EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
164e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom  EXPECT_TRUE(dex_file->IsReadOnly());
16533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  return dex_file;
16633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers}
16733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers
1689f30b38d74990286ce27c3a45368f73dbe3638f0Brian CarlstromTEST_F(DexFileTest, Header) {
16933f741eefef8f8012f6c190b39355f2e0430d535Brian Carlstrom  ScratchFile tmp;
170700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
1712cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  ASSERT_TRUE(raw.get() != nullptr);
1727e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom
173f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  const DexFile::Header& header = raw->GetHeader();
1747e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  // TODO: header.magic_
1757e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(0x00d87910U, header.checksum_);
1767e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  // TODO: header.signature_
1777e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(904U, header.file_size_);
1787e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(112U, header.header_size_);
1797e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(0U, header.link_size_);
1807e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(0U, header.link_off_);
1817e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(15U, header.string_ids_size_);
1827e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(112U, header.string_ids_off_);
1837e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(7U, header.type_ids_size_);
1847e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(172U, header.type_ids_off_);
1857e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(2U, header.proto_ids_size_);
1867e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(200U, header.proto_ids_off_);
1877e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(1U, header.field_ids_size_);
1887e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(224U, header.field_ids_off_);
1897e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(3U, header.method_ids_size_);
1907e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(232U, header.method_ids_off_);
1917e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(2U, header.class_defs_size_);
1927e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(256U, header.class_defs_off_);
1937e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(584U, header.data_size_);
1947e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(320U, header.data_off_);
1955b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
1965b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
1975b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
1985b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
1995b332c89fa3fdd7dc184b22c2587d28af304d019Brian CarlstromTEST_F(DexFileTest, GetLocationChecksum) {
20033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
201fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
2025b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
2035b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
2045b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
2055b332c89fa3fdd7dc184b22c2587d28af304d019Brian CarlstromTEST_F(DexFileTest, GetChecksum) {
2065b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  uint32_t checksum;
20733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
2088d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  std::string error_msg;
2095b8e6e36e96d6d1921dd356fa46191d1e6a18082Przemyslaw Szczepaniak  EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileNames()[0].c_str(), &checksum, &error_msg))
2108d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      << error_msg;
2115b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
2127e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom}
2137e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom
2149f30b38d74990286ce27c3a45368f73dbe3638f0Brian CarlstromTEST_F(DexFileTest, ClassDefs) {
21533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
216fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
217fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  ASSERT_TRUE(raw.get() != nullptr);
2187e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_EQ(2U, raw->NumClassDefs());
219578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
220f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  const DexFile::ClassDef& c0 = raw->GetClassDef(0);
2217e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
222578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom
223f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom  const DexFile::ClassDef& c1 = raw->GetClassDef(1);
2247e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom  EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
2251fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}
2261fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
227d91d6d6a80748f277fd938a412211e5af28913b1Ian RogersTEST_F(DexFileTest, GetMethodSignature) {
22833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
229fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
230fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  ASSERT_TRUE(raw.get() != nullptr);
231419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  EXPECT_EQ(1U, raw->NumClassDefs());
232419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
233419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  const DexFile::ClassDef& class_def = raw->GetClassDef(0);
234d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
235419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
23613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* class_data = raw->GetClassData(class_def);
2372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  ASSERT_TRUE(class_data != nullptr);
2384d6850c47515fe2a4f9de923befb6287bb863c8cElliott Hughes  ClassDataItemIterator it(*raw, class_data);
239419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  EXPECT_EQ(1u, it.NumDirectMethods());
241419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2420571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  // Check the signature for the static initializer.
243419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  {
2440571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_EQ(1U, it.NumDirectMethods());
2450571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
2460571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* name = raw->StringDataByIdx(method_id.name_idx_);
247419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro    ASSERT_STREQ("<init>", name);
248d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    std::string signature(raw->GetMethodSignature(method_id).ToString());
2490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_EQ("()V", signature);
250419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  }
251419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
252419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  // Check both virtual methods.
2530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  ASSERT_EQ(2U, it.NumVirtualMethods());
254419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  {
2550571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
2560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
257419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2580571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* name = raw->StringDataByIdx(method_id.name_idx_);
259419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro    ASSERT_STREQ("m1", name);
260419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
261d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    std::string signature(raw->GetMethodSignature(method_id).ToString());
2620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
263419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  }
264419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
265419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  {
2660571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    it.Next();
2670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
268419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
2690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* name = raw->StringDataByIdx(method_id.name_idx_);
270419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro    ASSERT_STREQ("m2", name);
271419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
272d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    std::string signature(raw->GetMethodSignature(method_id).ToString());
273d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers    ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
2740571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
2750571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
2760571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
2770571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindStringId) {
27833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  ScopedObjectAccess soa(Thread::Current());
279fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
280fbef44de596d298dc6430f482dffc933a046dd28Richard Uhler  ASSERT_TRUE(raw.get() != nullptr);
2810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  EXPECT_EQ(1U, raw->NumClassDefs());
2820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
283d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
2842cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      "D", "I", "J", nullptr };
2852cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  for (size_t i = 0; strings[i] != nullptr; i++) {
2860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* str = strings[i];
2870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::StringId* str_id = raw->FindStringId(str);
2880571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* dex_str = raw->GetStringData(*str_id);
2890571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_STREQ(dex_str, str);
2900571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
2910571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
2920571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
2930571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindTypeId) {
2940571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
2950571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
2960571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
2972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(type_str_id != nullptr);
2980571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
2990571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
3009507fa2c9545156747a5eb248bc1af3159bfd8c8Mathieu Chartier    ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
3012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(type_id != nullptr);
3020571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
3030571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
3040571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
3050571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
3060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindProtoId) {
3070571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
3080571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
3090571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
3100571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    std::vector<uint16_t> to_find_types;
3112cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    if (to_find_tl != nullptr) {
3120571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      for (size_t j = 0; j < to_find_tl->Size(); j++) {
3130571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
3140571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers      }
3150571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    }
3160571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::ProtoId* found =
3170571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
3182cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(found != nullptr);
3190571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
3200571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  }
3210571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers}
3220571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
3230571d357843c53e042f370f5f2c2e9aa3fe803a9Ian RogersTEST_F(DexFileTest, FindMethodId) {
3240571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
3250571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
3260571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
3270571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
3280571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
3290571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
3302cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
3310571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
3320571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers        << java_lang_dex_file_->GetStringData(name)
333d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers        << java_lang_dex_file_->GetMethodSignature(to_find);
3340571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
335419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro  }
336419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro}
337419ec7bbcdbf56a9d2a9fd7f91f9ace279e0b664Carl Shapiro
3389b1a4f425711c26d0465d54a1cb95ec4a813322aIan RogersTEST_F(DexFileTest, FindFieldId) {
3399b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers  for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
3409b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
3419b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
3429b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
3439b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
3449b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
3452cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
3469b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers        << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
3479b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers        << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
3489b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers        << java_lang_dex_file_->GetStringData(name);
3499b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers    EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
3509b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers  }
3519b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers}
3529b1a4f425711c26d0465d54a1cb95ec4a813322aIan Rogers
3534e1d579d6401fef2dd57b16f8d406e33221a69d9Calin JuravleTEST_F(DexFileTest, GetMultiDexClassesDexName) {
35490e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
35590e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
35690e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
35790e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
35890e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe}
35990e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe
36090e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas GampeTEST_F(DexFileTest, GetMultiDexLocation) {
3614e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string dex_location_str = "/system/app/framework.jar";
3624e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  const char* dex_location = dex_location_str.c_str();
36390e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
36490e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("/system/app/framework.jar:classes2.dex",
36590e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe            DexFile::GetMultiDexLocation(1, dex_location));
36690e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  ASSERT_EQ("/system/app/framework.jar:classes101.dex",
36790e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe            DexFile::GetMultiDexLocation(100, dex_location));
3684e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle}
3694e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3704e1d579d6401fef2dd57b16f8d406e33221a69d9Calin JuravleTEST_F(DexFileTest, GetDexCanonicalLocation) {
3714e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ScratchFile file;
372aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
373aa4497db59f1eeec954f2ba5da6d458fcdf9b3a4Vladimir Marko  std::string dex_location(dex_location_real.get());
3744e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
37561281dc0aaa22730fd4fee268cac40776b193042Calin Juravle  ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
37690e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
3774e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
3784e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3794e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  std::string dex_location_sym = dex_location + "symlink";
3804e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
3814e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3824e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
3834e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
38490e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
3854e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
3864e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
3874e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle  ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
3884e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle}
3894e1d579d6401fef2dd57b16f8d406e33221a69d9Calin Juravle
390e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
391e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
392e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes2.dex"));
393e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes8.dex"));
394e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
395e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ(":classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes2.dex"));
396e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler  EXPECT_EQ(":classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes8.dex"));
397e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler}
398e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler
3991fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}  // namespace art
400