// Copyright 2015 The Bazel Authors. All rights reserved.
//
// 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.
//
// zip.cc -- .zip (.jar) file reading/writing routines.
//

// See README.txt for details.
//
// See http://www.pkware.com/documents/casestudies/APPNOTE.TXT
// for definition of PKZIP file format.

#define _FILE_OFFSET_BITS 64  // Support zip files larger than 2GB

#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <limits.h>
#include <limits>
#include <vector>

#include "third_party/ijar/mapped_file.h"
#include "third_party/ijar/zip.h"
#include "third_party/ijar/zlib_client.h"

#define LOCAL_FILE_HEADER_SIGNATURE   0x04034b50
#define CENTRAL_FILE_HEADER_SIGNATURE 0x02014b50
#define DIGITAL_SIGNATURE             0x05054b50
#define ZIP64_EOCD_SIGNATURE          0x06064b50
#define ZIP64_EOCD_LOCATOR_SIGNATURE  0x07064b50
#define EOCD_SIGNATURE                0x06054b50
#define DATA_DESCRIPTOR_SIGNATURE     0x08074b50

#define U2_MAX 0xffff
#define U4_MAX 0xffffffffUL

#define ZIP64_EOCD_LOCATOR_SIZE 20
// zip64 eocd is fixed size in the absence of a zip64 extensible data sector
#define ZIP64_EOCD_FIXED_SIZE 56

// version to extract: 1.0 - default value from APPNOTE.TXT.
// Output JAR files contain no extra ZIP features, so this is enough.
#define ZIP_VERSION_TO_EXTRACT                10
#define COMPRESSION_METHOD_STORED             0   // no compression
#define COMPRESSION_METHOD_DEFLATED           8

#define GENERAL_PURPOSE_BIT_FLAG_COMPRESSED (1 << 3)
#define GENERAL_PURPOSE_BIT_FLAG_UTF8_ENCODED (1 << 11)
#define GENERAL_PURPOSE_BIT_FLAG_COMPRESSION_SPEED ((1 << 2) | (1 << 1))
#define GENERAL_PURPOSE_BIT_FLAG_SUPPORTED \
  (GENERAL_PURPOSE_BIT_FLAG_COMPRESSED \
  | GENERAL_PURPOSE_BIT_FLAG_UTF8_ENCODED \
  | GENERAL_PURPOSE_BIT_FLAG_COMPRESSION_SPEED)

namespace devtools_ijar {
// In the absence of ZIP64 support, zip files are limited to 4GB.
// http://www.info-zip.org/FAQ.html#limits
static const u8 kMaximumOutputSize = std::numeric_limits<uint32_t>::max();

//
// A class representing a ZipFile for reading. Its public API is exposed
// using the ZipExtractor abstract class.
//
class InputZipFile : public ZipExtractor {
 public:
  InputZipFile(ZipExtractorProcessor *processor, const char* filename);
  virtual ~InputZipFile();

  virtual const char* GetError() {
    if (errmsg[0] == 0) {
      return NULL;
    }
    return errmsg;
  }

  bool Open();
  virtual bool ProcessNext();
  virtual void Reset();
  virtual size_t GetSize() {
    return input_file_->Length();
  }

  virtual u8 CalculateOutputLength();

  virtual bool ProcessCentralDirEntry(const u1 *&p, size_t *compressed_size,
                                      size_t *uncompressed_size, char *filename,
                                      size_t filename_size, u4 *attr,
                                      u4 *offset);

 private:
  ZipExtractorProcessor *processor;
  const char* filename_;
  MappedInputFile *input_file_;

  // InputZipFile is responsible for maintaining the following
  // pointers. They are allocated by the Create() method before
  // the object is actually created using mmap.
  const u1 * zipdata_in_;   // start of input file mmap
  size_t bytes_unmapped_;         // bytes that have already been unmapped
  const u1 * central_dir_;  // central directory in input file

  size_t in_offset_;  // offset  the input file

  const u1 *p;  // input cursor

  const u1* central_dir_current_;  // central dir input cursor

  // Buffer size is initially INITIAL_BUFFER_SIZE. It doubles in size every
  // time it is found too small, until it reaches MAX_BUFFER_SIZE. If that is
  // not enough, we bail out. We only decompress class files, so they should
  // be smaller than 64K anyway, but we give a little leeway.
  // MAX_BUFFER_SIZE must be bigger than the size of the biggest file in the
  // ZIP. It is set to 2GB here because no one has audited the code for 64-bit
  // cleanliness.
  static const size_t INITIAL_BUFFER_SIZE = 256 * 1024;  // 256K
  static const size_t MAX_BUFFER_SIZE = std::numeric_limits<int32_t>::max();
  static const size_t MAX_MAPPED_REGION = 32 * 1024 * 1024;

  // These metadata fields are the fields of the ZIP header of the file being
  // processed.
  u2 extract_version_;
  u2 general_purpose_bit_flag_;
  u2 compression_method_;
  u4 uncompressed_size_;
  u4 compressed_size_;
  u2 file_name_length_;
  u2 extra_field_length_;
  const u1 *file_name_;
  const u1 *extra_field_;

