// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "third_party/zlib/google/zip.h"
#include "third_party/zlib/google/zip_reader.h"

namespace {

bool CreateFile(const std::string& content,
                base::FilePath* file_path,
                base::File* file) {
  if (!base::CreateTemporaryFile(file_path))
    return false;

  if (base::WriteFile(*file_path, content.data(), content.size()) == -1)
    return false;

  *file = base::File(
      *file_path, base::File::Flags::FLAG_OPEN | base::File::Flags::FLAG_READ);
  return file->IsValid();
}

// A virtual file system containing:
// /test
// /test/foo.txt
// /test/bar/bar1.txt
// /test/bar/bar2.txt
// Used to test providing a custom zip::FileAccessor when unzipping.
class VirtualFileSystem : public zip::FileAccessor {
 public:
  static constexpr char kFooContent[] = "This is foo.";
  static constexpr char kBar1Content[] = "This is bar.";
  static constexpr char kBar2Content[] = "This is bar too.";

  VirtualFileSystem() {
    base::FilePath test_dir(FILE_PATH_LITERAL("/test"));
    base::FilePath foo_txt_path = test_dir.Append(FILE_PATH_LITERAL("foo.txt"));

    base::FilePath file_path;
    base::File file;
    bool success = CreateFile(kFooContent, &file_path, &file);
    DCHECK(success);
    files_[foo_txt_path] = std::move(file);

    base::FilePath bar_dir = test_dir.Append(FILE_PATH_LITERAL("bar"));
    base::FilePath bar1_txt_path =
        bar_dir.Append(FILE_PATH_LITERAL("bar1.txt"));
    success = CreateFile(kBar1Content, &file_path, &file);
    DCHECK(success);
    files_[bar1_txt_path] = std::move(file);

    base::FilePath bar2_txt_path =
        bar_dir.Append(FILE_PATH_LITERAL("bar2.txt"));
    success = CreateFile(kBar2Content, &file_path, &file);
    DCHECK(success);
    files_[bar2_txt_path] = std::move(file);

    file_tree_[test_dir] = std::vector<DirectoryContentEntry>{
        DirectoryContentEntry(foo_txt_path, /*is_dir=*/false),
        DirectoryContentEntry(bar_dir, /*is_dir=*/true)};
    file_tree_[bar_dir] = std::vector<DirectoryContentEntry>{
        DirectoryContentEntry(bar1_txt_path, /*is_dir=*/false),
        DirectoryContentEntry(bar2_txt_path, /*is_dir=*/false)};
  }
  ~VirtualFileSystem() override = default;

 private:
  std::vector<base::File> OpenFilesForReading(
      const std::vector<base::FilePath>& paths) override {
    std::vector<base::File> files;
    for (const auto& path : paths) {
      auto iter = files_.find(path);
      files.push_back(iter == files_.end() ? base::File()
                                           : std::move(iter->second));
    }
    return files;
  }

  bool DirectoryExists(const base::FilePath& file) override {
    return file_tree_.count(file) == 1 && files_.count(file) == 0;
  }

  std::vector<DirectoryContentEntry> ListDirectoryContent(
      const base::FilePath& dir) override {
    auto iter = file_tree_.find(dir);
    if (iter == file_tree_.end()) {
      NOTREACHED();
      return std::vector<DirectoryContentEntry>();
    }
    return iter->second;
  }

  base::Time GetLastModifiedTime(const base::FilePath& path) override {
    return base::Time::FromDoubleT(172097977);  // Some random date.
  }

  std::map<base::FilePath, std::vector<DirectoryContentEntry>> file_tree_;
  std::map<base::FilePath, base::File> files_;

  DISALLOW_COPY_AND_ASSIGN(VirtualFileSystem);
};

// static
constexpr char VirtualFileSystem::kFooContent[];
constexpr char VirtualFileSystem::kBar1Content[];
constexpr char VirtualFileSystem::kBar2Content[];

// Make the test a PlatformTest to setup autorelease pools properly on Mac.
class ZipTest : public PlatformTest {
 protected:
  enum ValidYearType {
    VALID_YEAR,
    INVALID_YEAR
  };

