/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dex_file_loader.h"

#include <sys/stat.h>

#include <memory>
#include <optional>

#include "android-base/stringprintf.h"
#include "base/bit_utils.h"
#include "base/file_magic.h"
#include "base/mem_map.h"
#include "base/os.h"
#include "base/stl_util.h"
#include "base/systrace.h"
#include "base/unix_file/fd_file.h"
#include "base/zip_archive.h"
#include "compact_dex_file.h"
#include "dex_file.h"
#include "dex_file_verifier.h"
#include "standard_dex_file.h"

namespace art {

#if defined(STATIC_LIB)
#define DEXFILE_SCOPED_TRACE(name)
#else
#define DEXFILE_SCOPED_TRACE(name) ScopedTrace trace(name)
#endif

namespace {

// Technically we do not have a limitation with respect to the number of dex files that can be in a
// multidex APK. However, it's bad practice, as each dex file requires its own tables for symbols
// (types, classes, methods, ...) and dex caches. So warn the user that we open a zip with what
// seems an excessive number.
static constexpr size_t kWarnOnManyDexFilesThreshold = 100;

using android::base::StringPrintf;

class VectorContainer : public DexFileContainer {
 public:
  explicit VectorContainer(std::vector<uint8_t>&& vector) : vector_(std::move(vector)) { }
  ~VectorContainer() override { }

  bool IsReadOnly() const override { return true; }

  bool EnableWrite() override { return true; }

  bool DisableWrite() override { return false; }

  const uint8_t* Begin() const override { return vector_.data(); }

  const uint8_t* End() const override { return vector_.data() + vector_.size(); }

 private:
  std::vector<uint8_t> vector_;
  DISALLOW_COPY_AND_ASSIGN(VectorContainer);
};

class MemMapContainer : public DexFileContainer {
 public:
  explicit MemMapContainer(MemMap&& mem_map, bool is_file_map = false)
      : mem_map_(std::move(mem_map)), is_file_map_(is_file_map) {}

  int GetPermissions() const {
    if (!mem_map_.IsValid()) {
      return 0;
    } else {
      return mem_map_.GetProtect();
    }
  }

  bool IsReadOnly() const override { return GetPermissions() == PROT_READ; }

  bool EnableWrite() override {
    if (!IsReadOnly()) {
      // We can already write to the container.
      // This method may be called multiple times by tests if DexFiles share container.
      return true;
    }
    if (!mem_map_.IsValid()) {
      return false;
    } else {
      return mem_map_.Protect(PROT_READ | PROT_WRITE);
    }
  }

  bool DisableWrite() override {
    CHECK(!IsReadOnly());
    if (!mem_map_.IsValid()) {
      return false;
    } else {
      return mem_map_.Protect(PROT_READ);
    }
  }

  const uint8_t* Begin() const override { return mem_map_.Begin(); }

  const uint8_t* End() const override { return mem_map_.End(); }

  bool IsFileMap() const override { return is_file_map_; }

