11cb0ef41Sopenharmony_ci// Copyright 2011 The Chromium Authors
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "third_party/zlib/google/zip_reader.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <stddef.h>
81cb0ef41Sopenharmony_ci#include <stdint.h>
91cb0ef41Sopenharmony_ci#include <string.h>
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include <iterator>
121cb0ef41Sopenharmony_ci#include <string>
131cb0ef41Sopenharmony_ci#include <vector>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#include "base/check.h"
161cb0ef41Sopenharmony_ci#include "base/files/file.h"
171cb0ef41Sopenharmony_ci#include "base/files/file_path.h"
181cb0ef41Sopenharmony_ci#include "base/files/file_util.h"
191cb0ef41Sopenharmony_ci#include "base/files/scoped_temp_dir.h"
201cb0ef41Sopenharmony_ci#include "base/functional/bind.h"
211cb0ef41Sopenharmony_ci#include "base/hash/md5.h"
221cb0ef41Sopenharmony_ci#include "base/i18n/time_formatting.h"
231cb0ef41Sopenharmony_ci#include "base/path_service.h"
241cb0ef41Sopenharmony_ci#include "base/run_loop.h"
251cb0ef41Sopenharmony_ci#include "base/strings/string_piece.h"
261cb0ef41Sopenharmony_ci#include "base/strings/stringprintf.h"
271cb0ef41Sopenharmony_ci#include "base/strings/utf_string_conversions.h"
281cb0ef41Sopenharmony_ci#include "base/test/bind.h"
291cb0ef41Sopenharmony_ci#include "base/test/task_environment.h"
301cb0ef41Sopenharmony_ci#include "base/time/time.h"
311cb0ef41Sopenharmony_ci#include "build/build_config.h"
321cb0ef41Sopenharmony_ci#include "testing/gmock/include/gmock/gmock.h"
331cb0ef41Sopenharmony_ci#include "testing/gtest/include/gtest/gtest.h"
341cb0ef41Sopenharmony_ci#include "testing/platform_test.h"
351cb0ef41Sopenharmony_ci#include "third_party/icu/source/i18n/unicode/timezone.h"
361cb0ef41Sopenharmony_ci#include "third_party/zlib/google/zip_internal.h"
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciusing ::testing::_;
391cb0ef41Sopenharmony_ciusing ::testing::ElementsAre;
401cb0ef41Sopenharmony_ciusing ::testing::ElementsAreArray;
411cb0ef41Sopenharmony_ciusing ::testing::Return;
421cb0ef41Sopenharmony_ciusing ::testing::SizeIs;
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_cinamespace {
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciconst static std::string kQuuxExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciclass FileWrapper {
491cb0ef41Sopenharmony_ci public:
501cb0ef41Sopenharmony_ci  typedef enum { READ_ONLY, READ_WRITE } AccessMode;
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  FileWrapper(const base::FilePath& path, AccessMode mode) {
531cb0ef41Sopenharmony_ci    int flags = base::File::FLAG_READ;
541cb0ef41Sopenharmony_ci    if (mode == READ_ONLY)
551cb0ef41Sopenharmony_ci      flags |= base::File::FLAG_OPEN;
561cb0ef41Sopenharmony_ci    else
571cb0ef41Sopenharmony_ci      flags |= base::File::FLAG_WRITE | base::File::FLAG_CREATE_ALWAYS;
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci    file_.Initialize(path, flags);
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  ~FileWrapper() {}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  base::PlatformFile platform_file() { return file_.GetPlatformFile(); }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  base::File* file() { return &file_; }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci private:
691cb0ef41Sopenharmony_ci  base::File file_;
701cb0ef41Sopenharmony_ci};
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci// A mock that provides methods that can be used as callbacks in asynchronous
731cb0ef41Sopenharmony_ci// unzip functions.  Tracks the number of calls and number of bytes reported.
741cb0ef41Sopenharmony_ci// Assumes that progress callbacks will be executed in-order.
751cb0ef41Sopenharmony_ciclass MockUnzipListener : public base::SupportsWeakPtr<MockUnzipListener> {
761cb0ef41Sopenharmony_ci public:
771cb0ef41Sopenharmony_ci  MockUnzipListener()
781cb0ef41Sopenharmony_ci      : success_calls_(0),
791cb0ef41Sopenharmony_ci        failure_calls_(0),
801cb0ef41Sopenharmony_ci        progress_calls_(0),
811cb0ef41Sopenharmony_ci        current_progress_(0) {}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  // Success callback for async functions.
841cb0ef41Sopenharmony_ci  void OnUnzipSuccess() { success_calls_++; }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  // Failure callback for async functions.
871cb0ef41Sopenharmony_ci  void OnUnzipFailure() { failure_calls_++; }
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  // Progress callback for async functions.
901cb0ef41Sopenharmony_ci  void OnUnzipProgress(int64_t progress) {
911cb0ef41Sopenharmony_ci    DCHECK(progress > current_progress_);
921cb0ef41Sopenharmony_ci    progress_calls_++;
931cb0ef41Sopenharmony_ci    current_progress_ = progress;
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  int success_calls() { return success_calls_; }
971cb0ef41Sopenharmony_ci  int failure_calls() { return failure_calls_; }
981cb0ef41Sopenharmony_ci  int progress_calls() { return progress_calls_; }
991cb0ef41Sopenharmony_ci  int current_progress() { return current_progress_; }
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci private:
1021cb0ef41Sopenharmony_ci  int success_calls_;
1031cb0ef41Sopenharmony_ci  int failure_calls_;
1041cb0ef41Sopenharmony_ci  int progress_calls_;
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  int64_t current_progress_;
1071cb0ef41Sopenharmony_ci};
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ciclass MockWriterDelegate : public zip::WriterDelegate {
1101cb0ef41Sopenharmony_ci public:
1111cb0ef41Sopenharmony_ci  MOCK_METHOD0(PrepareOutput, bool());
1121cb0ef41Sopenharmony_ci  MOCK_METHOD2(WriteBytes, bool(const char*, int));
1131cb0ef41Sopenharmony_ci  MOCK_METHOD1(SetTimeModified, void(const base::Time&));
1141cb0ef41Sopenharmony_ci  MOCK_METHOD1(SetPosixFilePermissions, void(int));
1151cb0ef41Sopenharmony_ci  MOCK_METHOD0(OnError, void());
1161cb0ef41Sopenharmony_ci};
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_cibool ExtractCurrentEntryToFilePath(zip::ZipReader* reader,
1191cb0ef41Sopenharmony_ci                                   base::FilePath path) {
1201cb0ef41Sopenharmony_ci  zip::FilePathWriterDelegate writer(path);
1211cb0ef41Sopenharmony_ci  return reader->ExtractCurrentEntry(&writer);
1221cb0ef41Sopenharmony_ci}
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ciconst zip::ZipReader::Entry* LocateAndOpenEntry(
1251cb0ef41Sopenharmony_ci    zip::ZipReader* const reader,
1261cb0ef41Sopenharmony_ci    const base::FilePath& path_in_zip) {
1271cb0ef41Sopenharmony_ci  DCHECK(reader);
1281cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader->ok());
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  // The underlying library can do O(1) access, but ZipReader does not expose
1311cb0ef41Sopenharmony_ci  // that. O(N) access is acceptable for these tests.
1321cb0ef41Sopenharmony_ci  while (const zip::ZipReader::Entry* const entry = reader->Next()) {
1331cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader->ok());
1341cb0ef41Sopenharmony_ci    if (entry->path == path_in_zip)
1351cb0ef41Sopenharmony_ci      return entry;
1361cb0ef41Sopenharmony_ci  }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader->ok());
1391cb0ef41Sopenharmony_ci  return nullptr;
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ciusing Paths = std::vector<base::FilePath>;
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci}  // namespace
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_cinamespace zip {
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci// Make the test a PlatformTest to setup autorelease pools properly on Mac.
1491cb0ef41Sopenharmony_ciclass ZipReaderTest : public PlatformTest {
1501cb0ef41Sopenharmony_ci protected:
1511cb0ef41Sopenharmony_ci  void SetUp() override {
1521cb0ef41Sopenharmony_ci    PlatformTest::SetUp();
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1551cb0ef41Sopenharmony_ci    test_dir_ = temp_dir_.GetPath();
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  static base::FilePath GetTestDataDirectory() {
1591cb0ef41Sopenharmony_ci    base::FilePath path;
1601cb0ef41Sopenharmony_ci    CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &path));
1611cb0ef41Sopenharmony_ci    return path.AppendASCII("third_party")
1621cb0ef41Sopenharmony_ci        .AppendASCII("zlib")
1631cb0ef41Sopenharmony_ci        .AppendASCII("google")
1641cb0ef41Sopenharmony_ci        .AppendASCII("test")
1651cb0ef41Sopenharmony_ci        .AppendASCII("data");
1661cb0ef41Sopenharmony_ci  }
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  static Paths GetPaths(const base::FilePath& zip_path,
1691cb0ef41Sopenharmony_ci                        base::StringPiece encoding = {}) {
1701cb0ef41Sopenharmony_ci    Paths paths;
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci    if (ZipReader reader; reader.Open(zip_path)) {
1731cb0ef41Sopenharmony_ci      if (!encoding.empty())
1741cb0ef41Sopenharmony_ci        reader.SetEncoding(std::string(encoding));
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci      while (const ZipReader::Entry* const entry = reader.Next()) {
1771cb0ef41Sopenharmony_ci        EXPECT_TRUE(reader.ok());
1781cb0ef41Sopenharmony_ci        paths.push_back(entry->path);
1791cb0ef41Sopenharmony_ci      }
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci      EXPECT_TRUE(reader.ok());
1821cb0ef41Sopenharmony_ci    }
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci    return paths;
1851cb0ef41Sopenharmony_ci  }
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  // The path to temporary directory used to contain the test operations.
1881cb0ef41Sopenharmony_ci  base::FilePath test_dir_;
1891cb0ef41Sopenharmony_ci  // The path to the test data directory where test.zip etc. are located.
1901cb0ef41Sopenharmony_ci  const base::FilePath data_dir_ = GetTestDataDirectory();
1911cb0ef41Sopenharmony_ci  // The path to test.zip in the test data directory.
1921cb0ef41Sopenharmony_ci  const base::FilePath test_zip_file_ = data_dir_.AppendASCII("test.zip");
1931cb0ef41Sopenharmony_ci  const Paths test_zip_contents_ = {
1941cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo/")),
1951cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo/bar/")),
1961cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo/bar/baz.txt")),
1971cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo/bar/quux.txt")),
1981cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo/bar.txt")),
1991cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo.txt")),
2001cb0ef41Sopenharmony_ci      base::FilePath(FILE_PATH_LITERAL("foo/bar/.hidden")),
2011cb0ef41Sopenharmony_ci  };
2021cb0ef41Sopenharmony_ci  base::ScopedTempDir temp_dir_;
2031cb0ef41Sopenharmony_ci  base::test::TaskEnvironment task_environment_;
2041cb0ef41Sopenharmony_ci};
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Open_ValidZipFile) {
2071cb0ef41Sopenharmony_ci  ZipReader reader;
2081cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.Open(test_zip_file_));
2091cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2101cb0ef41Sopenharmony_ci}
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Open_ValidZipPlatformFile) {
2131cb0ef41Sopenharmony_ci  ZipReader reader;
2141cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2151cb0ef41Sopenharmony_ci  FileWrapper zip_fd_wrapper(test_zip_file_, FileWrapper::READ_ONLY);
2161cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
2171cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2181cb0ef41Sopenharmony_ci}
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Open_NonExistentFile) {
2211cb0ef41Sopenharmony_ci  ZipReader reader;
2221cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2231cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Open(data_dir_.AppendASCII("nonexistent.zip")));
2241cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Open_ExistentButNonZipFile) {
2281cb0ef41Sopenharmony_ci  ZipReader reader;
2291cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2301cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Open(data_dir_.AppendASCII("create_test_zip.sh")));
2311cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2321cb0ef41Sopenharmony_ci}
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Open_EmptyFile) {
2351cb0ef41Sopenharmony_ci  ZipReader reader;
2361cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2371cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Open(data_dir_.AppendASCII("empty.zip")));
2381cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2391cb0ef41Sopenharmony_ci}
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci// Iterate through the contents in the test ZIP archive, and compare that the
2421cb0ef41Sopenharmony_ci// contents collected from the ZipReader matches the expected contents.
2431cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Iteration) {
2441cb0ef41Sopenharmony_ci  Paths actual_contents;
2451cb0ef41Sopenharmony_ci  ZipReader reader;
2461cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ok());
2471cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.Open(test_zip_file_));
2481cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2491cb0ef41Sopenharmony_ci  while (const ZipReader::Entry* const entry = reader.Next()) {
2501cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader.ok());
2511cb0ef41Sopenharmony_ci    actual_contents.push_back(entry->path);
2521cb0ef41Sopenharmony_ci  }
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2551cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Next());  // Shouldn't go further.
2561cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  EXPECT_THAT(actual_contents, SizeIs(reader.num_entries()));
2591cb0ef41Sopenharmony_ci  EXPECT_THAT(actual_contents, ElementsAreArray(test_zip_contents_));
2601cb0ef41Sopenharmony_ci}
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci// Open the test ZIP archive from a file descriptor, iterate through its
2631cb0ef41Sopenharmony_ci// contents, and compare that they match the expected contents.
2641cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, PlatformFileIteration) {
2651cb0ef41Sopenharmony_ci  Paths actual_contents;
2661cb0ef41Sopenharmony_ci  ZipReader reader;
2671cb0ef41Sopenharmony_ci  FileWrapper zip_fd_wrapper(test_zip_file_, FileWrapper::READ_ONLY);
2681cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
2691cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2701cb0ef41Sopenharmony_ci  while (const ZipReader::Entry* const entry = reader.Next()) {
2711cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader.ok());
2721cb0ef41Sopenharmony_ci    actual_contents.push_back(entry->path);
2731cb0ef41Sopenharmony_ci  }
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2761cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Next());  // Shouldn't go further.
2771cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  EXPECT_THAT(actual_contents, SizeIs(reader.num_entries()));
2801cb0ef41Sopenharmony_ci  EXPECT_THAT(actual_contents, ElementsAreArray(test_zip_contents_));
2811cb0ef41Sopenharmony_ci}
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, RegularFile) {
2841cb0ef41Sopenharmony_ci  ZipReader reader;
2851cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
2861cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ci  const ZipReader::Entry* entry = LocateAndOpenEntry(&reader, target_path);
2891cb0ef41Sopenharmony_ci  ASSERT_TRUE(entry);
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci  EXPECT_EQ(target_path, entry->path);
2921cb0ef41Sopenharmony_ci  EXPECT_EQ(13527, entry->original_size);
2931cb0ef41Sopenharmony_ci  EXPECT_EQ("2009-05-29 06:22:20.000",
2941cb0ef41Sopenharmony_ci            base::UnlocalizedTimeFormatWithPattern(entry->last_modified,
2951cb0ef41Sopenharmony_ci                                                   "y-MM-dd HH:mm:ss.SSS",
2961cb0ef41Sopenharmony_ci                                                   icu::TimeZone::getGMT()));
2971cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_unsafe);
2981cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_directory);
2991cb0ef41Sopenharmony_ci}
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, DotDotFile) {
3021cb0ef41Sopenharmony_ci  ZipReader reader;
3031cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("evil.zip")));
3041cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL(
3051cb0ef41Sopenharmony_ci      "UP/levilevilevilevilevilevilevilevilevilevilevilevil"));
3061cb0ef41Sopenharmony_ci  const ZipReader::Entry* entry = LocateAndOpenEntry(&reader, target_path);
3071cb0ef41Sopenharmony_ci  ASSERT_TRUE(entry);
3081cb0ef41Sopenharmony_ci  EXPECT_EQ(target_path, entry->path);
3091cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_unsafe);
3101cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_directory);
3111cb0ef41Sopenharmony_ci}
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, InvalidUTF8File) {
3141cb0ef41Sopenharmony_ci  ZipReader reader;
3151cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("evil_via_invalid_utf8.zip")));
3161cb0ef41Sopenharmony_ci  base::FilePath target_path = base::FilePath::FromUTF8Unsafe(".�.�evil.txt");
3171cb0ef41Sopenharmony_ci  const ZipReader::Entry* entry = LocateAndOpenEntry(&reader, target_path);
3181cb0ef41Sopenharmony_ci  ASSERT_TRUE(entry);
3191cb0ef41Sopenharmony_ci  EXPECT_EQ(target_path, entry->path);
3201cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_unsafe);
3211cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_directory);
3221cb0ef41Sopenharmony_ci}
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci// By default, file paths in ZIPs are interpreted as UTF-8. But in this test,
3251cb0ef41Sopenharmony_ci// the ZIP archive contains file paths that are actually encoded in Shift JIS.
3261cb0ef41Sopenharmony_ci// The SJIS-encoded paths are thus wrongly interpreted as UTF-8, resulting in
3271cb0ef41Sopenharmony_ci// garbled paths. Invalid UTF-8 sequences are safely converted to the
3281cb0ef41Sopenharmony_ci// replacement character �.
3291cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, EncodingSjisAsUtf8) {
3301cb0ef41Sopenharmony_ci  EXPECT_THAT(
3311cb0ef41Sopenharmony_ci      GetPaths(data_dir_.AppendASCII("SJIS Bug 846195.zip")),
3321cb0ef41Sopenharmony_ci      ElementsAre(
3331cb0ef41Sopenharmony_ci          base::FilePath::FromUTF8Unsafe("�V�����t�H���_/SJIS_835C_��.txt"),
3341cb0ef41Sopenharmony_ci          base::FilePath::FromUTF8Unsafe(
3351cb0ef41Sopenharmony_ci              "�V�����t�H���_/�V�����e�L�X�g �h�L�������g.txt")));
3361cb0ef41Sopenharmony_ci}
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci// In this test, SJIS-encoded paths are interpreted as Code Page 1252. This
3391cb0ef41Sopenharmony_ci// results in garbled paths. Note the presence of C1 control codes U+0090 and
3401cb0ef41Sopenharmony_ci// U+0081 in the garbled paths.
3411cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, EncodingSjisAs1252) {
3421cb0ef41Sopenharmony_ci  EXPECT_THAT(
3431cb0ef41Sopenharmony_ci      GetPaths(data_dir_.AppendASCII("SJIS Bug 846195.zip"), "windows-1252"),
3441cb0ef41Sopenharmony_ci      ElementsAre(base::FilePath::FromUTF8Unsafe(
3451cb0ef41Sopenharmony_ci                      "\u0090V‚µ‚¢ƒtƒHƒ‹ƒ_/SJIS_835C_ƒ�.txt"),
3461cb0ef41Sopenharmony_ci                  base::FilePath::FromUTF8Unsafe(
3471cb0ef41Sopenharmony_ci                      "\u0090V‚µ‚¢ƒtƒHƒ‹ƒ_/\u0090V‚µ‚¢ƒeƒLƒXƒg "
3481cb0ef41Sopenharmony_ci                      "ƒhƒLƒ…ƒ\u0081ƒ“ƒg.txt")));
3491cb0ef41Sopenharmony_ci}
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci// In this test, SJIS-encoded paths are interpreted as Code Page 866. This
3521cb0ef41Sopenharmony_ci// results in garbled paths.
3531cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, EncodingSjisAsIbm866) {
3541cb0ef41Sopenharmony_ci  EXPECT_THAT(
3551cb0ef41Sopenharmony_ci      GetPaths(data_dir_.AppendASCII("SJIS Bug 846195.zip"), "IBM866"),
3561cb0ef41Sopenharmony_ci      ElementsAre(
3571cb0ef41Sopenharmony_ci          base::FilePath::FromUTF8Unsafe("РVВ╡ВвГtГHГЛГ_/SJIS_835C_Г�.txt"),
3581cb0ef41Sopenharmony_ci          base::FilePath::FromUTF8Unsafe(
3591cb0ef41Sopenharmony_ci              "РVВ╡ВвГtГHГЛГ_/РVВ╡ВвГeГLГXГg ГhГLГЕГБГУГg.txt")));
3601cb0ef41Sopenharmony_ci}
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci// Tests that SJIS-encoded paths are correctly converted to Unicode.
3631cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, EncodingSjis) {
3641cb0ef41Sopenharmony_ci  EXPECT_THAT(
3651cb0ef41Sopenharmony_ci      GetPaths(data_dir_.AppendASCII("SJIS Bug 846195.zip"), "Shift_JIS"),
3661cb0ef41Sopenharmony_ci      ElementsAre(
3671cb0ef41Sopenharmony_ci          base::FilePath::FromUTF8Unsafe("新しいフォルダ/SJIS_835C_ソ.txt"),
3681cb0ef41Sopenharmony_ci          base::FilePath::FromUTF8Unsafe(
3691cb0ef41Sopenharmony_ci              "新しいフォルダ/新しいテキスト ドキュメント.txt")));
3701cb0ef41Sopenharmony_ci}
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, AbsoluteFile) {
3731cb0ef41Sopenharmony_ci  ZipReader reader;
3741cb0ef41Sopenharmony_ci  ASSERT_TRUE(
3751cb0ef41Sopenharmony_ci      reader.Open(data_dir_.AppendASCII("evil_via_absolute_file_name.zip")));
3761cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("ROOT/evil.txt"));
3771cb0ef41Sopenharmony_ci  const ZipReader::Entry* entry = LocateAndOpenEntry(&reader, target_path);
3781cb0ef41Sopenharmony_ci  ASSERT_TRUE(entry);
3791cb0ef41Sopenharmony_ci  EXPECT_EQ(target_path, entry->path);
3801cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_unsafe);
3811cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_directory);
3821cb0ef41Sopenharmony_ci}
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, Directory) {
3851cb0ef41Sopenharmony_ci  ZipReader reader;
3861cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
3871cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/"));
3881cb0ef41Sopenharmony_ci  const ZipReader::Entry* entry = LocateAndOpenEntry(&reader, target_path);
3891cb0ef41Sopenharmony_ci  ASSERT_TRUE(entry);
3901cb0ef41Sopenharmony_ci  EXPECT_EQ(target_path, entry->path);
3911cb0ef41Sopenharmony_ci  // The directory size should be zero.
3921cb0ef41Sopenharmony_ci  EXPECT_EQ(0, entry->original_size);
3931cb0ef41Sopenharmony_ci  EXPECT_EQ("2009-05-31 15:49:52.000",
3941cb0ef41Sopenharmony_ci            base::UnlocalizedTimeFormatWithPattern(entry->last_modified,
3951cb0ef41Sopenharmony_ci                                                   "y-MM-dd HH:mm:ss.SSS",
3961cb0ef41Sopenharmony_ci                                                   icu::TimeZone::getGMT()));
3971cb0ef41Sopenharmony_ci  EXPECT_FALSE(entry->is_unsafe);
3981cb0ef41Sopenharmony_ci  EXPECT_TRUE(entry->is_directory);
3991cb0ef41Sopenharmony_ci}
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, EncryptedFile_WrongPassword) {
4021cb0ef41Sopenharmony_ci  ZipReader reader;
4031cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("Different Encryptions.zip")));
4041cb0ef41Sopenharmony_ci  reader.SetPassword("wrong password");
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_ci  {
4071cb0ef41Sopenharmony_ci    const ZipReader::Entry* entry = reader.Next();
4081cb0ef41Sopenharmony_ci    ASSERT_TRUE(entry);
4091cb0ef41Sopenharmony_ci    EXPECT_EQ(base::FilePath::FromASCII("ClearText.txt"), entry->path);
4101cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_directory);
4111cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_encrypted);
4121cb0ef41Sopenharmony_ci    std::string contents = "dummy";
4131cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader.ExtractCurrentEntryToString(&contents));
4141cb0ef41Sopenharmony_ci    EXPECT_EQ("This is not encrypted.\n", contents);
4151cb0ef41Sopenharmony_ci  }
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ci  for (const base::StringPiece path : {
4181cb0ef41Sopenharmony_ci           "Encrypted AES-128.txt",
4191cb0ef41Sopenharmony_ci           "Encrypted AES-192.txt",
4201cb0ef41Sopenharmony_ci           "Encrypted AES-256.txt",
4211cb0ef41Sopenharmony_ci           "Encrypted ZipCrypto.txt",
4221cb0ef41Sopenharmony_ci       }) {
4231cb0ef41Sopenharmony_ci    const ZipReader::Entry* entry = reader.Next();
4241cb0ef41Sopenharmony_ci    ASSERT_TRUE(entry);
4251cb0ef41Sopenharmony_ci    EXPECT_EQ(base::FilePath::FromASCII(path), entry->path);
4261cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_directory);
4271cb0ef41Sopenharmony_ci    EXPECT_TRUE(entry->is_encrypted);
4281cb0ef41Sopenharmony_ci    std::string contents = "dummy";
4291cb0ef41Sopenharmony_ci    EXPECT_FALSE(reader.ExtractCurrentEntryToString(&contents));
4301cb0ef41Sopenharmony_ci  }
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Next());
4331cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
4341cb0ef41Sopenharmony_ci}
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, EncryptedFile_RightPassword) {
4371cb0ef41Sopenharmony_ci  ZipReader reader;
4381cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("Different Encryptions.zip")));
4391cb0ef41Sopenharmony_ci  reader.SetPassword("password");
4401cb0ef41Sopenharmony_ci
4411cb0ef41Sopenharmony_ci  {
4421cb0ef41Sopenharmony_ci    const ZipReader::Entry* entry = reader.Next();
4431cb0ef41Sopenharmony_ci    ASSERT_TRUE(entry);
4441cb0ef41Sopenharmony_ci    EXPECT_EQ(base::FilePath::FromASCII("ClearText.txt"), entry->path);
4451cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_directory);
4461cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_encrypted);
4471cb0ef41Sopenharmony_ci    std::string contents = "dummy";
4481cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader.ExtractCurrentEntryToString(&contents));
4491cb0ef41Sopenharmony_ci    EXPECT_EQ("This is not encrypted.\n", contents);
4501cb0ef41Sopenharmony_ci  }
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci  // TODO(crbug.com/1296838) Support AES encryption.
4531cb0ef41Sopenharmony_ci  for (const base::StringPiece path : {
4541cb0ef41Sopenharmony_ci           "Encrypted AES-128.txt",
4551cb0ef41Sopenharmony_ci           "Encrypted AES-192.txt",
4561cb0ef41Sopenharmony_ci           "Encrypted AES-256.txt",
4571cb0ef41Sopenharmony_ci       }) {
4581cb0ef41Sopenharmony_ci    const ZipReader::Entry* entry = reader.Next();
4591cb0ef41Sopenharmony_ci    ASSERT_TRUE(entry);
4601cb0ef41Sopenharmony_ci    EXPECT_EQ(base::FilePath::FromASCII(path), entry->path);
4611cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_directory);
4621cb0ef41Sopenharmony_ci    EXPECT_TRUE(entry->is_encrypted);
4631cb0ef41Sopenharmony_ci    std::string contents = "dummy";
4641cb0ef41Sopenharmony_ci    EXPECT_FALSE(reader.ExtractCurrentEntryToString(&contents));
4651cb0ef41Sopenharmony_ci    EXPECT_EQ("", contents);
4661cb0ef41Sopenharmony_ci  }
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci  {
4691cb0ef41Sopenharmony_ci    const ZipReader::Entry* entry = reader.Next();
4701cb0ef41Sopenharmony_ci    ASSERT_TRUE(entry);
4711cb0ef41Sopenharmony_ci    EXPECT_EQ(base::FilePath::FromASCII("Encrypted ZipCrypto.txt"),
4721cb0ef41Sopenharmony_ci              entry->path);
4731cb0ef41Sopenharmony_ci    EXPECT_FALSE(entry->is_directory);
4741cb0ef41Sopenharmony_ci    EXPECT_TRUE(entry->is_encrypted);
4751cb0ef41Sopenharmony_ci    std::string contents = "dummy";
4761cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader.ExtractCurrentEntryToString(&contents));
4771cb0ef41Sopenharmony_ci    EXPECT_EQ("This is encrypted with ZipCrypto.\n", contents);
4781cb0ef41Sopenharmony_ci  }
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.Next());
4811cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ok());
4821cb0ef41Sopenharmony_ci}
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci// Verifies that the ZipReader class can extract a file from a zip archive
4851cb0ef41Sopenharmony_ci// stored in memory. This test opens a zip archive in a std::string object,
4861cb0ef41Sopenharmony_ci// extracts its content, and verifies the content is the same as the expected
4871cb0ef41Sopenharmony_ci// text.
4881cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, OpenFromString) {
4891cb0ef41Sopenharmony_ci  // A zip archive consisting of one file "test.txt", which is a 16-byte text
4901cb0ef41Sopenharmony_ci  // file that contains "This is a test.\n".
4911cb0ef41Sopenharmony_ci  const char kTestData[] =
4921cb0ef41Sopenharmony_ci      "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\xa4\x66\x24\x41\x13\xe8"
4931cb0ef41Sopenharmony_ci      "\xcb\x27\x10\x00\x00\x00\x10\x00\x00\x00\x08\x00\x1c\x00\x74\x65"
4941cb0ef41Sopenharmony_ci      "\x73\x74\x2e\x74\x78\x74\x55\x54\x09\x00\x03\x34\x89\x45\x50\x34"
4951cb0ef41Sopenharmony_ci      "\x89\x45\x50\x75\x78\x0b\x00\x01\x04\x8e\xf0\x00\x00\x04\x88\x13"
4961cb0ef41Sopenharmony_ci      "\x00\x00\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74"
4971cb0ef41Sopenharmony_ci      "\x2e\x0a\x50\x4b\x01\x02\x1e\x03\x0a\x00\x00\x00\x00\x00\xa4\x66"
4981cb0ef41Sopenharmony_ci      "\x24\x41\x13\xe8\xcb\x27\x10\x00\x00\x00\x10\x00\x00\x00\x08\x00"
4991cb0ef41Sopenharmony_ci      "\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\xa4\x81\x00\x00\x00\x00"
5001cb0ef41Sopenharmony_ci      "\x74\x65\x73\x74\x2e\x74\x78\x74\x55\x54\x05\x00\x03\x34\x89\x45"
5011cb0ef41Sopenharmony_ci      "\x50\x75\x78\x0b\x00\x01\x04\x8e\xf0\x00\x00\x04\x88\x13\x00\x00"
5021cb0ef41Sopenharmony_ci      "\x50\x4b\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00\x4e\x00\x00\x00"
5031cb0ef41Sopenharmony_ci      "\x52\x00\x00\x00\x00\x00";
5041cb0ef41Sopenharmony_ci  std::string data(kTestData, std::size(kTestData));
5051cb0ef41Sopenharmony_ci  ZipReader reader;
5061cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.OpenFromString(data));
5071cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("test.txt"));
5081cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
5091cb0ef41Sopenharmony_ci  ASSERT_TRUE(ExtractCurrentEntryToFilePath(&reader,
5101cb0ef41Sopenharmony_ci                                            test_dir_.AppendASCII("test.txt")));
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci  std::string actual;
5131cb0ef41Sopenharmony_ci  ASSERT_TRUE(
5141cb0ef41Sopenharmony_ci      base::ReadFileToString(test_dir_.AppendASCII("test.txt"), &actual));
5151cb0ef41Sopenharmony_ci  EXPECT_EQ(std::string("This is a test.\n"), actual);
5161cb0ef41Sopenharmony_ci}
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci// Verifies that the asynchronous extraction to a file works.
5191cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractToFileAsync_RegularFile) {
5201cb0ef41Sopenharmony_ci  MockUnzipListener listener;
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci  ZipReader reader;
5231cb0ef41Sopenharmony_ci  base::FilePath target_file = test_dir_.AppendASCII("quux.txt");
5241cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
5251cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
5261cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
5271cb0ef41Sopenharmony_ci  reader.ExtractCurrentEntryToFilePathAsync(
5281cb0ef41Sopenharmony_ci      target_file,
5291cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipSuccess, listener.AsWeakPtr()),
5301cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipFailure, listener.AsWeakPtr()),
5311cb0ef41Sopenharmony_ci      base::BindRepeating(&MockUnzipListener::OnUnzipProgress,
5321cb0ef41Sopenharmony_ci                          listener.AsWeakPtr()));
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
5351cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
5361cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.progress_calls());
5371cb0ef41Sopenharmony_ci
5381cb0ef41Sopenharmony_ci  base::RunLoop().RunUntilIdle();
5391cb0ef41Sopenharmony_ci
5401cb0ef41Sopenharmony_ci  EXPECT_EQ(1, listener.success_calls());
5411cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
5421cb0ef41Sopenharmony_ci  EXPECT_LE(1, listener.progress_calls());
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_ci  std::string output;
5451cb0ef41Sopenharmony_ci  ASSERT_TRUE(
5461cb0ef41Sopenharmony_ci      base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), &output));
5471cb0ef41Sopenharmony_ci  const std::string md5 = base::MD5String(output);
5481cb0ef41Sopenharmony_ci  EXPECT_EQ(kQuuxExpectedMD5, md5);
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci  int64_t file_size = 0;
5511cb0ef41Sopenharmony_ci  ASSERT_TRUE(base::GetFileSize(target_file, &file_size));
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  EXPECT_EQ(file_size, listener.current_progress());
5541cb0ef41Sopenharmony_ci}
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractToFileAsync_Encrypted_NoPassword) {
5571cb0ef41Sopenharmony_ci  MockUnzipListener listener;
5581cb0ef41Sopenharmony_ci
5591cb0ef41Sopenharmony_ci  ZipReader reader;
5601cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("Different Encryptions.zip")));
5611cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(
5621cb0ef41Sopenharmony_ci      &reader, base::FilePath::FromASCII("Encrypted ZipCrypto.txt")));
5631cb0ef41Sopenharmony_ci  const base::FilePath target_path = test_dir_.AppendASCII("extracted");
5641cb0ef41Sopenharmony_ci  reader.ExtractCurrentEntryToFilePathAsync(
5651cb0ef41Sopenharmony_ci      target_path,
5661cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipSuccess, listener.AsWeakPtr()),
5671cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipFailure, listener.AsWeakPtr()),
5681cb0ef41Sopenharmony_ci      base::BindRepeating(&MockUnzipListener::OnUnzipProgress,
5691cb0ef41Sopenharmony_ci                          listener.AsWeakPtr()));
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
5721cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
5731cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.progress_calls());
5741cb0ef41Sopenharmony_ci
5751cb0ef41Sopenharmony_ci  base::RunLoop().RunUntilIdle();
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
5781cb0ef41Sopenharmony_ci  EXPECT_EQ(1, listener.failure_calls());
5791cb0ef41Sopenharmony_ci  EXPECT_LE(1, listener.progress_calls());
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci  // The extracted file contains rubbish data.
5821cb0ef41Sopenharmony_ci  // We probably shouldn't even look at it.
5831cb0ef41Sopenharmony_ci  std::string contents;
5841cb0ef41Sopenharmony_ci  ASSERT_TRUE(base::ReadFileToString(target_path, &contents));
5851cb0ef41Sopenharmony_ci  EXPECT_NE("", contents);
5861cb0ef41Sopenharmony_ci  EXPECT_EQ(contents.size(), listener.current_progress());
5871cb0ef41Sopenharmony_ci}
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractToFileAsync_Encrypted_RightPassword) {
5901cb0ef41Sopenharmony_ci  MockUnzipListener listener;
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci  ZipReader reader;
5931cb0ef41Sopenharmony_ci  reader.SetPassword("password");
5941cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("Different Encryptions.zip")));
5951cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(
5961cb0ef41Sopenharmony_ci      &reader, base::FilePath::FromASCII("Encrypted ZipCrypto.txt")));
5971cb0ef41Sopenharmony_ci  const base::FilePath target_path = test_dir_.AppendASCII("extracted");
5981cb0ef41Sopenharmony_ci  reader.ExtractCurrentEntryToFilePathAsync(
5991cb0ef41Sopenharmony_ci      target_path,
6001cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipSuccess, listener.AsWeakPtr()),
6011cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipFailure, listener.AsWeakPtr()),
6021cb0ef41Sopenharmony_ci      base::BindRepeating(&MockUnzipListener::OnUnzipProgress,
6031cb0ef41Sopenharmony_ci                          listener.AsWeakPtr()));
6041cb0ef41Sopenharmony_ci
6051cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
6061cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
6071cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.progress_calls());
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_ci  base::RunLoop().RunUntilIdle();
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ci  EXPECT_EQ(1, listener.success_calls());
6121cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
6131cb0ef41Sopenharmony_ci  EXPECT_LE(1, listener.progress_calls());
6141cb0ef41Sopenharmony_ci
6151cb0ef41Sopenharmony_ci  std::string contents;
6161cb0ef41Sopenharmony_ci  ASSERT_TRUE(base::ReadFileToString(target_path, &contents));
6171cb0ef41Sopenharmony_ci  EXPECT_EQ("This is encrypted with ZipCrypto.\n", contents);
6181cb0ef41Sopenharmony_ci  EXPECT_EQ(contents.size(), listener.current_progress());
6191cb0ef41Sopenharmony_ci}
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractToFileAsync_WrongCrc) {
6221cb0ef41Sopenharmony_ci  MockUnzipListener listener;
6231cb0ef41Sopenharmony_ci
6241cb0ef41Sopenharmony_ci  ZipReader reader;
6251cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("Wrong CRC.zip")));
6261cb0ef41Sopenharmony_ci  ASSERT_TRUE(
6271cb0ef41Sopenharmony_ci      LocateAndOpenEntry(&reader, base::FilePath::FromASCII("Corrupted.txt")));
6281cb0ef41Sopenharmony_ci  const base::FilePath target_path = test_dir_.AppendASCII("extracted");
6291cb0ef41Sopenharmony_ci  reader.ExtractCurrentEntryToFilePathAsync(
6301cb0ef41Sopenharmony_ci      target_path,
6311cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipSuccess, listener.AsWeakPtr()),
6321cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipFailure, listener.AsWeakPtr()),
6331cb0ef41Sopenharmony_ci      base::BindRepeating(&MockUnzipListener::OnUnzipProgress,
6341cb0ef41Sopenharmony_ci                          listener.AsWeakPtr()));
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
6371cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
6381cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.progress_calls());
6391cb0ef41Sopenharmony_ci
6401cb0ef41Sopenharmony_ci  base::RunLoop().RunUntilIdle();
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
6431cb0ef41Sopenharmony_ci  EXPECT_EQ(1, listener.failure_calls());
6441cb0ef41Sopenharmony_ci  EXPECT_LE(1, listener.progress_calls());
6451cb0ef41Sopenharmony_ci
6461cb0ef41Sopenharmony_ci  std::string contents;
6471cb0ef41Sopenharmony_ci  ASSERT_TRUE(base::ReadFileToString(target_path, &contents));
6481cb0ef41Sopenharmony_ci  EXPECT_EQ("This file has been changed after its CRC was computed.\n",
6491cb0ef41Sopenharmony_ci            contents);
6501cb0ef41Sopenharmony_ci  EXPECT_EQ(contents.size(), listener.current_progress());
6511cb0ef41Sopenharmony_ci}
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci// Verifies that the asynchronous extraction to a file works.
6541cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractToFileAsync_Directory) {
6551cb0ef41Sopenharmony_ci  MockUnzipListener listener;
6561cb0ef41Sopenharmony_ci
6571cb0ef41Sopenharmony_ci  ZipReader reader;
6581cb0ef41Sopenharmony_ci  base::FilePath target_file = test_dir_.AppendASCII("foo");
6591cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/"));
6601cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
6611cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
6621cb0ef41Sopenharmony_ci  reader.ExtractCurrentEntryToFilePathAsync(
6631cb0ef41Sopenharmony_ci      target_file,
6641cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipSuccess, listener.AsWeakPtr()),
6651cb0ef41Sopenharmony_ci      base::BindOnce(&MockUnzipListener::OnUnzipFailure, listener.AsWeakPtr()),
6661cb0ef41Sopenharmony_ci      base::BindRepeating(&MockUnzipListener::OnUnzipProgress,
6671cb0ef41Sopenharmony_ci                          listener.AsWeakPtr()));
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.success_calls());
6701cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
6711cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.progress_calls());
6721cb0ef41Sopenharmony_ci
6731cb0ef41Sopenharmony_ci  base::RunLoop().RunUntilIdle();
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci  EXPECT_EQ(1, listener.success_calls());
6761cb0ef41Sopenharmony_ci  EXPECT_EQ(0, listener.failure_calls());
6771cb0ef41Sopenharmony_ci  EXPECT_GE(0, listener.progress_calls());
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci  ASSERT_TRUE(base::DirectoryExists(target_file));
6801cb0ef41Sopenharmony_ci}
6811cb0ef41Sopenharmony_ci
6821cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractCurrentEntryToString) {
6831cb0ef41Sopenharmony_ci  // test_mismatch_size.zip contains files with names from 0.txt to 7.txt with
6841cb0ef41Sopenharmony_ci  // sizes from 0 to 7 bytes respectively, being the contents of each file a
6851cb0ef41Sopenharmony_ci  // substring of "0123456" starting at '0'.
6861cb0ef41Sopenharmony_ci  base::FilePath test_zip_file =
6871cb0ef41Sopenharmony_ci      data_dir_.AppendASCII("test_mismatch_size.zip");
6881cb0ef41Sopenharmony_ci
6891cb0ef41Sopenharmony_ci  ZipReader reader;
6901cb0ef41Sopenharmony_ci  std::string contents;
6911cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file));
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_ci  for (size_t i = 0; i < 8; i++) {
6941cb0ef41Sopenharmony_ci    SCOPED_TRACE(base::StringPrintf("Processing %d.txt", static_cast<int>(i)));
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_ci    base::FilePath file_name = base::FilePath::FromUTF8Unsafe(
6971cb0ef41Sopenharmony_ci        base::StringPrintf("%d.txt", static_cast<int>(i)));
6981cb0ef41Sopenharmony_ci    ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name));
6991cb0ef41Sopenharmony_ci
7001cb0ef41Sopenharmony_ci    if (i > 1) {
7011cb0ef41Sopenharmony_ci      // Off by one byte read limit: must fail.
7021cb0ef41Sopenharmony_ci      EXPECT_FALSE(reader.ExtractCurrentEntryToString(i - 1, &contents));
7031cb0ef41Sopenharmony_ci    }
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ci    if (i > 0) {
7061cb0ef41Sopenharmony_ci      // Exact byte read limit: must pass.
7071cb0ef41Sopenharmony_ci      EXPECT_TRUE(reader.ExtractCurrentEntryToString(i, &contents));
7081cb0ef41Sopenharmony_ci      EXPECT_EQ(std::string(base::StringPiece("0123456", i)), contents);
7091cb0ef41Sopenharmony_ci    }
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ci    // More than necessary byte read limit: must pass.
7121cb0ef41Sopenharmony_ci    EXPECT_TRUE(reader.ExtractCurrentEntryToString(&contents));
7131cb0ef41Sopenharmony_ci    EXPECT_EQ(std::string(base::StringPiece("0123456", i)), contents);
7141cb0ef41Sopenharmony_ci  }
7151cb0ef41Sopenharmony_ci  reader.Close();
7161cb0ef41Sopenharmony_ci}
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractPartOfCurrentEntry) {
7191cb0ef41Sopenharmony_ci  // test_mismatch_size.zip contains files with names from 0.txt to 7.txt with
7201cb0ef41Sopenharmony_ci  // sizes from 0 to 7 bytes respectively, being the contents of each file a
7211cb0ef41Sopenharmony_ci  // substring of "0123456" starting at '0'.
7221cb0ef41Sopenharmony_ci  base::FilePath test_zip_file =
7231cb0ef41Sopenharmony_ci      data_dir_.AppendASCII("test_mismatch_size.zip");
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_ci  ZipReader reader;
7261cb0ef41Sopenharmony_ci  std::string contents;
7271cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file));
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci  base::FilePath file_name0 = base::FilePath::FromUTF8Unsafe("0.txt");
7301cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name0));
7311cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(0, &contents));
7321cb0ef41Sopenharmony_ci  EXPECT_EQ("", contents);
7331cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(1, &contents));
7341cb0ef41Sopenharmony_ci  EXPECT_EQ("", contents);
7351cb0ef41Sopenharmony_ci
7361cb0ef41Sopenharmony_ci  base::FilePath file_name1 = base::FilePath::FromUTF8Unsafe("1.txt");
7371cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name1));
7381cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(0, &contents));
7391cb0ef41Sopenharmony_ci  EXPECT_EQ("", contents);
7401cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(1, &contents));
7411cb0ef41Sopenharmony_ci  EXPECT_EQ("0", contents);
7421cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(2, &contents));
7431cb0ef41Sopenharmony_ci  EXPECT_EQ("0", contents);
7441cb0ef41Sopenharmony_ci
7451cb0ef41Sopenharmony_ci  base::FilePath file_name4 = base::FilePath::FromUTF8Unsafe("4.txt");
7461cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, file_name4));
7471cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(0, &contents));
7481cb0ef41Sopenharmony_ci  EXPECT_EQ("", contents);
7491cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ExtractCurrentEntryToString(2, &contents));
7501cb0ef41Sopenharmony_ci  EXPECT_EQ("01", contents);
7511cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(4, &contents));
7521cb0ef41Sopenharmony_ci  EXPECT_EQ("0123", contents);
7531cb0ef41Sopenharmony_ci  // Checks that entire file is extracted and function returns true when
7541cb0ef41Sopenharmony_ci  // |max_read_bytes| is larger than file size.
7551cb0ef41Sopenharmony_ci  EXPECT_TRUE(reader.ExtractCurrentEntryToString(5, &contents));
7561cb0ef41Sopenharmony_ci  EXPECT_EQ("0123", contents);
7571cb0ef41Sopenharmony_ci
7581cb0ef41Sopenharmony_ci  reader.Close();
7591cb0ef41Sopenharmony_ci}
7601cb0ef41Sopenharmony_ci
7611cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractPosixPermissions) {
7621cb0ef41Sopenharmony_ci  base::ScopedTempDir temp_dir;
7631cb0ef41Sopenharmony_ci  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci  ZipReader reader;
7661cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("test_posix_permissions.zip")));
7671cb0ef41Sopenharmony_ci  for (auto entry : {"0.txt", "1.txt", "2.txt", "3.txt"}) {
7681cb0ef41Sopenharmony_ci    ASSERT_TRUE(LocateAndOpenEntry(&reader, base::FilePath::FromASCII(entry)));
7691cb0ef41Sopenharmony_ci    FilePathWriterDelegate delegate(temp_dir.GetPath().AppendASCII(entry));
7701cb0ef41Sopenharmony_ci    ASSERT_TRUE(reader.ExtractCurrentEntry(&delegate));
7711cb0ef41Sopenharmony_ci  }
7721cb0ef41Sopenharmony_ci  reader.Close();
7731cb0ef41Sopenharmony_ci
7741cb0ef41Sopenharmony_ci#if defined(OS_POSIX)
7751cb0ef41Sopenharmony_ci  // This assumes a umask of at least 0400.
7761cb0ef41Sopenharmony_ci  int mode = 0;
7771cb0ef41Sopenharmony_ci  EXPECT_TRUE(base::GetPosixFilePermissions(
7781cb0ef41Sopenharmony_ci      temp_dir.GetPath().AppendASCII("0.txt"), &mode));
7791cb0ef41Sopenharmony_ci  EXPECT_EQ(mode & 0700, 0700);
7801cb0ef41Sopenharmony_ci  EXPECT_TRUE(base::GetPosixFilePermissions(
7811cb0ef41Sopenharmony_ci      temp_dir.GetPath().AppendASCII("1.txt"), &mode));
7821cb0ef41Sopenharmony_ci  EXPECT_EQ(mode & 0700, 0600);
7831cb0ef41Sopenharmony_ci  EXPECT_TRUE(base::GetPosixFilePermissions(
7841cb0ef41Sopenharmony_ci      temp_dir.GetPath().AppendASCII("2.txt"), &mode));
7851cb0ef41Sopenharmony_ci  EXPECT_EQ(mode & 0700, 0700);
7861cb0ef41Sopenharmony_ci  EXPECT_TRUE(base::GetPosixFilePermissions(
7871cb0ef41Sopenharmony_ci      temp_dir.GetPath().AppendASCII("3.txt"), &mode));
7881cb0ef41Sopenharmony_ci  EXPECT_EQ(mode & 0700, 0600);
7891cb0ef41Sopenharmony_ci#endif
7901cb0ef41Sopenharmony_ci}
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_ci// This test exposes http://crbug.com/430959, at least on OS X
7931cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, DISABLED_LeakDetectionTest) {
7941cb0ef41Sopenharmony_ci  for (int i = 0; i < 100000; ++i) {
7951cb0ef41Sopenharmony_ci    FileWrapper zip_fd_wrapper(test_zip_file_, FileWrapper::READ_ONLY);
7961cb0ef41Sopenharmony_ci    ZipReader reader;
7971cb0ef41Sopenharmony_ci    ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
7981cb0ef41Sopenharmony_ci  }
7991cb0ef41Sopenharmony_ci}
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci// Test that when WriterDelegate::PrepareMock returns false, no other methods on
8021cb0ef41Sopenharmony_ci// the delegate are called and the extraction fails.
8031cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractCurrentEntryPrepareFailure) {
8041cb0ef41Sopenharmony_ci  testing::StrictMock<MockWriterDelegate> mock_writer;
8051cb0ef41Sopenharmony_ci
8061cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(false));
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
8091cb0ef41Sopenharmony_ci  ZipReader reader;
8101cb0ef41Sopenharmony_ci
8111cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
8121cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
8131cb0ef41Sopenharmony_ci  ASSERT_FALSE(reader.ExtractCurrentEntry(&mock_writer));
8141cb0ef41Sopenharmony_ci}
8151cb0ef41Sopenharmony_ci
8161cb0ef41Sopenharmony_ci// Test that when WriterDelegate::WriteBytes returns false, only the OnError
8171cb0ef41Sopenharmony_ci// method on the delegate is called and the extraction fails.
8181cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractCurrentEntryWriteBytesFailure) {
8191cb0ef41Sopenharmony_ci  testing::StrictMock<MockWriterDelegate> mock_writer;
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(true));
8221cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, WriteBytes(_, _)).WillOnce(Return(false));
8231cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, OnError());
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
8261cb0ef41Sopenharmony_ci  ZipReader reader;
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
8291cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
8301cb0ef41Sopenharmony_ci  ASSERT_FALSE(reader.ExtractCurrentEntry(&mock_writer));
8311cb0ef41Sopenharmony_ci}
8321cb0ef41Sopenharmony_ci
8331cb0ef41Sopenharmony_ci// Test that extraction succeeds when the writer delegate reports all is well.
8341cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, ExtractCurrentEntrySuccess) {
8351cb0ef41Sopenharmony_ci  testing::StrictMock<MockWriterDelegate> mock_writer;
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(true));
8381cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, WriteBytes(_, _)).WillRepeatedly(Return(true));
8391cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, SetPosixFilePermissions(_));
8401cb0ef41Sopenharmony_ci  EXPECT_CALL(mock_writer, SetTimeModified(_));
8411cb0ef41Sopenharmony_ci
8421cb0ef41Sopenharmony_ci  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
8431cb0ef41Sopenharmony_ci  ZipReader reader;
8441cb0ef41Sopenharmony_ci
8451cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(test_zip_file_));
8461cb0ef41Sopenharmony_ci  ASSERT_TRUE(LocateAndOpenEntry(&reader, target_path));
8471cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.ExtractCurrentEntry(&mock_writer));
8481cb0ef41Sopenharmony_ci}
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ciTEST_F(ZipReaderTest, WrongCrc) {
8511cb0ef41Sopenharmony_ci  ZipReader reader;
8521cb0ef41Sopenharmony_ci  ASSERT_TRUE(reader.Open(data_dir_.AppendASCII("Wrong CRC.zip")));
8531cb0ef41Sopenharmony_ci
8541cb0ef41Sopenharmony_ci  const ZipReader::Entry* const entry =
8551cb0ef41Sopenharmony_ci      LocateAndOpenEntry(&reader, base::FilePath::FromASCII("Corrupted.txt"));
8561cb0ef41Sopenharmony_ci  ASSERT_TRUE(entry);
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci  std::string contents = "dummy";
8591cb0ef41Sopenharmony_ci  EXPECT_FALSE(reader.ExtractCurrentEntryToString(&contents));
8601cb0ef41Sopenharmony_ci  EXPECT_EQ("This file has been changed after its CRC was computed.\n",
8611cb0ef41Sopenharmony_ci            contents);
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ci  contents = "dummy";
8641cb0ef41Sopenharmony_ci  EXPECT_FALSE(
8651cb0ef41Sopenharmony_ci      reader.ExtractCurrentEntryToString(entry->original_size + 1, &contents));
8661cb0ef41Sopenharmony_ci  EXPECT_EQ("This file has been changed after its CRC was computed.\n",
8671cb0ef41Sopenharmony_ci            contents);
8681cb0ef41Sopenharmony_ci
8691cb0ef41Sopenharmony_ci  contents = "dummy";
8701cb0ef41Sopenharmony_ci  EXPECT_FALSE(
8711cb0ef41Sopenharmony_ci      reader.ExtractCurrentEntryToString(entry->original_size, &contents));
8721cb0ef41Sopenharmony_ci  EXPECT_EQ("This file has been changed after its CRC was computed.\n",
8731cb0ef41Sopenharmony_ci            contents);
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ci  contents = "dummy";
8761cb0ef41Sopenharmony_ci  EXPECT_FALSE(
8771cb0ef41Sopenharmony_ci      reader.ExtractCurrentEntryToString(entry->original_size - 1, &contents));
8781cb0ef41Sopenharmony_ci  EXPECT_EQ("This file has been changed after its CRC was computed.", contents);
8791cb0ef41Sopenharmony_ci}
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ciclass FileWriterDelegateTest : public ::testing::Test {
8821cb0ef41Sopenharmony_ci protected:
8831cb0ef41Sopenharmony_ci  void SetUp() override {
8841cb0ef41Sopenharmony_ci    ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path_));
8851cb0ef41Sopenharmony_ci    file_.Initialize(temp_file_path_,
8861cb0ef41Sopenharmony_ci                     (base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ |
8871cb0ef41Sopenharmony_ci                      base::File::FLAG_WRITE | base::File::FLAG_WIN_TEMPORARY |
8881cb0ef41Sopenharmony_ci                      base::File::FLAG_DELETE_ON_CLOSE));
8891cb0ef41Sopenharmony_ci    ASSERT_TRUE(file_.IsValid());
8901cb0ef41Sopenharmony_ci  }
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci  base::FilePath temp_file_path_;
8931cb0ef41Sopenharmony_ci  base::File file_;
8941cb0ef41Sopenharmony_ci};
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ciTEST_F(FileWriterDelegateTest, WriteToEnd) {
8971cb0ef41Sopenharmony_ci  const std::string payload = "This is the actualy payload data.\n";
8981cb0ef41Sopenharmony_ci
8991cb0ef41Sopenharmony_ci  {
9001cb0ef41Sopenharmony_ci    FileWriterDelegate writer(&file_);
9011cb0ef41Sopenharmony_ci    EXPECT_EQ(0, writer.file_length());
9021cb0ef41Sopenharmony_ci    ASSERT_TRUE(writer.PrepareOutput());
9031cb0ef41Sopenharmony_ci    ASSERT_TRUE(writer.WriteBytes(payload.data(), payload.size()));
9041cb0ef41Sopenharmony_ci    EXPECT_EQ(payload.size(), writer.file_length());
9051cb0ef41Sopenharmony_ci  }
9061cb0ef41Sopenharmony_ci
9071cb0ef41Sopenharmony_ci  EXPECT_EQ(payload.size(), file_.GetLength());
9081cb0ef41Sopenharmony_ci}
9091cb0ef41Sopenharmony_ci
9101cb0ef41Sopenharmony_ciTEST_F(FileWriterDelegateTest, EmptyOnError) {
9111cb0ef41Sopenharmony_ci  const std::string payload = "This is the actualy payload data.\n";
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci  {
9141cb0ef41Sopenharmony_ci    FileWriterDelegate writer(&file_);
9151cb0ef41Sopenharmony_ci    EXPECT_EQ(0, writer.file_length());
9161cb0ef41Sopenharmony_ci    ASSERT_TRUE(writer.PrepareOutput());
9171cb0ef41Sopenharmony_ci    ASSERT_TRUE(writer.WriteBytes(payload.data(), payload.size()));
9181cb0ef41Sopenharmony_ci    EXPECT_EQ(payload.size(), writer.file_length());
9191cb0ef41Sopenharmony_ci    EXPECT_EQ(payload.size(), file_.GetLength());
9201cb0ef41Sopenharmony_ci    writer.OnError();
9211cb0ef41Sopenharmony_ci    EXPECT_EQ(0, writer.file_length());
9221cb0ef41Sopenharmony_ci  }
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ci  EXPECT_EQ(0, file_.GetLength());
9251cb0ef41Sopenharmony_ci}
9261cb0ef41Sopenharmony_ci
9271cb0ef41Sopenharmony_ci}  // namespace zip
928