  virtual void SetUp() {
    PlatformTest::SetUp();

    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    test_dir_ = temp_dir_.GetPath();

    base::FilePath zip_path(test_dir_);
    zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("foo.txt")));
    zip_path = zip_path.Append(FILE_PATH_LITERAL("foo"));
    zip_contents_.insert(zip_path);
    zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("bar.txt")));
    zip_path = zip_path.Append(FILE_PATH_LITERAL("bar"));
    zip_contents_.insert(zip_path);
    zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("baz.txt")));
    zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL("quux.txt")));
    zip_contents_.insert(zip_path.Append(FILE_PATH_LITERAL(".hidden")));

    // Include a subset of files in |zip_file_list_| to test ZipFiles().
    zip_file_list_.push_back(base::FilePath(FILE_PATH_LITERAL("foo.txt")));
    zip_file_list_.push_back(
        base::FilePath(FILE_PATH_LITERAL("foo/bar/quux.txt")));
    zip_file_list_.push_back(
        base::FilePath(FILE_PATH_LITERAL("foo/bar/.hidden")));
  }

  virtual void TearDown() {
    PlatformTest::TearDown();
  }

  bool GetTestDataDirectory(base::FilePath* path) {
#if defined(STARBOARD)
    bool success = base::PathService::Get(base::DIR_TEST_DATA, path);
#else
    bool success = base::PathService::Get(base::DIR_SOURCE_ROOT, path);
#endif
    EXPECT_TRUE(success);
    if (!success)
      return false;
#if defined(STARBOARD)
    *path = path->AppendASCII("zlib");
#else
    *path = path->AppendASCII("third_party");
    *path = path->AppendASCII("zlib");
    *path = path->AppendASCII("google");
    *path = path->AppendASCII("test");
#endif
    *path = path->AppendASCII("data");
    return true;
  }

  void TestUnzipFile(const base::FilePath::StringType& filename,
                     bool expect_hidden_files) {
    base::FilePath test_dir;
    ASSERT_TRUE(GetTestDataDirectory(&test_dir));
    TestUnzipFile(test_dir.Append(filename), expect_hidden_files);
  }

  void TestUnzipFile(const base::FilePath& path, bool expect_hidden_files) {
    ASSERT_TRUE(base::PathExists(path)) << "no file " << path.value();
    ASSERT_TRUE(zip::Unzip(path, test_dir_));

#if defined(STARBOARD)
    VerifyUnzippedContents(expect_hidden_files);
  }
  void VerifyUnzippedContents(bool expect_hidden_files) {
#endif

    base::FilePath original_dir;
    ASSERT_TRUE(GetTestDataDirectory(&original_dir));
    original_dir = original_dir.AppendASCII("test");

    base::FileEnumerator files(test_dir_, true,
        base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
    base::FilePath unzipped_entry_path = files.Next();
    size_t count = 0;
    while (!unzipped_entry_path.value().empty()) {
      EXPECT_EQ(zip_contents_.count(unzipped_entry_path), 1U)
          << "Couldn't find " << unzipped_entry_path.value();
      count++;

      if (base::PathExists(unzipped_entry_path) &&
          !base::DirectoryExists(unzipped_entry_path)) {
        // It's a file, check its contents are what we zipped.
        base::FilePath relative_path;
        bool append_relative_path_success =
            test_dir_.AppendRelativePath(unzipped_entry_path, &relative_path);
        if (!append_relative_path_success) {
          LOG(ERROR) << "Append relative path failed, params: "
                     << test_dir_.value() << " and "
                     << unzipped_entry_path.value();
        }
        base::FilePath original_path = original_dir.Append(relative_path);
        EXPECT_TRUE(base::ContentsEqual(original_path, unzipped_entry_path))
           << "Contents differ between original " << original_path.value()
           << " and unzipped file " << unzipped_entry_path.value();
      }
      unzipped_entry_path = files.Next();
    }

    size_t expected_count = 0;
    for (std::set<base::FilePath>::iterator iter = zip_contents_.begin();
         iter != zip_contents_.end(); ++iter) {
      if (expect_hidden_files || iter->BaseName().value()[0] != '.')
        ++expected_count;
    }

    EXPECT_EQ(expected_count, count);
  }

#if defined(IN_MEMORY_UPDATES)
  void ReadFileToString(const base::FilePath::StringType& filename,
                        std::string* contents) {
    base::FilePath test_dir;
    ASSERT_TRUE(GetTestDataDirectory(&test_dir));
    ASSERT_TRUE(base::ReadFileToString(test_dir.Append(filename), contents));
  }

  void TestUnzipString(const std::string& zip_src, bool expect_hidden_files) {
    ASSERT_TRUE(zip::Unzip(zip_src, test_dir_));

    VerifyUnzippedContents(expect_hidden_files);
  }
#endif

  // This function does the following:
  // 1) Creates a test.txt file with the given last modification timestamp
  // 2) Zips test.txt and extracts it back into a different location.
  // 3) Confirms that test.txt in the output directory has the specified
  //    last modification timestamp if it is valid (|valid_year| is true).
  //    If the timestamp is not supported by the zip format, the last
  //    modification defaults to the current time.
  void TestTimeStamp(const char* date_time, ValidYearType valid_year) {
    SCOPED_TRACE(std::string("TestTimeStamp(") + date_time + ")");
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    base::FilePath zip_file = temp_dir.GetPath().AppendASCII("out.zip");
    base::FilePath src_dir = temp_dir.GetPath().AppendASCII("input");
    base::FilePath out_dir = temp_dir.GetPath().AppendASCII("output");

    base::FilePath src_file = src_dir.AppendASCII("test.txt");
    base::FilePath out_file = out_dir.AppendASCII("test.txt");

    EXPECT_TRUE(base::CreateDirectory(src_dir));
    EXPECT_TRUE(base::CreateDirectory(out_dir));

    base::Time test_mtime;
    ASSERT_TRUE(base::Time::FromString(date_time, &test_mtime));

    // Adjusting the current timestamp to the resolution that the zip file
    // supports, which is 2 seconds. Note that between this call to Time::Now()
    // and zip::Zip() the clock can advance a bit, hence the use of EXPECT_GE.
    base::Time::Exploded now_parts;
    base::Time::Now().LocalExplode(&now_parts);
    now_parts.second = now_parts.second & ~1;
    now_parts.millisecond = 0;
    base::Time now_time;
    EXPECT_TRUE(base::Time::FromLocalExploded(now_parts, &now_time));

    EXPECT_EQ(1, base::WriteFile(src_file, "1", 1));

// No Starboardized implementation of base::TouchFile.
#if !defined(STARBOARD)
    EXPECT_TRUE(base::TouchFile(src_file, base::Time::Now(), test_mtime));
#endif

    EXPECT_TRUE(zip::Zip(src_dir, zip_file, true));
    ASSERT_TRUE(zip::Unzip(zip_file, out_dir));

    base::File::Info file_info;
    EXPECT_TRUE(base::GetFileInfo(out_file, &file_info));
    EXPECT_EQ(file_info.size, 1);

    if (valid_year == VALID_YEAR) {
      EXPECT_EQ(file_info.last_modified, test_mtime);
    } else {
      // Invalid date means the modification time will default to 'now'.
      EXPECT_GE(file_info.last_modified, now_time);
    }
  }

  // The path to temporary directory used to contain the test operations.
  base::FilePath test_dir_;

  base::ScopedTempDir temp_dir_;

  // Hard-coded contents of a known zip file.
  std::set<base::FilePath> zip_contents_;

  // Hard-coded list of relative paths for a zip file created with ZipFiles.
  std::vector<base::FilePath> zip_file_list_;
};