 protected:
  MemMap mem_map_;
  bool is_file_map_;
  DISALLOW_COPY_AND_ASSIGN(MemMapContainer);
};

}  // namespace

const File DexFileLoader::kInvalidFile;

bool DexFileLoader::IsMagicValid(uint32_t magic) {
  return IsMagicValid(reinterpret_cast<uint8_t*>(&magic));
}

bool DexFileLoader::IsMagicValid(const uint8_t* magic) {
  return StandardDexFile::IsMagicValid(magic) ||
      CompactDexFile::IsMagicValid(magic);
}

bool DexFileLoader::IsVersionAndMagicValid(const uint8_t* magic) {
  if (StandardDexFile::IsMagicValid(magic)) {
    return StandardDexFile::IsVersionValid(magic);
  }
  if (CompactDexFile::IsMagicValid(magic)) {
    return CompactDexFile::IsVersionValid(magic);
  }
  return false;
}

bool DexFileLoader::IsMultiDexLocation(std::string_view location) {
  return location.find(kMultiDexSeparator) != std::string_view::npos;
}

std::string DexFileLoader::GetMultiDexClassesDexName(size_t index) {
  return (index == 0) ? "classes.dex" : StringPrintf("classes%zu.dex", index + 1);
}

std::string DexFileLoader::GetMultiDexLocation(size_t index, const char* dex_location) {
  DCHECK(!IsMultiDexLocation(dex_location));
  if (index == 0) {
    return dex_location;
  }
  return StringPrintf("%s%cclasses%zu.dex", dex_location, kMultiDexSeparator, index + 1);
}

bool DexFileLoader::GetMultiDexChecksum(std::optional<uint32_t>* checksum,
                                        std::string* error_msg,
                                        bool* only_contains_uncompressed_dex) {
  CHECK(checksum != nullptr);
  checksum->reset();  // Return nullopt for an empty zip archive.

  uint32_t magic;
  if (!InitAndReadMagic(/*header_offset=*/0, &magic, error_msg)) {
    return false;
  }

  if (IsZipMagic(magic)) {
    std::unique_ptr<ZipArchive> zip_archive(
        file_->IsValid() ?
            ZipArchive::OpenFromOwnedFd(file_->Fd(), location_.c_str(), error_msg) :
            ZipArchive::OpenFromMemory(
                root_container_->Begin(), root_container_->Size(), location_.c_str(), error_msg));
    if (zip_archive.get() == nullptr) {
      DCHECK(!error_msg->empty());
      return false;
    }
    if (only_contains_uncompressed_dex != nullptr) {
      *only_contains_uncompressed_dex = true;
    }
    for (size_t i = 0;; ++i) {
      std::string name = GetMultiDexClassesDexName(i);
      std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(name.c_str(), error_msg));
      if (zip_entry == nullptr) {
        break;
      }
      if (only_contains_uncompressed_dex != nullptr) {
        if (!(zip_entry->IsUncompressed() && zip_entry->IsAlignedTo(alignof(DexFile::Header)))) {
          *only_contains_uncompressed_dex = false;
        }
      }
      *checksum = checksum->value_or(kEmptyMultiDexChecksum) ^ zip_entry->GetCrc32();
    }
    return true;
  }
  if (!MapRootContainer(error_msg)) {
    return false;
  }
  const uint8_t* begin = root_container_->Begin();
  const uint8_t* end = root_container_->End();
  for (const uint8_t* ptr = begin; ptr < end;) {
    const auto* header = reinterpret_cast<const DexFile::Header*>(ptr);
    size_t size = dchecked_integral_cast<size_t>(end - ptr);
    if (size < sizeof(*header) || !IsMagicValid(ptr)) {
      *error_msg = StringPrintf("Invalid dex header: '%s'", filename_.c_str());
      return false;
    }
    if (size < header->file_size_) {
      *error_msg = StringPrintf("Truncated dex file: '%s'", filename_.c_str());
      return false;
    }
    *checksum = checksum->value_or(kEmptyMultiDexChecksum) ^ header->checksum_;
    ptr += header->file_size_;
  }
  return true;
}

std::string DexFileLoader::GetDexCanonicalLocation(const char* dex_location) {
  CHECK_NE(dex_location, static_cast<const char*>(nullptr));
  std::string base_location = GetBaseLocation(dex_location);
  const char* suffix = dex_location + base_location.size();
  DCHECK(suffix[0] == 0 || suffix[0] == kMultiDexSeparator);
#ifdef _WIN32
  // Warning: No symbolic link processing here.
  PLOG(WARNING) << "realpath is unsupported on Windows.";
#else
  // Warning: Bionic implementation of realpath() allocates > 12KB on the stack.
  // Do not run this code on a small stack, e.g. in signal handler.
  UniqueCPtr<const char[]> path(realpath(base_location.c_str(), nullptr));
  if (path != nullptr && path.get() != base_location) {
    return std::string(path.get()) + suffix;
  }
#endif
  if (suffix[0] == 0) {
    return base_location;
  } else {
    return dex_location;
  }
}

