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

Commit 153c03ac authored by Narayan Kamath's avatar Narayan Kamath Committed by Android Git Automerger
Browse files

am df39ce39: am d61266d0: am 4928d8d0: Merge "Fix ExtractEntryToFile."

* commit 'df39ce39':
  Fix ExtractEntryToFile.
parents d27f65ba df39ce39
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -152,7 +152,10 @@ int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
int32_t Next(void* cookie, ZipEntry* data, ZipEntryName *name);

/*
 * Uncompress and write an entry to a file descriptor.
 * Uncompress and write an entry to an open file identified by |fd|.
 * |entry->uncompressed_length| bytes will be written to the file at
 * its current offset, and the file will be truncated at the end of
 * the uncompressed data.
 *
 * Returns 0 on success and negative values on failure.
 */
+11 −3
Original line number Diff line number Diff line
@@ -1007,13 +1007,21 @@ int32_t ExtractEntryToFile(ZipArchiveHandle handle,
                           ZipEntry* entry, int fd) {
  const int32_t declared_length = entry->uncompressed_length;

  int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length));
  const off64_t current_offset = lseek64(fd, 0, SEEK_CUR);
  if (current_offset == -1) {
    ALOGW("Zip: unable to seek to current location on fd %d: %s", fd,
          strerror(errno));
    return kIoError;
  }

  int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
  if (result == -1) {
    ALOGW("Zip: unable to truncate file to %ud", declared_length);
    ALOGW("Zip: unable to truncate file to %lld: %s", declared_length + current_offset,
          strerror(errno));
    return kIoError;
  }

  android::FileMap* map  = MapFileSegment(fd, 0, declared_length,
  android::FileMap* map  = MapFileSegment(fd, current_offset, declared_length,
                                          false, kTempMappingFileName);
  if (map == NULL) {
    return kMmapFailed;
+42 −1
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@

#include "ziparchive/zip_archive.h"

#include "getopt.h"
#include <errno.h>
#include <getopt.h>
#include <stdio.h>
#include <unistd.h>
#include <vector>

#include <gtest/gtest.h>

static std::string test_data_dir;
@@ -136,6 +140,43 @@ TEST(ziparchive, ExtractToMemory) {
  CloseArchive(handle);
}

TEST(ziparchive, ExtractToFile) {
  char kTempFilePattern[] = "zip_archive_test_XXXXXX";
  int fd = mkstemp(kTempFilePattern);
  ASSERT_NE(-1, fd);
  const uint8_t data[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };
  const ssize_t data_size = sizeof(data);

  ASSERT_EQ(data_size, TEMP_FAILURE_RETRY(write(fd, data, data_size)));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));

  ZipEntry entry;
  ASSERT_EQ(0, FindEntry(handle, "a.txt", &entry));
  ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, fd));


  // Assert that the first 8 bytes of the file haven't been clobbered.
  uint8_t read_buffer[data_size];
  ASSERT_EQ(0, lseek64(fd, 0, SEEK_SET));
  ASSERT_EQ(data_size, TEMP_FAILURE_RETRY(read(fd, read_buffer, data_size)));
  ASSERT_EQ(0, memcmp(read_buffer, data, data_size));

  // Assert that the remainder of the file contains the incompressed data.
  std::vector<uint8_t> uncompressed_data(entry.uncompressed_length);
  ASSERT_EQ(static_cast<ssize_t>(entry.uncompressed_length),
            TEMP_FAILURE_RETRY(
                read(fd, &uncompressed_data[0], entry.uncompressed_length)));
  ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents,
                      sizeof(kATxtContents)));

  // Assert that the total length of the file is sane
  ASSERT_EQ(data_size + sizeof(kATxtContents), lseek64(fd, 0, SEEK_END));

  close(fd);
}

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);