TEST_F(ZipTest, Unzip) {
  TestUnzipFile(FILE_PATH_LITERAL("test.zip"), true);
}

#if defined(IN_MEMORY_UPDATES)
TEST_F(ZipTest, UnzipFromString) {
  std::string zip_str;
  ReadFileToString(FILE_PATH_LITERAL("test.zip"), &zip_str);

  TestUnzipString(zip_str, true);
}
#endif

TEST_F(ZipTest, UnzipUncompressed) {
  TestUnzipFile(FILE_PATH_LITERAL("test_nocompress.zip"), true);
}

#if defined(IN_MEMORY_UPDATES)
TEST_F(ZipTest, UnzipFromStringUncompressed) {
  std::string zip_str;
  ReadFileToString(FILE_PATH_LITERAL("test_nocompress.zip"), &zip_str);

  TestUnzipString(zip_str, true);
}
#endif

TEST_F(ZipTest, UnzipEvil) {
  base::FilePath path;
  ASSERT_TRUE(GetTestDataDirectory(&path));
  path = path.AppendASCII("evil.zip");
  // Unzip the zip file into a sub directory of test_dir_ so evil.zip
  // won't create a persistent file outside test_dir_ in case of a
  // failure.
  base::FilePath output_dir = test_dir_.AppendASCII("out");
  ASSERT_FALSE(zip::Unzip(path, output_dir));
  base::FilePath evil_file = output_dir;
  evil_file = evil_file.AppendASCII(
      "../levilevilevilevilevilevilevilevilevilevilevilevil");
  ASSERT_FALSE(base::PathExists(evil_file));
}