// All of the implementations here should be independent of the runtime.

DexFileLoader::DexFileLoader(const uint8_t* base, size_t size, const std::string& location)
    : DexFileLoader(std::make_shared<MemoryDexFileContainer>(base, base + size), location) {}

DexFileLoader::DexFileLoader(std::vector<uint8_t>&& memory, const std::string& location)
    : DexFileLoader(std::make_shared<VectorContainer>(std::move(memory)), location) {}

DexFileLoader::DexFileLoader(MemMap&& mem_map, const std::string& location)
    : DexFileLoader(std::make_shared<MemMapContainer>(std::move(mem_map)), location) {}

std::unique_ptr<const DexFile> DexFileLoader::OpenOne(size_t header_offset,
                                                      uint32_t location_checksum,
                                                      const OatDexFile* oat_dex_file,
                                                      bool verify,
                                                      bool verify_checksum,
                                                      std::string* error_msg) {
  DEXFILE_SCOPED_TRACE(std::string("Open dex file ") + location_);

  uint32_t magic;
  if (!InitAndReadMagic(header_offset, &magic, error_msg) || !MapRootContainer(error_msg)) {
    DCHECK(!error_msg->empty());
    return {};
  }
  DCHECK(root_container_ != nullptr);
  DCHECK_LE(header_offset, root_container_->Size());
  std::unique_ptr<const DexFile> dex_file = OpenCommon(root_container_,
                                                       root_container_->Begin() + header_offset,
                                                       root_container_->Size() - header_offset,
                                                       location_,
                                                       location_checksum,
                                                       oat_dex_file,
                                                       verify,
                                                       verify_checksum,
                                                       error_msg,
                                                       nullptr);
  return dex_file;
}

bool DexFileLoader::InitAndReadMagic(size_t header_offset,
                                     uint32_t* magic,
                                     std::string* error_msg) {
  if (root_container_ != nullptr) {
    if (root_container_->Size() < header_offset ||
        root_container_->Size() - header_offset < sizeof(uint32_t)) {
      *error_msg = StringPrintf("Unable to open '%s' : Size is too small", location_.c_str());
      return false;
    }
    *magic = *reinterpret_cast<const uint32_t*>(root_container_->Begin() + header_offset);
  } else {
    // Open the file if we have not been given the file-descriptor directly before.
    if (!file_->IsValid()) {
      CHECK(!filename_.empty());
      owned_file_ = File(filename_, O_RDONLY, /* check_usage= */ false);
      if (!owned_file_->IsValid()) {
        *error_msg = StringPrintf("Unable to open '%s' : %s", filename_.c_str(), strerror(errno));
        return false;
      }
      file_ = &owned_file_.value();
    }
    CHECK_EQ(header_offset, 0u);  // We always expect to read from the start of physical file.
    if (!ReadMagicAndReset(file_->Fd(), magic, error_msg)) {
      return false;
    }
  }
  return true;
}

bool DexFileLoader::MapRootContainer(std::string* error_msg) {
  if (root_container_ != nullptr) {
    return true;
  }

  CHECK(MemMap::IsInitialized());
  CHECK(file_->IsValid());
  struct stat sbuf;
  memset(&sbuf, 0, sizeof(sbuf));
  if (fstat(file_->Fd(), &sbuf) == -1) {
    *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", filename_.c_str(), strerror(errno));
    return false;
  }
  if (S_ISDIR(sbuf.st_mode)) {
    *error_msg = StringPrintf("Attempt to mmap directory '%s'", filename_.c_str());
    return false;
  }
  MemMap map = MemMap::MapFile(sbuf.st_size,
                               PROT_READ,
                               MAP_PRIVATE,
                               file_->Fd(),
                               0,
                               /*low_4gb=*/false,
                               filename_.c_str(),
                               error_msg);
  if (!map.IsValid()) {
    DCHECK(!error_msg->empty());
    return false;
  }
  root_container_ = std::make_shared<MemMapContainer>(std::move(map));
  return true;
}

