Home | History | Annotate | Download | only in common
      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