  // Administration of memory reserved for decompressed data. We use the same
  // buffer for each file to avoid some malloc()/free() calls and free the
  // memory only in the dtor. C-style memory management is used so that we
  // can call realloc.
  u1 *uncompressed_data_;
  size_t uncompressed_data_allocated_;

  // Copy of the last filename entry - Null-terminated.
  char filename[PATH_MAX];
  // The external file attribute field
  u4 attr;

  // last error
  char errmsg[4*PATH_MAX];

  Decompressor *decompressor_;

  int error(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(errmsg, 4*PATH_MAX, fmt, ap);
    va_end(ap);
    return -1;
  }

  // Check that at least n bytes remain in the input file, otherwise
  // abort with an error message.  "state" is the name of the field
  // we're about to read, for diagnostics.
  int EnsureRemaining(size_t n, const char *state) {
    size_t in_offset = p - zipdata_in_;
    size_t remaining = input_file_->Length() - in_offset;
    if (n > remaining) {
      return error("Premature end of file (at offset %zd, state=%s); "
                   "expected %zd more bytes but found %zd.\n",
                   in_offset, state, n, remaining);
    }
    return 0;
  }

  // Read one entry from input zip file
  int ProcessLocalFileEntry(size_t compressed_size, size_t uncompressed_size);

  // Uncompress a file from the archive using zlib. The pointer returned
  // is owned by InputZipFile, so it must not be freed. Advances the input
  // cursor to the first byte after the compressed data.
  u1* UncompressFile();

  // Skip a file
  int SkipFile(const bool compressed);

  // Process a file
  int ProcessFile(const bool compressed);
};

//
// A class implementing ZipBuilder that represent an open zip file for writing.
//
class OutputZipFile : public ZipBuilder {
 public:
  OutputZipFile(const char* filename, u8 estimated_size) :
      output_file_(NULL),
      filename_(filename),
      estimated_size_(estimated_size),
      finished_(false) {
    errmsg[0] = 0;
  }

  virtual const char* GetError() {
    if (errmsg[0] == 0) {
      return NULL;
    }
    return errmsg;
  }

  virtual ~OutputZipFile() { Finish(); }
  virtual u1* NewFile(const char* filename, const u4 attr);
  virtual int FinishFile(size_t filelength, bool compress = false,
                         bool compute_crc = false);
  virtual int WriteEmptyFile(const char *filename);
  virtual size_t GetSize() {
    return Offset(q);
  }
  virtual int GetNumberFiles() {
    return entries_.size();
  }
  virtual int Finish();
  bool Open();

 private:
  struct LocalFileEntry {
    // Start of the local header (in the output buffer).
    size_t local_header_offset;

    // Sizes of the file entry
    size_t uncompressed_length;
    size_t compressed_length;

    // Compression method
    u2 compression_method;

    // CRC32
    u4 crc32;

    // external attributes field
    u4 external_attr;

    // Start/length of the file_name in the local header.
    u1 *file_name;
    u2 file_name_length;

    // Start/length of the extra_field in the local header.
    const u1 *extra_field;
    u2 extra_field_length;
  };

  MappedOutputFile* output_file_;
  const char* filename_;
  u8 estimated_size_;
  bool finished_;

  // OutputZipFile is responsible for maintaining the following
  // pointers. They are allocated by the Create() method before
  // the object is actually created using mmap.
  u1 *zipdata_out_;        // start of output file mmap
  u1 *q;  // output cursor

  u1 *header_ptr;  // Current pointer to "compression method" entry.

  // List of entries to write the central directory
  std::vector<LocalFileEntry*> entries_;

  // last error
  char errmsg[4*PATH_MAX];

  int error(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(errmsg, 4*PATH_MAX, fmt, ap);
    va_end(ap);
    return -1;
  }

  // Write the ZIP central directory structure for each local file
  // entry in "entries".
  void WriteCentralDirectory();

  // Returns the offset of the pointer relative to the start of the
  // output zip file.
  size_t Offset(const u1 *const x) {
    return x - zipdata_out_;
  }

  // Write ZIP file header in the output. Since the compressed size is not
  // known in advance, it must be recorded later. This method returns a pointer
  // to "compressed size" in the file header that should be passed to
  // WriteFileSizeInLocalFileHeader() later.
  u1* WriteLocalFileHeader(const char *filename, const u4 attr);