bool DexFileLoader::Open(bool verify,
                         bool verify_checksum,
                         bool allow_no_dex_files,
                         DexFileLoaderErrorCode* error_code,
                         std::string* error_msg,
                         std::vector<std::unique_ptr<const DexFile>>* dex_files) {
  DEXFILE_SCOPED_TRACE(std::string("Open dex file ") + location_);

  DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";

  uint32_t magic;
  if (!InitAndReadMagic(/*header_offset=*/0, &magic, error_msg)) {
    return false;
  }

  if (IsZipMagic(magic)) {
    std::unique_ptr<ZipArchive> zip_archive(
        file_->IsValid() ?
            ZipArchive::OpenFromOwnedFd(file_->Fd(), location_.c_str(), error_msg) :
            ZipArchive::OpenFromMemory(
                root_container_->Begin(), root_container_->Size(), location_.c_str(), error_msg));
    if (zip_archive.get() == nullptr) {
      DCHECK(!error_msg->empty());
      return false;
    }
    size_t multidex_count = 0;
    for (size_t i = 0;; ++i) {
      std::string name = GetMultiDexClassesDexName(i);
      bool ok = OpenFromZipEntry(*zip_archive,
                                 name.c_str(),
                                 location_,
                                 verify,
                                 verify_checksum,
                                 &multidex_count,
                                 error_code,
                                 error_msg,
                                 dex_files);
      if (!ok) {
        // We keep opening consecutive dex entries as long as we can (until entry is not found).
        if (*error_code == DexFileLoaderErrorCode::kEntryNotFound) {
          // Success if we loaded at least one entry, or if empty zip is explicitly allowed.
          return i > 0 || allow_no_dex_files;
        }
        return false;
      }
      if (i == kWarnOnManyDexFilesThreshold) {
        LOG(WARNING) << location_ << " has in excess of " << kWarnOnManyDexFilesThreshold
                     << " dex files. Please consider coalescing and shrinking the number to "
                        " avoid runtime overhead.";
      }
    }
  }
  if (IsMagicValid(magic)) {
    if (!MapRootContainer(error_msg)) {
      return false;
    }
    DCHECK(root_container_ != nullptr);
    size_t header_offset = 0;
    for (size_t i = 0;; i++) {
      std::string multidex_location = GetMultiDexLocation(i, location_.c_str());
      std::unique_ptr<const DexFile> dex_file =
          OpenCommon(root_container_,
                     root_container_->Begin() + header_offset,
                     root_container_->Size() - header_offset,
                     multidex_location,
                     /*location_checksum*/ {},  // Use default checksum from dex header.
                     /*oat_dex_file=*/nullptr,
                     verify,
                     verify_checksum,
                     error_msg,
                     error_code);
      if (dex_file == nullptr) {
        return false;
      }
      dex_files->push_back(std::move(dex_file));
      size_t file_size = dex_files->back()->GetHeader().file_size_;
      CHECK_LE(file_size, root_container_->Size() - header_offset);
      header_offset += file_size;
      if (dex_files->back()->IsDexContainerLastEntry()) {
        break;
      }
    }
    return true;
  }
  *error_msg = StringPrintf("Expected valid zip or dex file");
  return false;
}

