15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/zlib/google/zip_reader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/md5.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/platform_file.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/zlib/google/zip_internal.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Wrap PlatformFiles in a class so that we don't leak them in tests.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PlatformFileWrapper {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef enum {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    READ_ONLY,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    READ_WRITE
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } AccessMode;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformFileWrapper(const base::FilePath& file, AccessMode mode)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : file_(base::kInvalidPlatformFileValue) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (mode) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case READ_ONLY:
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        file_ = base::CreatePlatformFile(file,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::PLATFORM_FILE_OPEN |
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::PLATFORM_FILE_READ,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         NULL, NULL);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case READ_WRITE:
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        file_ = base::CreatePlatformFile(file,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::PLATFORM_FILE_CREATE_ALWAYS |
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::PLATFORM_FILE_READ |
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::PLATFORM_FILE_WRITE,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         NULL, NULL);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~PlatformFileWrapper() {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ClosePlatformFile(file_);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::PlatformFile platform_file() { return file_; }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::PlatformFile file_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}   // namespace
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace zip {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make the test a PlatformTest to setup autorelease pools properly on Mac.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ZipReaderTest : public PlatformTest {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::SetUp();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_dir_ = temp_dir_.path();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(GetTestDataDirectory(&test_data_dir_));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_zip_file_ = test_data_dir_.AppendASCII("test.zip");
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    evil_zip_file_ = test_data_dir_.AppendASCII("evil.zip");
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    evil_via_invalid_utf8_zip_file_ = test_data_dir_.AppendASCII(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "evil_via_invalid_utf8.zip");
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    evil_via_absolute_file_name_zip_file_ = test_data_dir_.AppendASCII(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "evil_via_absolute_file_name.zip");
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(base::FilePath(FILE_PATH_LITERAL("foo/")));
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(base::FilePath(FILE_PATH_LITERAL("foo/bar/")));
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("foo/bar/baz.txt")));
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("foo/bar/quux.txt")));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("foo/bar.txt")));
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(base::FilePath(FILE_PATH_LITERAL("foo.txt")));
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_zip_contents_.insert(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("foo/bar/.hidden")));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::TearDown();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetTestDataDirectory(base::FilePath* path) {
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool success = PathService::Get(base::DIR_SOURCE_ROOT, path);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(success);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!success)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *path = path->AppendASCII("third_party");
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *path = path->AppendASCII("zlib");
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *path = path->AppendASCII("google");
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *path = path->AppendASCII("test");
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *path = path->AppendASCII("data");
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path to temporary directory used to contain the test operations.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_dir_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path to the test data directory where test.zip etc. are located.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_data_dir_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path to test.zip in the test data directory.
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_zip_file_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path to evil.zip in the test data directory.
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath evil_zip_file_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path to evil_via_invalid_utf8.zip in the test data directory.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath evil_via_invalid_utf8_zip_file_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path to evil_via_absolute_file_name.zip in the test data directory.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath evil_via_absolute_file_name_zip_file_;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> test_zip_contents_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, Open_ValidZipFile) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ZipReaderTest, Open_ValidZipPlatformFile) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     PlatformFileWrapper::READ_ONLY);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, Open_NonExistentFile) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(reader.Open(test_data_dir_.AppendASCII("nonexistent.zip")));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, Open_ExistentButNonZipFile) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(reader.Open(test_data_dir_.AppendASCII("create_test_zip.sh")));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Iterate through the contents in the test zip file, and compare that the
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contents collected from the zip reader matches the expected contents.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, Iteration) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> actual_contents;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (reader.HasMore()) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.OpenCurrentEntryInZip());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    actual_contents.insert(reader.current_entry_info()->file_path());
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.AdvanceToNextEntry());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(reader.AdvanceToNextEntry());  // Shouldn't go further.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test_zip_contents_.size(),
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<size_t>(reader.num_entries()));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test_zip_contents_.size(), actual_contents.size());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test_zip_contents_, actual_contents);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Open the test zip file from a file descriptor, iterate through its contents,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and compare that they match the expected contents.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ZipReaderTest, PlatformFileIteration) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> actual_contents;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     PlatformFileWrapper::READ_ONLY);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (reader.HasMore()) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.OpenCurrentEntryInZip());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    actual_contents.insert(reader.current_entry_info()->file_path());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.AdvanceToNextEntry());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(reader.AdvanceToNextEntry());  // Shouldn't go further.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test_zip_contents_.size(),
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<size_t>(reader.num_entries()));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test_zip_contents_.size(), actual_contents.size());
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(test_zip_contents_, actual_contents);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, LocateAndOpenEntry_ValidFile) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> actual_contents;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(target_path, reader.current_entry_info()->file_path());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, LocateAndOpenEntry_NonExistentFile) {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> actual_contents;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("nonexistent.txt"));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(reader.LocateAndOpenEntry(target_path));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, reader.current_entry_info());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_RegularFile) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_dir_.AppendASCII("quux.txt")));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the output file ans compute the MD5.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                     &output));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string md5 = base::MD5String(output);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kExpectedMD5, md5);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // quux.txt should be larger than kZipBufSize so that we can exercise
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the loop in ExtractCurrentEntry().
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFilePath_RegularFile) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     PlatformFileWrapper::READ_ONLY);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_dir_.AppendASCII("quux.txt")));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the output file and compute the MD5.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                     &output));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string md5 = base::MD5String(output);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kExpectedMD5, md5);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // quux.txt should be larger than kZipBufSize so that we can exercise
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the loop in ExtractCurrentEntry().
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_POSIX)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFd_RegularFile) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     PlatformFileWrapper::READ_ONLY);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath out_path = test_dir_.AppendASCII("quux.txt");
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PlatformFileWrapper out_fd_w(out_path, PlatformFileWrapper::READ_WRITE);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(reader.ExtractCurrentEntryToFd(out_fd_w.platform_file()));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the output file and compute the MD5.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                     &output));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string md5 = base::MD5String(output);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kExpectedMD5, md5);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // quux.txt should be larger than kZipBufSize so that we can exercise
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the loop in ExtractCurrentEntry().
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_Directory) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/"));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_dir_.AppendASCII("foo")));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The directory should be created.
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::DirectoryExists(test_dir_.AppendASCII("foo")));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, ExtractCurrentEntryIntoDirectory_RegularFile) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.ExtractCurrentEntryIntoDirectory(test_dir_));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sub directories should be created.
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::DirectoryExists(test_dir_.AppendASCII("foo/bar")));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the file should be created.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_dir_.AppendASCII("foo/bar/quux.txt"), &output));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string md5 = base::MD5String(output);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kExpectedMD5, md5);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, current_entry_info_RegularFile) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(target_path, current_entry_info->file_path());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13527, current_entry_info->original_size());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The expected time stamp: 2009-05-29 06:22:20
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::Exploded exploded = {};  // Zero-clear.
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_entry_info->last_modified().LocalExplode(&exploded);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2009, exploded.year);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, exploded.month);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(29, exploded.day_of_month);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, exploded.hour);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(22, exploded.minute);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20, exploded.second);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, exploded.millisecond);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(current_entry_info->is_unsafe());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(current_entry_info->is_directory());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, current_entry_info_DotDotFile) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(evil_zip_file_));
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL(
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "../levilevilevilevilevilevilevilevilevilevilevilevil"));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(target_path, current_entry_info->file_path());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This file is unsafe because of ".." in the file name.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(current_entry_info->is_unsafe());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(current_entry_info->is_directory());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, current_entry_info_InvalidUTF8File) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(evil_via_invalid_utf8_zip_file_));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The evil file is the 2nd file in the zip file.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cannot locate by the file name ".\x80.\\evil.txt",
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as FilePath may internally convert the string.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.AdvanceToNextEntry());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.OpenCurrentEntryInZip());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This file is unsafe because of invalid UTF-8 in the file name.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(current_entry_info->is_unsafe());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(current_entry_info->is_directory());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, current_entry_info_AbsoluteFile) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(evil_via_absolute_file_name_zip_file_));
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("/evil.txt"));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(target_path, current_entry_info->file_path());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This file is unsafe because of the absolute file name.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(current_entry_info->is_unsafe());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(current_entry_info->is_directory());
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, current_entry_info_Directory) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.Open(test_zip_file_));
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/"));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("foo/bar/")),
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            current_entry_info->file_path());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The directory size should be zero.
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, current_entry_info->original_size());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The expected time stamp: 2009-05-31 15:49:52
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time::Exploded exploded = {};  // Zero-clear.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_entry_info->last_modified().LocalExplode(&exploded);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2009, exploded.year);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, exploded.month);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(31, exploded.day_of_month);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(15, exploded.hour);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(49, exploded.minute);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(52, exploded.second);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, exploded.millisecond);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(current_entry_info->is_unsafe());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(current_entry_info->is_directory());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that the ZipReader class can extract a file from a zip archive
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stored in memory. This test opens a zip archive in a std::string object,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extracts its content, and verifies the content is the same as the expected
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// text.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ZipReaderTest, OpenFromString) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A zip archive consisting of one file "test.txt", which is a 16-byte text
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file that contains "This is a test.\n".
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestData[] =
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\xa4\x66\x24\x41\x13\xe8"
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\xcb\x27\x10\x00\x00\x00\x10\x00\x00\x00\x08\x00\x1c\x00\x74\x65"
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x73\x74\x2e\x74\x78\x74\x55\x54\x09\x00\x03\x34\x89\x45\x50\x34"
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x89\x45\x50\x75\x78\x0b\x00\x01\x04\x8e\xf0\x00\x00\x04\x88\x13"
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x00\x00\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74"
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x2e\x0a\x50\x4b\x01\x02\x1e\x03\x0a\x00\x00\x00\x00\x00\xa4\x66"
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x24\x41\x13\xe8\xcb\x27\x10\x00\x00\x00\x10\x00\x00\x00\x08\x00"
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\xa4\x81\x00\x00\x00\x00"
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x74\x65\x73\x74\x2e\x74\x78\x74\x55\x54\x05\x00\x03\x34\x89\x45"
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x50\x75\x78\x0b\x00\x01\x04\x8e\xf0\x00\x00\x04\x88\x13\x00\x00"
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x50\x4b\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00\x4e\x00\x00\x00"
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x52\x00\x00\x00\x00\x00";
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data(kTestData, arraysize(kTestData));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZipReader reader;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.OpenFromString(data));
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath target_path(FILE_PATH_LITERAL("test.txt"));
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_dir_.AppendASCII("test.txt")));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string actual;
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_dir_.AppendASCII("test.txt"), &actual));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string("This is a test.\n"), actual);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace zip
432