1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <set> 6 7 #include "base/file_util.h" 8 #include "base/memory/scoped_temp_dir.h" 9 #include "base/path_service.h" 10 #include "base/string_util.h" 11 #include "chrome/common/chrome_paths.h" 12 #include "chrome/common/zip.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/platform_test.h" 15 16 namespace { 17 18 // Make the test a PlatformTest to setup autorelease pools properly on Mac. 19 class ZipTest : public PlatformTest { 20 protected: 21 virtual void SetUp() { 22 PlatformTest::SetUp(); 23 24 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 25 test_dir_ = temp_dir_.path(); 26 27 FilePath zip_path(test_dir_); 28 zip_contents_.insert(zip_path.AppendASCII("foo.txt")); 29 zip_path = zip_path.AppendASCII("foo"); 30 zip_contents_.insert(zip_path); 31 zip_contents_.insert(zip_path.AppendASCII("bar.txt")); 32 zip_path = zip_path.AppendASCII("bar"); 33 zip_contents_.insert(zip_path); 34 zip_contents_.insert(zip_path.AppendASCII("baz.txt")); 35 zip_contents_.insert(zip_path.AppendASCII("quux.txt")); 36 zip_contents_.insert(zip_path.AppendASCII(".hidden")); 37 } 38 39 virtual void TearDown() { 40 PlatformTest::TearDown(); 41 } 42 43 void TestUnzipFile(const FilePath::StringType& filename, 44 bool expect_hidden_files) { 45 FilePath test_dir; 46 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); 47 test_dir = test_dir.AppendASCII("zip"); 48 TestUnzipFile(test_dir.Append(filename), expect_hidden_files); 49 } 50 51 void TestUnzipFile(const FilePath& path, bool expect_hidden_files) { 52 ASSERT_TRUE(file_util::PathExists(path)) << "no file " << path.value(); 53 ASSERT_TRUE(Unzip(path, test_dir_)); 54 55 file_util::FileEnumerator files(test_dir_, true, 56 static_cast<file_util::FileEnumerator::FILE_TYPE>( 57 file_util::FileEnumerator::FILES | 58 file_util::FileEnumerator::DIRECTORIES)); 59 FilePath next_path = files.Next(); 60 size_t count = 0; 61 while (!next_path.value().empty()) { 62 if (next_path.value().find(FILE_PATH_LITERAL(".svn")) == 63 FilePath::StringType::npos) { 64 EXPECT_EQ(zip_contents_.count(next_path), 1U) << 65 "Couldn't find " << next_path.value(); 66 count++; 67 } 68 next_path = files.Next(); 69 } 70 71 size_t expected_count = 0; 72 for (std::set<FilePath>::iterator iter = zip_contents_.begin(); 73 iter != zip_contents_.end(); ++iter) { 74 if (expect_hidden_files || iter->BaseName().value()[0] != '.') 75 ++expected_count; 76 } 77 78 EXPECT_EQ(expected_count, count); 79 } 80 81 // the path to temporary directory used to contain the test operations 82 FilePath test_dir_; 83 84 ScopedTempDir temp_dir_; 85 86 // hard-coded contents of a known zip file 87 std::set<FilePath> zip_contents_; 88 }; 89 90 TEST_F(ZipTest, Unzip) { 91 TestUnzipFile(FILE_PATH_LITERAL("test.zip"), true); 92 } 93 94 TEST_F(ZipTest, UnzipUncompressed) { 95 TestUnzipFile(FILE_PATH_LITERAL("test_nocompress.zip"), true); 96 } 97 98 TEST_F(ZipTest, UnzipEvil) { 99 FilePath path; 100 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); 101 path = path.AppendASCII("zip").AppendASCII("evil.zip"); 102 ASSERT_FALSE(Unzip(path, test_dir_)); 103 FilePath evil_file = test_dir_; 104 evil_file = evil_file.AppendASCII( 105 "../levilevilevilevilevilevilevilevilevilevilevilevil"); 106 ASSERT_FALSE(file_util::PathExists(evil_file)); 107 } 108 109 TEST_F(ZipTest, UnzipEvil2) { 110 FilePath path; 111 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); 112 path = path.AppendASCII("zip").AppendASCII("evil_via_invalid_utf8.zip"); 113 ASSERT_TRUE(Unzip(path, test_dir_)); 114 FilePath evil_file = test_dir_; 115 evil_file = evil_file.AppendASCII("../evil.txt"); 116 ASSERT_FALSE(file_util::PathExists(evil_file)); 117 } 118 119 TEST_F(ZipTest, Zip) { 120 FilePath src_dir; 121 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &src_dir)); 122 src_dir = src_dir.AppendASCII("zip").AppendASCII("test"); 123 124 ScopedTempDir temp_dir; 125 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 126 FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); 127 128 EXPECT_TRUE(Zip(src_dir, zip_file, true)); 129 TestUnzipFile(zip_file, true); 130 } 131 132 TEST_F(ZipTest, ZipIgnoreHidden) { 133 FilePath src_dir; 134 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &src_dir)); 135 src_dir = src_dir.AppendASCII("zip").AppendASCII("test"); 136 137 ScopedTempDir temp_dir; 138 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 139 FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); 140 141 EXPECT_TRUE(Zip(src_dir, zip_file, false)); 142 TestUnzipFile(zip_file, false); 143 } 144 145 } // namespace 146