std::unique_ptr<DexFile> DexFileLoader::OpenCommon(std::shared_ptr<DexFileContainer> container,
                                                   const uint8_t* base,
                                                   size_t app_compat_size,
                                                   const std::string& location,
                                                   std::optional<uint32_t> location_checksum,
                                                   const OatDexFile* oat_dex_file,
                                                   bool verify,
                                                   bool verify_checksum,
                                                   std::string* error_msg,
                                                   DexFileLoaderErrorCode* error_code) {
  if (container == nullptr) {
    // We should never pass null here, but use reasonable default for app compat anyway.
    container = std::make_shared<MemoryDexFileContainer>(base, app_compat_size);
  }
  CHECK_GE(base, container->Begin());
  CHECK_LE(base, container->End());
  const size_t size = container->End() - base;
  if (error_code != nullptr) {
    *error_code = DexFileLoaderErrorCode::kDexFileError;
  }
  std::unique_ptr<DexFile> dex_file;
  auto header = reinterpret_cast<const DexFile::Header*>(base);
  if (size >= sizeof(StandardDexFile::Header) && StandardDexFile::IsMagicValid(base)) {
    uint32_t checksum = location_checksum.value_or(header->checksum_);
    dex_file.reset(new StandardDexFile(base, location, checksum, oat_dex_file, container));
  } else if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(base)) {
    uint32_t checksum = location_checksum.value_or(header->checksum_);
    dex_file.reset(new CompactDexFile(base, location, checksum, oat_dex_file, container));
  } else {
    *error_msg = StringPrintf("Invalid or truncated dex file '%s'", location.c_str());
  }
  if (dex_file == nullptr) {
    *error_msg =
        StringPrintf("Failed to open dex file '%s': %s", location.c_str(), error_msg->c_str());
    return nullptr;
  }
  if (!dex_file->Init(error_msg)) {
    dex_file.reset();
    return nullptr;
  }
  // NB: Dex verifier does not understand the compact dex format.
  if (verify && !dex_file->IsCompactDexFile()) {
    DEXFILE_SCOPED_TRACE(std::string("Verify dex file ") + location);
    if (!dex::Verify(dex_file.get(), location.c_str(), verify_checksum, error_msg)) {
      if (error_code != nullptr) {
        *error_code = DexFileLoaderErrorCode::kVerifyError;
      }
      return nullptr;
    }
  }
  if (error_code != nullptr) {
    *error_code = DexFileLoaderErrorCode::kNoError;
  }
  return dex_file;
}