#if defined(IN_MEMORY_UPDATES)
TEST_F(ZipTest, UnzipFromStringEvil) {
  std::string zip_str;
  ReadFileToString(FILE_PATH_LITERAL("evil.zip"), &zip_str);

  // Unzip the zip file into a sub directory of test_dir_ so evil.zip
  // won't create a persistent file outside test_dir_ in case of a
  // failure.
  base::FilePath output_dir = test_dir_.AppendASCII("out");
  ASSERT_FALSE(zip::Unzip(zip_str, output_dir));

  base::FilePath evil_file = output_dir;
  evil_file = evil_file.AppendASCII(
      "../levilevilevilevilevilevilevilevilevilevilevilevil");
  ASSERT_FALSE(base::PathExists(evil_file));
}
#endif

TEST_F(ZipTest, UnzipEvil2) {
  base::FilePath path;
  ASSERT_TRUE(GetTestDataDirectory(&path));
  // The zip file contains an evil file with invalid UTF-8 in its file
  // name.
  path = path.AppendASCII("evil_via_invalid_utf8.zip");
  // See the comment at UnzipEvil() for why we do this.
  base::FilePath output_dir = test_dir_.AppendASCII("out");
  // This should fail as it contains an evil file.
  ASSERT_FALSE(zip::Unzip(path, output_dir));
  base::FilePath evil_file = output_dir;
  evil_file = evil_file.AppendASCII("../evil.txt");
  ASSERT_FALSE(base::PathExists(evil_file));
}

#if defined(IN_MEMORY_UPDATES)
TEST_F(ZipTest, UnzipFromStringEvil2) {
  std::string zip_str;
  // The zip file contains an evil file with invalid UTF-8 in its file
  // name.
  ReadFileToString(FILE_PATH_LITERAL("evil_via_invalid_utf8.zip"), &zip_str);

  // See the comment at UnzipEvil() for why we do this.
  base::FilePath output_dir = test_dir_.AppendASCII("out");
  // This should fail as it contains an evil file.
  ASSERT_FALSE(zip::Unzip(zip_str, output_dir));

  base::FilePath evil_file = output_dir;
  evil_file = evil_file.AppendASCII("../evil.txt");
  ASSERT_FALSE(base::PathExists(evil_file));
}
#endif

TEST_F(ZipTest, UnzipWithFilter) {
  auto filter = base::BindRepeating([](const base::FilePath& path) {
    return path.BaseName().MaybeAsASCII() == "foo.txt";
  });
  base::FilePath path;
  ASSERT_TRUE(GetTestDataDirectory(&path));
  ASSERT_TRUE(zip::UnzipWithFilterCallback(path.AppendASCII("test.zip"),
                                           test_dir_, filter, false));
  // Only foo.txt should have been extracted. The following paths should not
  // be extracted:
  //   foo/
  //   foo/bar.txt
  //   foo/bar/
  //   foo/bar/.hidden
  //   foo/bar/baz.txt
  //   foo/bar/quux.txt
  ASSERT_TRUE(base::PathExists(test_dir_.AppendASCII("foo.txt")));
  base::FileEnumerator extractedFiles(
      test_dir_,
      false,  // Do not enumerate recursively - the file must be in the root.
      base::FileEnumerator::FileType::FILES);
  int extracted_count = 0;
  while (!extractedFiles.Next().empty())
    ++extracted_count;
  ASSERT_EQ(1, extracted_count);

  base::FileEnumerator extractedDirs(
      test_dir_,
      false,  // Do not enumerate recursively - we require zero directories.
      base::FileEnumerator::FileType::DIRECTORIES);
  extracted_count = 0;
  while (!extractedDirs.Next().empty())
    ++extracted_count;
  ASSERT_EQ(0, extracted_count);
}

