// Copyright 2016 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.

#include "src/tools/singlejar/input_jar.h"

#include <cstddef>
#include <string>

#include "src/tools/singlejar/diag.h"

bool InputJar::Open(const std::string& path) {
  if (!path_.empty()) {
    diag_errx(1, "%s:%d: This instance is already handling %s\n", __FILE__,
              __LINE__, path_.c_str());
  }
  if (!mapped_file_.Open(path)) {
    diag_warn("%s:%d: Cannot open input jar %s", __FILE__, __LINE__,
              path.c_str());
    mapped_file_.Close();
    return false;
  }
  if (mapped_file_.size() < sizeof(ECD)) {
    diag_warnx(
        "%s:%d: %s is only 0x%zx"
        " bytes long, should be at least 0x%zx bytes long",
        __FILE__, __LINE__, path.c_str(), mapped_file_.size(), sizeof(ECD));
    mapped_file_.Close();
    return false;
  }
  return LocateCentralDirectory(path);
}

bool InputJar::Open(const std::string& path, unsigned char* data,
                    size_t length) {
  if (path.empty()) {
    diag_errx(1, "%s:%d: A non-empty path is required\n", __FILE__, __LINE__);
  }
  mapped_file_.MapExisting(data, data + length);
  return LocateCentralDirectory(path);
}

bool InputJar::LocateCentralDirectory(const std::string& path) {
  // Now locate End of Central Directory (ECD) record.
  auto ecd_min = mapped_file_.end() - 65536 - sizeof(ECD);
  if (ecd_min < mapped_file_.start()) {
    ecd_min = mapped_file_.start();
  }

  const ECD* ecd = nullptr;
  for (auto ecd_ptr = mapped_file_.end() - sizeof(ECD); ecd_ptr >= ecd_min;
       --ecd_ptr) {
    if (reinterpret_cast<const ECD*>(ecd_ptr)->is()) {
      ecd = reinterpret_cast<const ECD*>(ecd_ptr);
      break;
    }
  }
  if (ecd == nullptr) {
    diag_warnx("%s:%d: Cannot locate  ECD record in %s", __FILE__, __LINE__,
               path.c_str());
    mapped_file_.Close();
    return false;
  }

  /* Find Central Directory and preamble size. We want to handle the case
   * where a Jar/Zip file contains a preamble (an arbitrary data before the
   * first entry) and 'zip -A' was not called to adjust the offsets, so all
   * the offsets are off by the preamble size. In the 32-bit case (that is,
   * there is no ECD64Locator+ECD64), ECD immediately follows the last CDH,
   * ECD immediately follows the Central Directory, and contains its size, so
   * Central Directory can be found reliably. We then use its stated location,
   * which ECD contains, too, to calculate the preamble size.  In the 64-bit
   * case, there are ECD64 and ECD64Locator records between the end of the
   * Central Directory and the ECD, the calculation is similar, with the
   * exception of the logic to find the actual start of the ECD64.
   * ECD64Locator contains only its position in the file, which is off by
   * preamble size, but does not contain the actual size of ECD64, which in
   * theory is variable (the fixed fields may be followed by some custom data,
   * with the total size saved in ECD64::remaining_size and thus unavailable
   * until we find ECD64.  We assume that the custom data is missing.
   */

  // First, consistency check the directory.
  uint32_t cen_position = ecd->cen_offset32();
  if (!ziph::zfield_has_ext64(cen_position)) {
    if (!mapped_file_.mapped(mapped_file_.address(cen_position))) {
      diag_warnx("%s:%d: %s is corrupt: Central Directory location 0x%" PRIx32
                 " is invalid",
                 __FILE__, __LINE__, path.c_str(), cen_position);
      mapped_file_.Close();
      return false;
    }
    if (mapped_file_.offset(ecd) < cen_position) {
      diag_warnx("%s:%d: %s is corrupt: End of Central Directory at 0x%" PRIx64
                 " precedes Central Directory at 0x%" PRIx32,
                 __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd),
                 cen_position);
      mapped_file_.Close();
      return false;
    }
  }
  uint32_t cen_size = ecd->cen_size32();
  if (!ziph::zfield_has_ext64(cen_size)) {
    if (cen_size > mapped_file_.offset(ecd)) {
      diag_warnx("%s:%d: %s is corrupt: Central Directory size 0x%" PRIx32
                 " is too large",
                 __FILE__, __LINE__, path.c_str(), cen_size);
      mapped_file_.Close();
      return false;
    }
  }
  if (cen_size == 0) {
    // Empty archive, let cdh_ point to End of Central Directory.
    cdh_ = reinterpret_cast<const CDH*>(ecd);
    preamble_size_ = mapped_file_.offset(cdh_) - cen_position;
  } else {
    auto ecd64loc = reinterpret_cast<const ECD64Locator*>(ziph::byte_ptr(ecd) -
                                                          sizeof(ECD64Locator));
    if (ecd64loc->is()) {
      auto ecd64 = reinterpret_cast<const ECD64*>(ziph::byte_ptr(ecd64loc) -
                                                  sizeof(ECD64));
      if (!ecd64->is()) {
        diag_warnx(
            "%s:%d: %s is corrupt, expected ECD64 record at offset 0x%" PRIx64
            " is missing",
            __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd64));
        mapped_file_.Close();
        return false;
      }
      cdh_ = reinterpret_cast<const CDH*>(ziph::byte_ptr(ecd64) -
                                          ecd64->cen_size());
      preamble_size_ = mapped_file_.offset(cdh_) - ecd64->cen_offset();
      // Find CEN and preamble size.
    } else {
      if (ziph::zfield_has_ext64(cen_size) ||
          ziph::zfield_has_ext64(cen_position)) {
        diag_warnx(
            "%s:%d: %s is corrupt, expected ECD64 locator record at "
            "offset 0x%" PRIx64 " is missing",
            __FILE__, __LINE__, path.c_str(), mapped_file_.offset(ecd64loc));
        return false;
      }
      cdh_ = reinterpret_cast<const CDH*>(ziph::byte_ptr(ecd) - cen_size);
      preamble_size_ = mapped_file_.offset(cdh_) - cen_position;
    }
    if (!cdh_->is()) {
      diag_warnx(
          "%s:%d: In %s, expected central file header signature at "
          "offset0x%" PRIx64,
          __FILE__, __LINE__, path.c_str(), mapped_file_.offset(cdh_));
      mapped_file_.Close();
      return false;
    }
  }
  path_ = path;
  return true;
}

bool InputJar::Close() {
  mapped_file_.Close();
  path_.clear();
  return true;
}
