Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 264a37d1 authored by Elliott Hughes's avatar Elliott Hughes Committed by Gerrit Code Review
Browse files

Merge "Fix SEGV in libziparchive with malformed zip file."

parents 43ad6362 fba2a1a1
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -36,7 +36,7 @@ struct FileRegion {
    FileRegion(borrowed_fd fd, off64_t offset, size_t length)
    FileRegion(borrowed_fd fd, off64_t offset, size_t length)
        : mapped_(android::base::MappedFile::FromOsHandle(adb_get_os_handle(fd), offset, length,
        : mapped_(android::base::MappedFile::FromOsHandle(adb_get_os_handle(fd), offset, length,
                                                          PROT_READ)) {
                                                          PROT_READ)) {
        if (mapped_.data() != nullptr) {
        if (mapped_ != nullptr) {
            return;
            return;
        }
        }


@@ -50,14 +50,14 @@ struct FileRegion {
        }
        }
    }
    }


    const char* data() const { return mapped_.data() ? mapped_.data() : buffer_.data(); }
    const char* data() const { return mapped_ ? mapped_->data() : buffer_.data(); }
    size_t size() const { return mapped_.data() ? mapped_.size() : buffer_.size(); }
    size_t size() const { return mapped_ ? mapped_->size() : buffer_.size(); }


  private:
  private:
    FileRegion() = default;
    FileRegion() = default;
    DISALLOW_COPY_AND_ASSIGN(FileRegion);
    DISALLOW_COPY_AND_ASSIGN(FileRegion);


    android::base::MappedFile mapped_;
    std::unique_ptr<android::base::MappedFile> mapped_;
    std::string buffer_;
    std::string buffer_;
};
};
}  // namespace
}  // namespace
+2 −5
Original line number Original line Diff line number Diff line
@@ -53,7 +53,8 @@ class MappedFile {
  /**
  /**
   * Same thing, but using the raw OS file handle instead of a CRT wrapper.
   * Same thing, but using the raw OS file handle instead of a CRT wrapper.
   */
   */
  static MappedFile FromOsHandle(os_handle h, off64_t offset, size_t length, int prot);
  static std::unique_ptr<MappedFile> FromOsHandle(os_handle h, off64_t offset, size_t length,
                                                  int prot);


  /**
  /**
   * Removes the mapping.
   * Removes the mapping.
@@ -69,10 +70,6 @@ class MappedFile {
  char* data() const { return base_ + offset_; }
  char* data() const { return base_ + offset_; }
  size_t size() const { return size_; }
  size_t size() const { return size_; }


  bool isValid() const { return base_ != nullptr; }

  explicit operator bool() const { return isValid(); }

 private:
 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(MappedFile);
  DISALLOW_IMPLICIT_CONSTRUCTORS(MappedFile);


+13 −12
Original line number Original line Diff line number Diff line
@@ -38,15 +38,14 @@ static off64_t InitPageSize() {
std::unique_ptr<MappedFile> MappedFile::FromFd(borrowed_fd fd, off64_t offset, size_t length,
std::unique_ptr<MappedFile> MappedFile::FromFd(borrowed_fd fd, off64_t offset, size_t length,
                                               int prot) {
                                               int prot) {
#if defined(_WIN32)
#if defined(_WIN32)
  auto file =
  return FromOsHandle(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), offset, length, prot);
      FromOsHandle(reinterpret_cast<HANDLE>(_get_osfhandle(fd.get())), offset, length, prot);
#else
#else
  auto file = FromOsHandle(fd.get(), offset, length, prot);
  return FromOsHandle(fd.get(), offset, length, prot);
#endif
#endif
  return file ? std::make_unique<MappedFile>(std::move(file)) : std::unique_ptr<MappedFile>{};
}
}


MappedFile MappedFile::FromOsHandle(os_handle h, off64_t offset, size_t length, int prot) {
std::unique_ptr<MappedFile> MappedFile::FromOsHandle(os_handle h, off64_t offset, size_t length,
                                                     int prot) {
  static const off64_t page_size = InitPageSize();
  static const off64_t page_size = InitPageSize();
  size_t slop = offset % page_size;
  size_t slop = offset % page_size;
  off64_t file_offset = offset - slop;
  off64_t file_offset = offset - slop;
@@ -59,28 +58,30 @@ MappedFile MappedFile::FromOsHandle(os_handle h, off64_t offset, size_t length,
    // http://b/119818070 "app crashes when reading asset of zero length".
    // http://b/119818070 "app crashes when reading asset of zero length".
    // Return a MappedFile that's only valid for reading the size.
    // Return a MappedFile that's only valid for reading the size.
    if (length == 0 && ::GetLastError() == ERROR_FILE_INVALID) {
    if (length == 0 && ::GetLastError() == ERROR_FILE_INVALID) {
      return MappedFile{const_cast<char*>(kEmptyBuffer), 0, 0, nullptr};
      return std::unique_ptr<MappedFile>(
          new MappedFile(const_cast<char*>(kEmptyBuffer), 0, 0, nullptr));
    }
    }
    return MappedFile(nullptr, 0, 0, nullptr);
    return nullptr;
  }
  }
  void* base = MapViewOfFile(handle, (prot & PROT_WRITE) ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ, 0,
  void* base = MapViewOfFile(handle, (prot & PROT_WRITE) ? FILE_MAP_ALL_ACCESS : FILE_MAP_READ, 0,
                             file_offset, file_length);
                             file_offset, file_length);
  if (base == nullptr) {
  if (base == nullptr) {
    CloseHandle(handle);
    CloseHandle(handle);
    return MappedFile(nullptr, 0, 0, nullptr);
    return nullptr;
  }
  }
  return MappedFile{static_cast<char*>(base), length, slop, handle};
  return std::unique_ptr<MappedFile>(
      new MappedFile(static_cast<char*>(base), length, slop, handle));
#else
#else
  void* base = mmap(nullptr, file_length, prot, MAP_SHARED, h, file_offset);
  void* base = mmap(nullptr, file_length, prot, MAP_SHARED, h, file_offset);
  if (base == MAP_FAILED) {
  if (base == MAP_FAILED) {
    // http://b/119818070 "app crashes when reading asset of zero length".
    // http://b/119818070 "app crashes when reading asset of zero length".
    // mmap fails with EINVAL for a zero length region.
    // mmap fails with EINVAL for a zero length region.
    if (errno == EINVAL && length == 0) {
    if (errno == EINVAL && length == 0) {
      return MappedFile{const_cast<char*>(kEmptyBuffer), 0, 0};
      return std::unique_ptr<MappedFile>(new MappedFile(const_cast<char*>(kEmptyBuffer), 0, 0));
    }
    }
    return MappedFile(nullptr, 0, 0);
    return nullptr;
  }
  }
  return MappedFile{static_cast<char*>(base), length, slop};
  return std::unique_ptr<MappedFile>(new MappedFile(static_cast<char*>(base), length, slop));
#endif
#endif
}
}


+0 −2
Original line number Original line Diff line number Diff line
@@ -44,8 +44,6 @@ TEST(mapped_file, zero_length_mapping) {
  ASSERT_TRUE(tf.fd != -1);
  ASSERT_TRUE(tf.fd != -1);


  auto m = android::base::MappedFile::FromFd(tf.fd, 4096, 0, PROT_READ);
  auto m = android::base::MappedFile::FromFd(tf.fd, 4096, 0, PROT_READ);
  ASSERT_NE(nullptr, m);
  EXPECT_TRUE((bool)*m);
  EXPECT_EQ(0u, m->size());
  EXPECT_EQ(0u, m->size());
  EXPECT_NE(nullptr, m->data());
  EXPECT_NE(nullptr, m->data());
}
}
+22 B

File added.

No diff preview for this file type.

Loading