#if defined(IN_MEMORY_UPDATES)
TEST_F(ZipTest, UnzipFromStringWithFilter) {
  auto filter = base::BindRepeating([](const base::FilePath& path) {
    return path.BaseName().MaybeAsASCII() == "foo.txt";
  });
  std::string zip_str;
  ReadFileToString(FILE_PATH_LITERAL("test.zip"), &zip_str);

  ASSERT_TRUE(zip::UnzipWithFilterCallback(zip_str,
                                           test_dir_, filter, false));

  // Only foo.txt should have been extracted. The following paths should not
  // be extracted:
  //   foo/
  //   foo/bar.txt
  //   foo/bar/
  //   foo/bar/.hidden
  //   foo/bar/baz.txt
  //   foo/bar/quux.txt
  ASSERT_TRUE(base::PathExists(test_dir_.AppendASCII("foo.txt")));
  base::FileEnumerator extractedFiles(
      test_dir_,
      false,  // Do not enumerate recursively - the file must be in the root.
      base::FileEnumerator::FileType::FILES);
  int extracted_count = 0;
  while (!extractedFiles.Next().empty())
    ++extracted_count;
  ASSERT_EQ(1, extracted_count);

  base::FileEnumerator extractedDirs(
      test_dir_,
      false,  // Do not enumerate recursively - we require zero directories.
      base::FileEnumerator::FileType::DIRECTORIES);
  extracted_count = 0;
  while (!extractedDirs.Next().empty())
    ++extracted_count;
  ASSERT_EQ(0, extracted_count);
}
#endif

TEST_F(ZipTest, UnzipWithDelegates) {
  auto filter =
      base::BindRepeating([](const base::FilePath& path) { return true; });
  auto dir_creator = base::BindRepeating(
      [](const base::FilePath& extract_dir, const base::FilePath& entry_path) {
        return base::CreateDirectory(extract_dir.Append(entry_path));
      },
      test_dir_);
  auto writer = base::BindRepeating(
      [](const base::FilePath& extract_dir, const base::FilePath& entry_path)
          -> std::unique_ptr<zip::WriterDelegate> {
        return std::make_unique<zip::FilePathWriterDelegate>(
            extract_dir.Append(entry_path));
      },
      test_dir_);
  base::FilePath path;
  ASSERT_TRUE(GetTestDataDirectory(&path));
#if defined(STARBOARD)
  ASSERT_TRUE(zip::UnzipWithFilterAndWriters(
      path.AppendASCII("test.zip"), writer, dir_creator, filter, false));
#else
  base::File file(path.AppendASCII("test.zip"),
                  base::File::Flags::FLAG_OPEN | base::File::Flags::FLAG_READ);
  ASSERT_TRUE(zip::UnzipWithFilterAndWriters(file.GetPlatformFile(), writer,
                                             dir_creator, filter, false));
#endif
  base::FilePath dir = test_dir_;
  base::FilePath dir_foo = dir.AppendASCII("foo");
  base::FilePath dir_foo_bar = dir_foo.AppendASCII("bar");
  ASSERT_TRUE(base::PathExists(dir.AppendASCII("foo.txt")));
  ASSERT_TRUE(base::PathExists(dir_foo));
  ASSERT_TRUE(base::PathExists(dir_foo.AppendASCII("bar.txt")));
  ASSERT_TRUE(base::PathExists(dir_foo_bar));
  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII(".hidden")));
  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII("baz.txt")));
  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII("quux.txt")));
}