bool DexFileLoader::OpenFromZipEntry(const ZipArchive& zip_archive,
                                     const char* entry_name,
                                     const std::string& location,
                                     bool verify,
                                     bool verify_checksum,
                                     size_t* multidex_count,
                                     DexFileLoaderErrorCode* error_code,
                                     std::string* error_msg,
                                     std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
  CHECK(!location.empty());
  std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
  if (zip_entry == nullptr) {
    *error_code = DexFileLoaderErrorCode::kEntryNotFound;
    return false;
  }
  if (zip_entry->GetUncompressedLength() == 0) {
    *error_msg = StringPrintf("Dex file '%s' has zero length", location.c_str());
    *error_code = DexFileLoaderErrorCode::kDexFileError;
    return false;
  }

  CHECK(MemMap::IsInitialized());
  MemMap map;
  bool is_file_map = false;
  if (file_->IsValid() && zip_entry->IsUncompressed()) {
    if (!zip_entry->IsAlignedTo(alignof(DexFile::Header))) {
      // Do not mmap unaligned ZIP entries because
      // doing so would fail dex verification which requires 4 byte alignment.
      LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
                   << "please zipalign to " << alignof(DexFile::Header) << " bytes. "
                   << "Falling back to extracting file.";
    } else {
      // Map uncompressed files within zip as file-backed to avoid a dirty copy.
      map = zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/ error_msg);
      if (!map.IsValid()) {
        LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
                     << "is your ZIP file corrupted? Falling back to extraction.";
        // Try again with Extraction which still has a chance of recovery.
      }
      is_file_map = true;
    }
  }
  if (!map.IsValid()) {
    DEXFILE_SCOPED_TRACE(std::string("Extract dex file ") + location);

    // Default path for compressed ZIP entries,
    // and fallback for stored ZIP entries.
    map = zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg);
  }
  if (!map.IsValid()) {
    *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
                              error_msg->c_str());
    *error_code = DexFileLoaderErrorCode::kExtractToMemoryError;
    return false;
  }
  auto container = std::make_shared<MemMapContainer>(std::move(map), is_file_map);
  container->SetIsZip();
  if (!container->DisableWrite()) {
    *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
    *error_code = DexFileLoaderErrorCode::kMakeReadOnlyError;
    return false;
  }

  size_t header_offset = 0;
  for (size_t i = 0;; i++) {
    std::string multidex_location = GetMultiDexLocation(*multidex_count, location.c_str());
    ++(*multidex_count);
    uint32_t multidex_checksum = zip_entry->GetCrc32() + i;
    std::unique_ptr<const DexFile> dex_file = OpenCommon(container,
                                                         container->Begin() + header_offset,
                                                         container->Size() - header_offset,
                                                         multidex_location,
                                                         multidex_checksum,
                                                         /*oat_dex_file=*/nullptr,
                                                         verify,
                                                         verify_checksum,
                                                         error_msg,
                                                         error_code);
    if (dex_file == nullptr) {
      return false;
    }
    if (dex_file->IsCompactDexFile()) {
      *error_msg = StringPrintf("Can not open compact dex file from zip '%s'", location.c_str());
      return false;
    }
    CHECK(dex_file->IsReadOnly()) << multidex_location;
    dex_files->push_back(std::move(dex_file));
    size_t file_size = dex_files->back()->GetHeader().file_size_;
    CHECK_LE(file_size, container->Size() - header_offset);
    header_offset += file_size;
    if (dex_files->back()->IsDexContainerLastEntry()) {
      break;
    }
  }
  return true;
}

std::unique_ptr<const DexFile> DexFileLoader::Open(
    const uint8_t* base,
    size_t size,
    const std::string& location,
    uint32_t location_checksum,
    const OatDexFile* oat_dex_file,
    bool verify,
    bool verify_checksum,
    std::string* error_msg,
    std::unique_ptr<DexFileContainer> container) const {
  return OpenCommon(base,
                    size,
                    /*data_base=*/nullptr,
                    /*data_size=*/0,
                    location,
                    location_checksum,
                    oat_dex_file,
                    verify,
                    verify_checksum,
                    error_msg,
                    std::move(container),
                    /*verify_result=*/nullptr);
}

std::unique_ptr<DexFile> DexFileLoader::OpenCommon(const uint8_t* base,
                                                   size_t size,
                                                   const uint8_t* data_base,
                                                   size_t data_size,
                                                   const std::string& location,
                                                   uint32_t location_checksum,
                                                   const OatDexFile* oat_dex_file,
                                                   bool verify,
                                                   bool verify_checksum,
                                                   std::string* error_msg,
                                                   std::unique_ptr<DexFileContainer> old_container,
                                                   VerifyResult* verify_result) {
  CHECK(data_base == base || data_base == nullptr);
  CHECK(data_size == size || data_size == 0);
  CHECK(verify_result == nullptr);

  // The provided container probably does implent the new API.
  // We don't use it, but let's at least call its destructor.
  struct NewContainer : public MemoryDexFileContainer {
    using MemoryDexFileContainer::MemoryDexFileContainer;  // ctor.
    std::unique_ptr<DexFileContainer> old_container_ = nullptr;
  };
  auto new_container = std::make_shared<NewContainer>(base, size);
  new_container->old_container_ = std::move(old_container);

  return OpenCommon(std::move(new_container),
                    base,
                    size,
                    location,
                    location_checksum,
                    oat_dex_file,
                    verify,
                    verify_checksum,
                    error_msg,
                    /*error_code=*/nullptr);
}

}  // namespace art
