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