#if defined(IN_MEMORY_UPDATES)
TEST_F(ZipTest, UnzipFromStringWithDelegates) {
  auto filter =
       base::BindRepeating([](const base::FilePath& path) { return true; });
  auto dir_creator = base::BindRepeating(
      [](const base::FilePath& extract_dir, const base::FilePath& entry_path) {
        return base::CreateDirectory(extract_dir.Append(entry_path));
      },
      test_dir_);
  auto writer = base::BindRepeating(
      [](const base::FilePath& extract_dir, const base::FilePath& entry_path)
          -> std::unique_ptr<zip::WriterDelegate> {
        return std::make_unique<zip::FilePathWriterDelegate>(
            extract_dir.Append(entry_path));
      },
      test_dir_);
  std::string zip_str;
  ReadFileToString(FILE_PATH_LITERAL("test.zip"), &zip_str);

  ASSERT_TRUE(zip::UnzipWithFilterAndWriters(
      zip_str, writer, dir_creator, filter, false));

  base::FilePath dir = test_dir_;
  base::FilePath dir_foo = dir.AppendASCII("foo");
  base::FilePath dir_foo_bar = dir_foo.AppendASCII("bar");
  ASSERT_TRUE(base::PathExists(dir.AppendASCII("foo.txt")));
  ASSERT_TRUE(base::PathExists(dir_foo));
  ASSERT_TRUE(base::PathExists(dir_foo.AppendASCII("bar.txt")));
  ASSERT_TRUE(base::PathExists(dir_foo_bar));
  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII(".hidden")));
  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII("baz.txt")));
  ASSERT_TRUE(base::PathExists(dir_foo_bar.AppendASCII("quux.txt")));
}
#endif

TEST_F(ZipTest, Zip) {
  base::FilePath src_dir;
  ASSERT_TRUE(GetTestDataDirectory(&src_dir));
  src_dir = src_dir.AppendASCII("test");

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath zip_file = temp_dir.GetPath().AppendASCII("out.zip");

  EXPECT_TRUE(zip::Zip(src_dir, zip_file, /*include_hidden_files=*/true));
  TestUnzipFile(zip_file, true);
}

TEST_F(ZipTest, ZipIgnoreHidden) {
  base::FilePath src_dir;
  ASSERT_TRUE(GetTestDataDirectory(&src_dir));
  src_dir = src_dir.AppendASCII("test");

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath zip_file = temp_dir.GetPath().AppendASCII("out.zip");

  EXPECT_TRUE(zip::Zip(src_dir, zip_file, /*include_hidden_files=*/false));
  TestUnzipFile(zip_file, false);
}

// No Starboardized implementation of base::CopyDirectory or base::CopyFile.
#if !defined(STARBOARD)
TEST_F(ZipTest, ZipNonASCIIDir) {
  base::FilePath src_dir;
  ASSERT_TRUE(GetTestDataDirectory(&src_dir));
  src_dir = src_dir.AppendASCII("test");

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  // Append 'Тест' (in cyrillic).
  base::FilePath src_dir_russian = temp_dir.GetPath().Append(
      base::FilePath::FromUTF8Unsafe("\xD0\xA2\xD0\xB5\xD1\x81\xD1\x82"));
  base::CopyDirectory(src_dir, src_dir_russian, true);
  base::FilePath zip_file = temp_dir.GetPath().AppendASCII("out_russian.zip");

  EXPECT_TRUE(zip::Zip(src_dir_russian, zip_file, true));
  TestUnzipFile(zip_file, true);
}
#endif

// No Starboardized implementation of base::TouchFile.
#if !defined(STARBOARD)
TEST_F(ZipTest, ZipTimeStamp) {
  // The dates tested are arbitrary, with some constraints. The zip format can
  // only store years from 1980 to 2107 and an even number of seconds, due to it
  // using the ms dos date format.

  // Valid arbitrary date.
  TestTimeStamp("23 Oct 1997 23:22:20", VALID_YEAR);

  // Date before 1980, zip format limitation, must default to unix epoch.
  TestTimeStamp("29 Dec 1979 21:00:10", INVALID_YEAR);

  // Despite the minizip headers telling the maximum year should be 2044, it
  // can actually go up to 2107. Beyond that, the dos date format cannot store
  // the year (2107-1980=127). To test that limit, the input file needs to be
  // touched, but the code that modifies the file access and modification times
  // relies on time_t which is defined as long, therefore being in many
  // platforms just a 4-byte integer, like 32-bit Mac OSX or linux. As such, it
  // suffers from the year-2038 bug. Therefore 2038 is the highest we can test
  // in all platforms reliably.
  TestTimeStamp("02 Jan 2038 23:59:58", VALID_YEAR);
}
#endif