  // Fill in the "compressed size" and "uncompressed size" fields in a local
  // file header previously written by WriteLocalFileHeader().
  size_t WriteFileSizeInLocalFileHeader(u1 *header_ptr,
                                        size_t out_length,
                                        bool compress = false,
                                        const u4 crc = 0);
};

//
// Implementation of InputZipFile
//
bool InputZipFile::ProcessNext() {
  // Process the next entry in the central directory. Also make sure that the
  // content pointer is in sync.
  size_t compressed, uncompressed;
  u4 offset;
  if (!ProcessCentralDirEntry(central_dir_current_, &compressed, &uncompressed,
                              filename, PATH_MAX, &attr, &offset)) {
    return false;
  }

  // There might be an offset specified in the central directory that does
  // not match the file offset, if so, correct the pointer.
  if (offset != 0 && (p != (zipdata_in_ + in_offset_ + offset))) {
    p = zipdata_in_ + offset;
  }

  if (EnsureRemaining(4, "signature") < 0) {
    return false;
  }
  u4 signature = get_u4le(p);
  if (signature == LOCAL_FILE_HEADER_SIGNATURE) {
    if (ProcessLocalFileEntry(compressed, uncompressed) < 0) {
      return false;
    }
  } else {
    error("local file header signature for file %s not found\n", filename);
    return false;
  }

  return true;
}

int InputZipFile::ProcessLocalFileEntry(
    size_t compressed_size, size_t uncompressed_size) {
  if (EnsureRemaining(26, "extract_version") < 0) {
    return -1;
  }
  extract_version_ = get_u2le(p);
  general_purpose_bit_flag_ = get_u2le(p);

  if ((general_purpose_bit_flag_ & ~GENERAL_PURPOSE_BIT_FLAG_SUPPORTED) != 0) {
    return error("Unsupported value (0x%04x) in general purpose bit flag.\n",
                 general_purpose_bit_flag_);
  }

  compression_method_ = get_u2le(p);

  if (compression_method_ != COMPRESSION_METHOD_DEFLATED &&
      compression_method_ != COMPRESSION_METHOD_STORED) {
    return error("Unsupported compression method (%d).\n",
                 compression_method_);
  }

  // skip over: last_mod_file_time, last_mod_file_date, crc32
  p += 2 + 2 + 4;
  compressed_size_ = get_u4le(p);
  uncompressed_size_ = get_u4le(p);
  file_name_length_ = get_u2le(p);
  extra_field_length_ = get_u2le(p);

  if (EnsureRemaining(file_name_length_, "file_name") < 0) {
    return -1;
  }
  file_name_ = p;
  p += file_name_length_;

  if (EnsureRemaining(extra_field_length_, "extra_field") < 0) {
    return -1;
  }
  extra_field_ = p;
  p += extra_field_length_;

  bool is_compressed = compression_method_ == COMPRESSION_METHOD_DEFLATED;

  // If the zip is compressed, compressed and uncompressed size members are
  // zero in the local file header. If not, check that they are the same as the
  // lengths from the central directory, otherwise, just believe the central
  // directory
  if (compressed_size_ == 0) {
    compressed_size_ = compressed_size;
  } else {
    if (compressed_size_ != compressed_size) {
      return error("central directory and file header inconsistent\n");
    }
  }

  if (uncompressed_size_ == 0) {
    uncompressed_size_ = uncompressed_size;
  } else {
    if (uncompressed_size_ != uncompressed_size) {
      return error("central directory and file header inconsistent\n");
    }
  }

  if (processor->Accept(filename, attr)) {
    if (ProcessFile(is_compressed) < 0) {
      return -1;
    }
  } else {
    if (SkipFile(is_compressed) < 0) {
      return -1;
    }
  }

  if (general_purpose_bit_flag_ & GENERAL_PURPOSE_BIT_FLAG_COMPRESSED) {
    // Skip the data descriptor. Some implementations do not put the signature
    // here, so check if the next 4 bytes are a signature, and if so, skip the
    // next 12 bytes (for CRC, compressed/uncompressed size), otherwise skip
    // the next 8 bytes (because the value just read was the CRC).
    u4 signature = get_u4le(p);
    if (signature == DATA_DESCRIPTOR_SIGNATURE) {
      p += 4 * 3;
    } else {
      p += 4 * 2;
    }
  }

  size_t bytes_processed = p - zipdata_in_;
  if (bytes_processed > bytes_unmapped_ + MAX_MAPPED_REGION) {
    input_file_->Discard(MAX_MAPPED_REGION);
    bytes_unmapped_ += MAX_MAPPED_REGION;
  }

  return 0;
}

int InputZipFile::SkipFile(const bool compressed) {
  if (!compressed) {
    // In this case, compressed_size_ == uncompressed_size_ (since the file is
    // uncompressed), so we can use either.
    if (compressed_size_ != uncompressed_size_) {
      return error("compressed size != uncompressed size, although the file "
                   "is uncompressed.\n");
    }
  }

  if (EnsureRemaining(compressed_size_, "file_data") < 0) {
    return -1;
  }
  p += compressed_size_;
  return 0;
}

u1* InputZipFile::UncompressFile() {
  size_t in_offset = p - zipdata_in_;
  size_t remaining = input_file_->Length() - in_offset;
  DecompressedFile *decompressed_file =
      decompressor_->UncompressFile(p, remaining);
  if (decompressed_file == NULL) {
    if (decompressor_->GetError() != NULL) {
      error(decompressor_->GetError());
    }
    return NULL;
  } else {
    compressed_size_ = decompressed_file->compressed_size;
    uncompressed_size_ = decompressed_file->uncompressed_size;
    u1 *uncompressed_data = decompressed_file->uncompressed_data;
    free(decompressed_file);
    p += compressed_size_;
    return uncompressed_data;
  }
}

int InputZipFile::ProcessFile(const bool compressed) {
  const u1 *file_data;
  if (compressed) {
    file_data = UncompressFile();
    if (file_data == NULL) {
      return -1;
    }
  } else {
    // In this case, compressed_size_ == uncompressed_size_ (since the file is
    // uncompressed), so we can use either.
    if (compressed_size_ != uncompressed_size_) {
      return error("compressed size != uncompressed size, although the file "
                   "is uncompressed.\n");
    }

    if (EnsureRemaining(compressed_size_, "file_data") < 0) {
      return -1;
    }
    file_data = p;
    p += compressed_size_;
  }
  processor->Process(filename, attr, file_data, uncompressed_size_);
  return 0;
}


// Reads and returns some metadata of the next file from the central directory:
// - compressed size
// - uncompressed size
// - whether the entry is a class file (to be included in the output).
// Precondition: p points to the beginning of an entry in the central dir
// Postcondition: p points to the beginning of the next entry in the central dir
// Returns true if the central directory contains another file and false if not.
// Of course, in the latter case, the size output variables are not changed.
// Note that the central directory is always followed by another data structure
// that has a signature, so parsing it this way is safe.
bool InputZipFile::ProcessCentralDirEntry(const u1 *&p, size_t *compressed_size,
                                          size_t *uncompressed_size,
                                          char *filename, size_t filename_size,
                                          u4 *attr, u4 *offset) {
  u4 signature = get_u4le(p);

  if (signature != CENTRAL_FILE_HEADER_SIGNATURE) {
    if (signature != DIGITAL_SIGNATURE && signature != EOCD_SIGNATURE &&
        signature != ZIP64_EOCD_SIGNATURE) {
      error("invalid central file header signature: 0x%x\n", signature);
    }
    return false;
  }

  p += 16;  // skip to 'compressed size' field
  *compressed_size = get_u4le(p);
  *uncompressed_size = get_u4le(p);
  u2 file_name_length = get_u2le(p);
  u2 extra_field_length = get_u2le(p);
  u2 file_comment_length = get_u2le(p);
  p += 4;  // skip to external file attributes field
  *attr = get_u4le(p);
  *offset = get_u4le(p);
  {
    size_t len = (file_name_length < filename_size)
      ? file_name_length
      : (filename_size - 1);
    memcpy(reinterpret_cast<void*>(filename), p, len);
    filename[len] = 0;
  }
  p += file_name_length;
  p += extra_field_length;
  p += file_comment_length;
  return true;
}

// Gives a maximum bound on the size of the interface JAR. Basically, adds
// the difference between the compressed and uncompressed sizes to the size
// of the input file.
u8 InputZipFile::CalculateOutputLength() {
  const u1* current = central_dir_;

  u8 compressed_size = 0;
  u8 uncompressed_size = 0;
  u8 skipped_compressed_size = 0;
  u4 attr;
  u4 offset;
  char filename[PATH_MAX];

  while (true) {
    size_t file_compressed, file_uncompressed;
    if (!ProcessCentralDirEntry(current,
                                &file_compressed, &file_uncompressed,
                                filename, PATH_MAX, &attr, &offset)) {
      break;
    }

    if (processor->Accept(filename, attr)) {
      compressed_size += (u8) file_compressed;
      uncompressed_size += (u8) file_uncompressed;
    } else {
      skipped_compressed_size += file_compressed;
    }
  }

  // The worst case is when the output is simply the input uncompressed. The
  // metadata in the zip file will stay the same, so the file will grow by the
  // difference between the compressed and uncompressed sizes.
  return (u8) input_file_->Length() - skipped_compressed_size
      + (uncompressed_size - compressed_size);
}

// An end of central directory record, sized for optional zip64 contents.
struct EndOfCentralDirectoryRecord {
  u4 number_of_this_disk;
  u4 disk_with_central_dir;
  u8 central_dir_entries_on_this_disk;
  u8 central_dir_entries;
  u8 central_dir_size;
  u8 central_dir_offset;
};

// Checks for a zip64 end of central directory record. If a valid zip64 EOCD is
// found, updates the original EOCD record and returns true.
bool MaybeReadZip64CentralDirectory(const u1 *bytes, size_t in_length,
                                    const u1 *current,
                                    const u1 **end_of_central_dir,
                                    EndOfCentralDirectoryRecord *cd) {
  if (current < bytes) {
    return false;
  }
  const u1 *candidate = current;
  u4 zip64_directory_signature = get_u4le(current);
  if (zip64_directory_signature != ZIP64_EOCD_SIGNATURE) {
    return false;
  }

  // size of zip64 end of central directory record
  // (fixed size unless there's a zip64 extensible data sector, which
  // we don't need to read)
  get_u8le(current);
  get_u2be(current);  // version made by
  get_u2be(current);  // version needed to extract

  u4 number_of_this_disk = get_u4be(current);
  u4 disk_with_central_dir = get_u4le(current);
  u8 central_dir_entries_on_this_disk = get_u8le(current);
  u8 central_dir_entries = get_u8le(current);
  u8 central_dir_size = get_u8le(current);
  u8 central_dir_offset = get_u8le(current);

  // check for a zip64 EOCD that matches the regular EOCD
  if (number_of_this_disk != cd->number_of_this_disk &&
      cd->number_of_this_disk != U2_MAX) {
    return false;
  }
  if (disk_with_central_dir != cd->disk_with_central_dir &&
      cd->disk_with_central_dir != U2_MAX) {
    return false;
  }
  if (central_dir_entries_on_this_disk !=
          cd->central_dir_entries_on_this_disk &&
      cd->central_dir_entries_on_this_disk != U2_MAX) {
    return false;
  }
  if (central_dir_entries != cd->central_dir_entries &&
      cd->central_dir_entries != U2_MAX) {
    return false;
  }
  if (central_dir_size != cd->central_dir_size &&
      cd->central_dir_size != U4_MAX) {
    return false;
  }
  if (central_dir_offset != cd->central_dir_offset &&
      cd->central_dir_offset != U4_MAX) {
    return false;
  }

  *end_of_central_dir = candidate;
  cd->number_of_this_disk = number_of_this_disk;
  cd->disk_with_central_dir = disk_with_central_dir;
  cd->central_dir_entries_on_this_disk = central_dir_entries_on_this_disk;
  cd->central_dir_entries = central_dir_entries;
  cd->central_dir_size = central_dir_size;
  cd->central_dir_offset = central_dir_offset;
  return true;
}

// Starting from the end of central directory record, attempts to locate a zip64
// end of central directory record. If found, updates the given record and
// offset with the zip64 data. Returns false on error.
bool FindZip64CentralDirectory(const u1 *bytes, size_t in_length,
                               const u1 **end_of_central_dir,
                               EndOfCentralDirectoryRecord *cd) {
  // In the absence of a zip64 extensible data sector, the zip64 EOCD is at a
  // fixed offset from the regular central directory.
  if (MaybeReadZip64CentralDirectory(
          bytes, in_length,
          *end_of_central_dir - ZIP64_EOCD_LOCATOR_SIZE - ZIP64_EOCD_FIXED_SIZE,
          end_of_central_dir, cd)) {
    return true;
  }

  // If we couldn't find a zip64 EOCD at a fixed offset, either it doesn't exist
  // or there was a zip64 extensible data sector, so try going through the
  // locator. This approach doesn't work if data was prepended to the archive
  // without updating the offset in the locator.
  const u1 *zip64_locator = *end_of_central_dir - ZIP64_EOCD_LOCATOR_SIZE;
  if (zip64_locator - ZIP64_EOCD_FIXED_SIZE < bytes) {
    return true;
  }
  u4 zip64_locator_signature = get_u4le(zip64_locator);
  if (zip64_locator_signature != ZIP64_EOCD_LOCATOR_SIGNATURE) {
    return true;
  }
  u4 disk_with_zip64_central_directory = get_u4le(zip64_locator);
  u8 zip64_end_of_central_dir_offset = get_u8le(zip64_locator);
  u4 zip64_total_disks = get_u4le(zip64_locator);
  if (MaybeReadZip64CentralDirectory(bytes, in_length,
                                     bytes + zip64_end_of_central_dir_offset,
                                     end_of_central_dir, cd)) {
    if (disk_with_zip64_central_directory != 0 || zip64_total_disks != 1) {
      fprintf(stderr, "multi-disk JAR files are not supported\n");
      return false;
    }
    return true;
  }
  return true;
}

// Given the data in the zip file, returns the offset of the central directory
// and the number of files contained in it.
bool FindZipCentralDirectory(const u1 *bytes, size_t in_length, u4 *offset,
                             const u1 **central_dir) {
  static const int MAX_COMMENT_LENGTH = 0xffff;
  static const int CENTRAL_DIR_LOCATOR_SIZE = 22;
  // Maximum distance of start of central dir locator from end of file
  static const int MAX_DELTA = MAX_COMMENT_LENGTH + CENTRAL_DIR_LOCATOR_SIZE;
  const u1* last_pos_to_check = in_length < MAX_DELTA
      ? bytes
      : bytes + (in_length - MAX_DELTA);
  const u1* current;
  bool found = false;

  for (current = bytes + in_length - CENTRAL_DIR_LOCATOR_SIZE;
       current >= last_pos_to_check;
       current-- ) {
    const u1* p = current;
    if (get_u4le(p) != EOCD_SIGNATURE) {
      continue;
    }

    p += 16;  // skip to comment length field
    u2 comment_length = get_u2le(p);

    // Does the comment go exactly till the end of the file?
    if (current + comment_length + CENTRAL_DIR_LOCATOR_SIZE
        != bytes + in_length) {
      continue;
    }

    // Hooray, we found it!
    found = true;
    break;
  }

  if (!found) {
    fprintf(stderr, "file is invalid or corrupted (missing end of central "
                    "directory record)\n");
    return false;
  }

  EndOfCentralDirectoryRecord cd;
  const u1* end_of_central_dir = current;
  get_u4le(current);  // central directory locator signature, already checked
  cd.number_of_this_disk = get_u2le(current);
  cd.disk_with_central_dir = get_u2le(current);
  cd.central_dir_entries_on_this_disk = get_u2le(current);
  cd.central_dir_entries = get_u2le(current);
  cd.central_dir_size = get_u4le(current);
  cd.central_dir_offset = get_u4le(current);
  u2 file_comment_length = get_u2le(current);
  current += file_comment_length;  // set current to the end of the central dir

  if (!FindZip64CentralDirectory(bytes, in_length, &end_of_central_dir, &cd)) {
    return false;
  }

  if (cd.number_of_this_disk != 0 || cd.disk_with_central_dir != 0 ||
      cd.central_dir_entries_on_this_disk != cd.central_dir_entries) {
    fprintf(stderr, "multi-disk JAR files are not supported\n");
    return false;
  }

  // Do not change output values before determining that they are OK.
  *offset = cd.central_dir_offset;
  // Central directory start can then be used to determine the actual
  // starts of the zip file (which can be different in case of a non-zip
  // header like for auto-extractable binaries).
  *central_dir = end_of_central_dir - cd.central_dir_size;
  return true;
}

void InputZipFile::Reset() {
  central_dir_current_ = central_dir_;
  bytes_unmapped_ = 0;
  p = zipdata_in_ + in_offset_;
}

int ZipExtractor::ProcessAll() {
  while (ProcessNext()) {}
  if (GetError() != NULL) {
    return -1;
  }
  return 0;
}

ZipExtractor* ZipExtractor::Create(const char* filename,
                                   ZipExtractorProcessor *processor) {
  InputZipFile* result = new InputZipFile(processor, filename);
  if (!result->Open()) {
    fprintf(stderr, "%s\n", result->GetError());
    delete result;
    return NULL;
  }

  return result;
}

// zipdata_in_, in_offset_, p, central_dir_current_

InputZipFile::InputZipFile(ZipExtractorProcessor *processor,
                           const char* filename)
    : processor(processor), filename_(filename), input_file_(NULL),
      bytes_unmapped_(0) {
  decompressor_ = new Decompressor();
  errmsg[0] = 0;
}

bool InputZipFile::Open() {
  MappedInputFile* input_file = new MappedInputFile(filename_);
  if (!input_file->Opened()) {
    snprintf(errmsg, sizeof(errmsg), "%s", input_file->Error());
    delete input_file;
    return false;
  }

  void *zipdata_in = input_file->Buffer();
  u4 central_dir_offset;
  const u1 *central_dir = NULL;

  if (!devtools_ijar::FindZipCentralDirectory(
          static_cast<const u1*>(zipdata_in), input_file->Length(),
          &central_dir_offset, &central_dir)) {
    errno = EIO;  // we don't really have a good error number
    error("Cannot find central directory");
    delete input_file;
    return false;
  }
  const u1 *zipdata_start = static_cast<const u1*>(zipdata_in);
  in_offset_ = - static_cast<off_t>(zipdata_start
                                    + central_dir_offset
                                    - central_dir);

  input_file_ = input_file;
  zipdata_in_ = zipdata_start;
  central_dir_ = central_dir;
  central_dir_current_ = central_dir;
  p = zipdata_in_ + in_offset_;
  errmsg[0] = 0;
  return true;
}

InputZipFile::~InputZipFile() {
  delete decompressor_;
  if (input_file_ != NULL) {
    input_file_->Close();
    delete input_file_;
  }
}


//
// Implementation of OutputZipFile
//
int OutputZipFile::WriteEmptyFile(const char *filename) {
  const u1* file_name = (const u1*) filename;
  size_t file_name_length = strlen(filename);

  LocalFileEntry *entry = new LocalFileEntry;
  entry->local_header_offset = Offset(q);
  entry->external_attr = 0;
  entry->crc32 = 0;

  // Output the ZIP local_file_header:
  put_u4le(q, LOCAL_FILE_HEADER_SIGNATURE);
  put_u2le(q, 10);  // extract_version
  put_u2le(q, 0);  // general_purpose_bit_flag
  put_u2le(q, 0);  // compression_method
  put_u2le(q, 0);  // last_mod_file_time
  put_u2le(q, 0);  // last_mod_file_date
  put_u4le(q, entry->crc32);  // crc32
  put_u4le(q, 0);  // compressed_size
  put_u4le(q, 0);  // uncompressed_size
  put_u2le(q, file_name_length);
  put_u2le(q, 0);  // extra_field_length
  put_n(q, file_name, file_name_length);

  entry->file_name_length = file_name_length;
  entry->extra_field_length = 0;
  entry->compressed_length = 0;
  entry->uncompressed_length = 0;
  entry->compression_method = 0;
  entry->extra_field = (const u1 *)"";
  entry->file_name = (u1*) strdup((const char *) file_name);
  entries_.push_back(entry);

  return 0;
}

void OutputZipFile::WriteCentralDirectory() {
  // central directory:
  const u1 *central_directory_start = q;
  for (size_t ii = 0; ii < entries_.size(); ++ii) {
    LocalFileEntry *entry = entries_[ii];
    put_u4le(q, CENTRAL_FILE_HEADER_SIGNATURE);
    put_u2le(q, 0);  // version made by

    put_u2le(q, ZIP_VERSION_TO_EXTRACT);  // version to extract
    put_u2le(q, 0);  // general purpose bit flag
    put_u2le(q, entry->compression_method);  // compression method:
    put_u2le(q, 0);                          // last_mod_file_time
    put_u2le(q, 0);  // last_mod_file_date
    put_u4le(q, entry->crc32);  // crc32
    put_u4le(q, entry->compressed_length);    // compressed_size
    put_u4le(q, entry->uncompressed_length);  // uncompressed_size
    put_u2le(q, entry->file_name_length);
    put_u2le(q, entry->extra_field_length);

    put_u2le(q, 0);  // file comment length
    put_u2le(q, 0);  // disk number start
    put_u2le(q, 0);  // internal file attributes
    put_u4le(q, entry->external_attr);  // external file attributes
    // relative offset of local header:
    put_u4le(q, entry->local_header_offset);

    put_n(q, entry->file_name, entry->file_name_length);
    put_n(q, entry->extra_field, entry->extra_field_length);
  }
  u8 central_directory_size = q - central_directory_start;

  if (entries_.size() > U2_MAX || central_directory_size > U4_MAX ||
      Offset(central_directory_start) > U4_MAX) {
    u1 *zip64_end_of_central_directory_start = q;

    put_u4le(q, ZIP64_EOCD_SIGNATURE);
    // signature and size field doesn't count towards size
    put_u8le(q, ZIP64_EOCD_FIXED_SIZE - 12);
    put_u2le(q, 0);  // version made by
    put_u2le(q, 0);  // version needed to extract
    put_u4le(q, 0);  // number of this disk
    put_u4le(q, 0);  // # of the disk with the start of the central directory
    put_u8le(q, entries_.size());  // # central dir entries on this disk
    put_u8le(q, entries_.size());  // total # entries in the central directory
    put_u8le(q, central_directory_size);  // size of the central directory
    // offset of start of central directory wrt starting disk
    put_u8le(q, Offset(central_directory_start));

    put_u4le(q, ZIP64_EOCD_LOCATOR_SIGNATURE);
    // number of the disk with the start of the zip64 end of central directory
    put_u4le(q, 0);
    // relative offset of the zip64 end of central directory record
    put_u8le(q, Offset(zip64_end_of_central_directory_start));
    // total number of disks
    put_u4le(q, 1);

    put_u4le(q, EOCD_SIGNATURE);
    put_u2le(q, 0);  // number of this disk
    put_u2le(q, 0);  // # of disk with the start of the central directory
    // # central dir entries on this disk
    put_u2le(q, entries_.size() > 0xffff ? 0xffff : entries_.size());
    // total # entries in the central directory
    put_u2le(q, entries_.size() > 0xffff ? 0xffff : entries_.size());
    // size of the central directory
    put_u4le(q,
             central_directory_size > U4_MAX ? U4_MAX : central_directory_size);
    // offset of start of central
    put_u4le(q, Offset(central_directory_start) > U4_MAX
                    ? U4_MAX
                    : Offset(central_directory_start));
    put_u2le(q, 0);  // .ZIP file comment length

  } else {
    put_u4le(q, EOCD_SIGNATURE);
    put_u2le(q, 0);  // number of this disk
    put_u2le(q, 0);  // # of the disk with the start of the central directory
    put_u2le(q, entries_.size());  // # central dir entries on this disk
    put_u2le(q, entries_.size());  // total # entries in the central directory
    put_u4le(q, central_directory_size);  // size of the central directory
    // offset of start of central directory wrt starting disk
    put_u4le(q, Offset(central_directory_start));
    put_u2le(q, 0);  // .ZIP file comment length
  }
}

u1* OutputZipFile::WriteLocalFileHeader(const char* filename, const u4 attr) {
  off_t file_name_length_ = strlen(filename);
  LocalFileEntry *entry = new LocalFileEntry;
  entry->local_header_offset = Offset(q);
  entry->file_name_length = file_name_length_;
  entry->file_name = new u1[file_name_length_];
  entry->external_attr = attr;
  memcpy(entry->file_name, filename, file_name_length_);
  entry->extra_field_length = 0;
  entry->extra_field = (const u1 *)"";
  entry->crc32 = 0;

  // Output the ZIP local_file_header:
  put_u4le(q, LOCAL_FILE_HEADER_SIGNATURE);
  put_u2le(q, ZIP_VERSION_TO_EXTRACT);     // version to extract
  put_u2le(q, 0);                          // general purpose bit flag
  u1 *header_ptr = q;
  put_u2le(q, COMPRESSION_METHOD_STORED);  // compression method = placeholder
  put_u2le(q, 0);                          // last_mod_file_time
  put_u2le(q, 0);                          // last_mod_file_date
  put_u4le(q, entry->crc32);               // crc32
  put_u4le(q, 0);  // compressed_size = placeholder
  put_u4le(q, 0);  // uncompressed_size = placeholder
  put_u2le(q, entry->file_name_length);
  put_u2le(q, entry->extra_field_length);

  put_n(q, entry->file_name, entry->file_name_length);
  put_n(q, entry->extra_field, entry->extra_field_length);
  entries_.push_back(entry);

  return header_ptr;
}

size_t OutputZipFile::WriteFileSizeInLocalFileHeader(u1 *header_ptr,
                                                     size_t out_length,
                                                     bool compress,
                                                     const u4 crc) {
  size_t compressed_size = out_length;
  if (compress) {
    compressed_size = TryDeflate(q, out_length);
  }
  // compression method
  if (compressed_size < out_length) {
    put_u2le(header_ptr, COMPRESSION_METHOD_DEFLATED);
  } else {
    put_u2le(header_ptr, COMPRESSION_METHOD_STORED);
  }
  header_ptr += 4;
  put_u4le(header_ptr, crc);              // crc32
  put_u4le(header_ptr, compressed_size);  // compressed_size
  put_u4le(header_ptr, out_length);       // uncompressed_size
  return compressed_size;
}

int OutputZipFile::Finish() {
  if (finished_) {
    return 0;
  }

  finished_ = true;
  WriteCentralDirectory();
  if (output_file_->Close(GetSize()) < 0) {
    return error("%s", output_file_->Error());
  }
  delete output_file_;
  output_file_ = NULL;
  return 0;
}

u1* OutputZipFile::NewFile(const char* filename, const u4 attr) {
  header_ptr = WriteLocalFileHeader(filename, attr);
  return q;
}

int OutputZipFile::FinishFile(size_t filelength, bool compress,
                              bool compute_crc) {
  u4 crc = 0;
  if (compute_crc) {
    crc = ComputeCrcChecksum(q, filelength);

    if (filelength > 0 && crc == 0) {
      fprintf(stderr, "Error calculating CRC32 checksum.\n");
      return -1;
    }
  }
  size_t compressed_size =
      WriteFileSizeInLocalFileHeader(header_ptr, filelength, compress, crc);

  if (compressed_size == 0 && filelength > 0) {
    fprintf(stderr, "Error compressing files.\n");
    return -1;
  }

  entries_.back()->crc32 = crc;
  entries_.back()->compressed_length = compressed_size;
  entries_.back()->uncompressed_length = filelength;
  if (compressed_size < filelength) {
    entries_.back()->compression_method = COMPRESSION_METHOD_DEFLATED;
  } else {
    entries_.back()->compression_method = COMPRESSION_METHOD_STORED;
  }
  q += compressed_size;
  return 0;
}

bool OutputZipFile::Open() {
  if (estimated_size_ > kMaximumOutputSize) {
    fprintf(stderr,
            "Uncompressed input jar has size %llu, "
            "which exceeds the maximum supported output size %llu.\n"
            "Assuming that ijar will be smaller and hoping for the best.\n",
            estimated_size_, kMaximumOutputSize);
    estimated_size_ = kMaximumOutputSize;
  }

  MappedOutputFile* output_file = new MappedOutputFile(
      filename_, estimated_size_);
  if (!output_file->Opened()) {
    snprintf(errmsg, sizeof(errmsg), "%s", output_file->Error());
    delete output_file;
    return false;
  }

  output_file_ = output_file;
  q = output_file->Buffer();
  zipdata_out_ = output_file->Buffer();
  return true;
}

ZipBuilder* ZipBuilder::Create(const char* zip_file, u8 estimated_size) {
  OutputZipFile* result = new OutputZipFile(zip_file, estimated_size);
  if (!result->Open()) {
    fprintf(stderr, "%s\n", result->GetError());
    delete result;
    return NULL;
  }

  return result;
}

u8 ZipBuilder::EstimateSize(char const* const* files,
                            char const* const* zip_paths,
                            int nb_entries) {
  struct stat statst;
  // Digital signature field size = 6, End of central directory = 22, Total = 28
  u8 size = 28;
  // Count the size of all the files in the input to estimate the size of the
  // output.
  for (int i = 0; i < nb_entries; i++) {
    statst.st_size = 0;
    if (files[i] != NULL && stat(files[i], &statst) != 0) {
      fprintf(stderr, "File %s does not seem to exist.", files[i]);
      return 0;
    }
    size += statst.st_size;
    // Add sizes of Zip meta data
    // local file header = 30 bytes
    // data descriptor = 12 bytes
    // central directory descriptor = 46 bytes
    //    Total: 88bytes
    size += 88;
    // The filename is stored twice (once in the central directory
    // and once in the local file header).
    size += strlen((zip_paths[i] != NULL) ? zip_paths[i] : files[i]) * 2;
  }
  return size;
}

}  // namespace devtools_ijar
