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

Commit 547c7d9a authored by Narayan Kamath's avatar Narayan Kamath
Browse files

DO NOT MERGE : Fix build breakage due to 2d516d2d.

Test: make
Test: zip_archive_test
Bug: 64211847

Change-Id: Ide48ce66542e152d88520dcd6abcd104e48137f6
parent 64406ab1
Loading
Loading
Loading
Loading
+25 −25
Original line number Diff line number Diff line
@@ -594,6 +594,29 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name,
  return result;
}

// Attempts to read |len| bytes into |buf| at offset |off|.
//
// This method uses pread64 on platforms that support it and
// lseek64 + read on platforms that don't. This implies that
// callers should not rely on the |fd| offset being incremented
// as a side effect of this call.
static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len,
                                   off64_t off) {
#ifdef HAVE_PREAD
  return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off));
#else
  // The only supported platform that doesn't support pread at the moment
  // is Windows. Only recent versions of windows support unix like forks,
  // and even there the semantics are quite different.
  if (lseek64(fd, off, SEEK_SET) != off) {
    ALOGW("Zip: failed seek to offset %" PRId64, off);
    return kIoError;
  }

  return TEMP_FAILURE_RETRY(read(fd, buf, len));
#endif  // HAVE_PREAD
}

/*
 * Parses the Zip archive's Central Directory.  Allocates and populates the
 * hash table.
@@ -672,8 +695,8 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
  }

  uint32_t lfh_start_bytes;
  if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast<uint8_t*>(&lfh_start_bytes),
                                        sizeof(uint32_t), 0)) {
  if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes),
                    sizeof(uint32_t), 0) != sizeof(uint32_t)) {
    ALOGW("Zip: Unable to read header for entry at offset == 0.");
    return -1;
  }
@@ -755,29 +778,6 @@ static int32_t UpdateEntryFromDataDescriptor(int fd,
  return 0;
}

// Attempts to read |len| bytes into |buf| at offset |off|.
//
// This method uses pread64 on platforms that support it and
// lseek64 + read on platforms that don't. This implies that
// callers should not rely on the |fd| offset being incremented
// as a side effect of this call.
static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len,
                                   off64_t off) {
#ifdef HAVE_PREAD
  return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off));
#else
  // The only supported platform that doesn't support pread at the moment
  // is Windows. Only recent versions of windows support unix like forks,
  // and even there the semantics are quite different.
  if (lseek64(fd, off, SEEK_SET) != off) {
    ALOGW("Zip: failed seek to offset %" PRId64, off);
    return kIoError;
  }

  return TEMP_FAILURE_RETRY(read(fd, buf, len));
#endif  // HAVE_PREAD
}

static int32_t FindEntry(const ZipArchive* archive, const int ent,
                         ZipEntry* data) {
  const uint16_t nameLen = archive->hash_table[ent].name_length;
+10 −6
Original line number Diff line number Diff line
@@ -266,7 +266,7 @@ TEST(ziparchive, ExtractToFile) {
// Manual changes :
// [2] = 0xff  // Corrupt the LFH signature of entry 0.
// [3] = 0xff  // Corrupt the LFH signature of entry 0.
static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{
static const uint8_t kZipFileWithBrokenLfhSignature[] = {
    //[lfh-sig-----------], [lfh contents---------------------------------
    0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
    //--------------------------------------------------------------------
@@ -297,12 +297,16 @@ static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{
    0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00};

TEST(ziparchive, BrokenLfhSignature) {
  TemporaryFile tmp_file;
  ASSERT_NE(-1, tmp_file.fd);
  ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0],
                                        kZipFileWithBrokenLfhSignature.size()));
  char kTempFilePattern[] = "zip_archive_input_XXXXXX";
  int fd = make_temporary_file(kTempFilePattern);
  ASSERT_NE(-1, fd);

  ASSERT_EQ(static_cast<int32_t>(sizeof(kZipFileWithBrokenLfhSignature)),
      TEMP_FAILURE_RETRY(write(fd, kZipFileWithBrokenLfhSignature,
                               sizeof(kZipFileWithBrokenLfhSignature))));
  ZipArchiveHandle handle;
  ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle));
  ASSERT_EQ(-1, OpenArchiveFd(fd, "LeadingNonZipBytes", &handle));
  close(fd);
}

int main(int argc, char** argv) {