#if defined(OS_POSIX)
TEST_F(ZipTest, ZipFiles) {
  base::FilePath src_dir;
  ASSERT_TRUE(GetTestDataDirectory(&src_dir));
  src_dir = src_dir.AppendASCII("test");

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath zip_name = temp_dir.GetPath().AppendASCII("out.zip");

  base::File zip_file(zip_name,
                      base::File::FLAG_CREATE | base::File::FLAG_WRITE);
  ASSERT_TRUE(zip_file.IsValid());
  EXPECT_TRUE(zip::ZipFiles(src_dir, zip_file_list_,
                            zip_file.GetPlatformFile()));
  zip_file.Close();

  zip::ZipReader reader;
  EXPECT_TRUE(reader.Open(zip_name));
  EXPECT_EQ(zip_file_list_.size(), static_cast<size_t>(reader.num_entries()));
  for (size_t i = 0; i < zip_file_list_.size(); ++i) {
    EXPECT_TRUE(reader.HasMore());
    EXPECT_TRUE(reader.OpenCurrentEntryInZip());
    const zip::ZipReader::EntryInfo* entry_info = reader.current_entry_info();
    EXPECT_EQ(entry_info->file_path(), zip_file_list_[i]);
    reader.AdvanceToNextEntry();
  }
}
#endif  // defined(OS_POSIX)

TEST_F(ZipTest, UnzipFilesWithIncorrectSize) {
  base::FilePath test_data_folder;
  ASSERT_TRUE(GetTestDataDirectory(&test_data_folder));

  // test_mismatch_size.zip contains files with names from 0.txt to 7.txt with
  // sizes from 0 to 7 bytes respectively, but the metadata in the zip file says
  // the uncompressed size is 3 bytes. The ZipReader and minizip code needs to
  // be clever enough to get all the data out.
  base::FilePath test_zip_file =
      test_data_folder.AppendASCII("test_mismatch_size.zip");

  base::ScopedTempDir scoped_temp_dir;
  ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
  const base::FilePath& temp_dir = scoped_temp_dir.GetPath();

  ASSERT_TRUE(zip::Unzip(test_zip_file, temp_dir));
  EXPECT_TRUE(base::DirectoryExists(temp_dir.AppendASCII("d")));

  for (int i = 0; i < 8; i++) {
    SCOPED_TRACE(base::StringPrintf("Processing %d.txt", i));
    base::FilePath file_path = temp_dir.AppendASCII(
        base::StringPrintf("%d.txt", i));
    int64_t file_size = -1;
    EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
    EXPECT_EQ(static_cast<int64_t>(i), file_size);
  }
}

TEST_F(ZipTest, ZipWithFileAccessor) {
  base::FilePath zip_file;
  ASSERT_TRUE(base::CreateTemporaryFile(&zip_file));
  zip::ZipParams params(base::FilePath(FILE_PATH_LITERAL("/test")), zip_file);
  params.set_file_accessor(std::make_unique<VirtualFileSystem>());
  ASSERT_TRUE(zip::Zip(params));

  base::ScopedTempDir scoped_temp_dir;
  ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
  const base::FilePath& temp_dir = scoped_temp_dir.GetPath();
  ASSERT_TRUE(zip::Unzip(zip_file, temp_dir));
  base::FilePath bar_dir = temp_dir.Append(FILE_PATH_LITERAL("bar"));
  EXPECT_TRUE(base::DirectoryExists(bar_dir));
  std::string file_content;
  EXPECT_TRUE(base::ReadFileToString(
      temp_dir.Append(FILE_PATH_LITERAL("foo.txt")), &file_content));
  EXPECT_EQ(VirtualFileSystem::kFooContent, file_content);
  EXPECT_TRUE(base::ReadFileToString(
      bar_dir.Append(FILE_PATH_LITERAL("bar1.txt")), &file_content));
  EXPECT_EQ(VirtualFileSystem::kBar1Content, file_content);
  EXPECT_TRUE(base::ReadFileToString(
      bar_dir.Append(FILE_PATH_LITERAL("bar2.txt")), &file_content));
  EXPECT_EQ(VirtualFileSystem::kBar2Content, file_content);
}

}  // namespace
