Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: chrome/common/zip_reader_unittest.cc

Issue 8508003: zip: Add ZipReader and rework Unzip() using the new class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix a win failure Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/zip_reader.cc ('k') | chrome/common/zip_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "chrome/common/zip_reader.h"
6
7 #include <set>
8 #include <string>
9
10 #include "base/file_util.h"
11 #include "base/md5.h"
12 #include "base/path_service.h"
13 #include "base/scoped_temp_dir.h"
14 #include "base/time.h"
15 #include "base/utf_string_conversions.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/zip_internal.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/platform_test.h"
20
21 namespace zip {
22
23 // Make the test a PlatformTest to setup autorelease pools properly on Mac.
24 class ZipReaderTest : public PlatformTest {
25 protected:
26 virtual void SetUp() {
27 PlatformTest::SetUp();
28
29 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
30 test_dir_ = temp_dir_.path();
31
32 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
33 test_data_dir_ = test_data_dir_.AppendASCII("zip");
34
35 test_zip_file_ = test_data_dir_.AppendASCII("test.zip");
36 evil_zip_file_ = test_data_dir_.AppendASCII("evil.zip");
37 evil_via_invalid_utf8_zip_file_ = test_data_dir_.AppendASCII(
38 "evil_via_invalid_utf8.zip");
39 evil_via_absolute_file_name_zip_file_ = test_data_dir_.AppendASCII(
40 "evil_via_absolute_file_name.zip");
41
42 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo/")));
43 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo/bar/")));
44 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo/bar/baz.txt")));
45 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo/bar/quux.txt")));
46 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo/bar.txt")));
47 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo.txt")));
48 test_zip_contents_.insert(FilePath(FILE_PATH_LITERAL("foo/bar/.hidden")));
49 }
50
51 virtual void TearDown() {
52 PlatformTest::TearDown();
53 }
54
55 // The path to temporary directory used to contain the test operations.
56 FilePath test_dir_;
57 // The path to the test data directory where test.zip etc. are located.
58 FilePath test_data_dir_;
59 // The path to test.zip in the test data directory.
60 FilePath test_zip_file_;
61 // The path to evil.zip in the test data directory.
62 FilePath evil_zip_file_;
63 // The path to evil_via_invalid_utf8.zip in the test data directory.
64 FilePath evil_via_invalid_utf8_zip_file_;
65 // The path to evil_via_absolute_file_name.zip in the test data directory.
66 FilePath evil_via_absolute_file_name_zip_file_;
67 std::set<FilePath> test_zip_contents_;
68
69 ScopedTempDir temp_dir_;
70 };
71
72 TEST_F(ZipReaderTest, Open_ValidZipFile) {
73 ZipReader reader;
74 ASSERT_TRUE(reader.Open(test_zip_file_));
75 }
76
77 TEST_F(ZipReaderTest, Open_NonExistentFile) {
78 ZipReader reader;
79 ASSERT_FALSE(reader.Open(test_data_dir_.AppendASCII("nonexistent.zip")));
80 }
81
82 TEST_F(ZipReaderTest, Open_ExistentButNonZipFile) {
83 ZipReader reader;
84 ASSERT_FALSE(reader.Open(test_data_dir_.AppendASCII("create_test_zip.sh")));
85 }
86
87 // Iterate through the contents in the test zip file, and compare that the
88 // contents collected from the zip reader matches the expected contents.
89 TEST_F(ZipReaderTest, Iteration) {
90 std::set<FilePath> actual_contents;
91 ZipReader reader;
92 ASSERT_TRUE(reader.Open(test_zip_file_));
93 while (reader.HasMore()) {
94 ASSERT_TRUE(reader.OpenCurrentEntryInZip());
95 actual_contents.insert(reader.current_entry_info()->file_path());
96 ASSERT_TRUE(reader.AdvanceToNextEntry());
97 }
98 EXPECT_FALSE(reader.AdvanceToNextEntry()); // Shouldn't go further.
99 EXPECT_EQ(test_zip_contents_.size(),
100 static_cast<size_t>(reader.num_entries()));
101 EXPECT_EQ(test_zip_contents_.size(), actual_contents.size());
102 EXPECT_EQ(test_zip_contents_, actual_contents);
103 }
104
105
106 TEST_F(ZipReaderTest, LocateAndOpenEntry_ValidFile) {
107 std::set<FilePath> actual_contents;
108 ZipReader reader;
109 ASSERT_TRUE(reader.Open(test_zip_file_));
110 FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
111 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
112 EXPECT_EQ(target_path, reader.current_entry_info()->file_path());
113 }
114
115 TEST_F(ZipReaderTest, LocateAndOpenEntry_NonExistentFile) {
116 std::set<FilePath> actual_contents;
117 ZipReader reader;
118 ASSERT_TRUE(reader.Open(test_zip_file_));
119 FilePath target_path(FILE_PATH_LITERAL("nonexistent.txt"));
120 ASSERT_FALSE(reader.LocateAndOpenEntry(target_path));
121 EXPECT_EQ(NULL, reader.current_entry_info());
122 }
123
124 TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_RegularFile) {
125 ZipReader reader;
126 ASSERT_TRUE(reader.Open(test_zip_file_));
127 FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
128 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
129 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
130 test_dir_.AppendASCII("quux.txt")));
131 // Read the output file ans compute the MD5.
132 std::string output;
133 ASSERT_TRUE(file_util::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
134 &output));
135 const std::string md5 = base::MD5String(output);
136 const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
137 EXPECT_EQ(kExpectedMD5, md5);
138 // quux.txt should be larger than kZipBufSize so that we can exercise
139 // the loop in ExtractCurrentEntry().
140 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
141 }
142
143 TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_Directory) {
144 ZipReader reader;
145 ASSERT_TRUE(reader.Open(test_zip_file_));
146 FilePath target_path(FILE_PATH_LITERAL("foo/"));
147 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
148 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
149 test_dir_.AppendASCII("foo")));
150 // The directory should be created.
151 ASSERT_TRUE(file_util::DirectoryExists(test_dir_.AppendASCII("foo")));
152 }
153
154 TEST_F(ZipReaderTest, ExtractCurrentEntryIntoDirectory_RegularFile) {
155 ZipReader reader;
156 ASSERT_TRUE(reader.Open(test_zip_file_));
157 FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
158 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
159 ASSERT_TRUE(reader.ExtractCurrentEntryIntoDirectory(test_dir_));
160 // Sub directories should be created.
161 ASSERT_TRUE(file_util::DirectoryExists(test_dir_.AppendASCII("foo/bar")));
162 // And the file should be created.
163 std::string output;
164 ASSERT_TRUE(file_util::ReadFileToString(
165 test_dir_.AppendASCII("foo/bar/quux.txt"), &output));
166 const std::string md5 = base::MD5String(output);
167 const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
168 EXPECT_EQ(kExpectedMD5, md5);
169 }
170
171 TEST_F(ZipReaderTest, current_entry_info_RegularFile) {
172 ZipReader reader;
173 ASSERT_TRUE(reader.Open(test_zip_file_));
174 FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
175 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
176 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
177
178 EXPECT_EQ(target_path, current_entry_info->file_path());
179 EXPECT_EQ(13527, current_entry_info->original_size());
180
181 // The expected time stamp: 2009-05-29 06:22:20
182 base::Time::Exploded exploded = {}; // Zero-clear.
183 current_entry_info->last_modified().LocalExplode(&exploded);
184 EXPECT_EQ(2009, exploded.year);
185 EXPECT_EQ(5, exploded.month);
186 EXPECT_EQ(29, exploded.day_of_month);
187 EXPECT_EQ(6, exploded.hour);
188 EXPECT_EQ(22, exploded.minute);
189 EXPECT_EQ(20, exploded.second);
190 EXPECT_EQ(0, exploded.millisecond);
191
192 EXPECT_FALSE(current_entry_info->is_unsafe());
193 EXPECT_FALSE(current_entry_info->is_directory());
194 }
195
196 TEST_F(ZipReaderTest, current_entry_info_DotDotFile) {
197 ZipReader reader;
198 ASSERT_TRUE(reader.Open(evil_zip_file_));
199 FilePath target_path(FILE_PATH_LITERAL(
200 "../levilevilevilevilevilevilevilevilevilevilevilevil"));
201 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
202 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
203 EXPECT_EQ(target_path, current_entry_info->file_path());
204
205 // This file is unsafe because of ".." in the file name.
206 EXPECT_TRUE(current_entry_info->is_unsafe());
207 EXPECT_FALSE(current_entry_info->is_directory());
208 }
209
210 TEST_F(ZipReaderTest, current_entry_info_InvalidUTF8File) {
211 ZipReader reader;
212 ASSERT_TRUE(reader.Open(evil_via_invalid_utf8_zip_file_));
213 // The evil file is the 2nd file in the zip file.
214 // We cannot locate by the file name ".\x80.\\evil.txt",
215 // as FilePath may internally convert the string.
216 ASSERT_TRUE(reader.AdvanceToNextEntry());
217 ASSERT_TRUE(reader.OpenCurrentEntryInZip());
218 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
219
220 // This file is unsafe because of invalid UTF-8 in the file name.
221 EXPECT_TRUE(current_entry_info->is_unsafe());
222 EXPECT_FALSE(current_entry_info->is_directory());
223 }
224
225 TEST_F(ZipReaderTest, current_entry_info_AbsoluteFile) {
226 ZipReader reader;
227 ASSERT_TRUE(reader.Open(evil_via_absolute_file_name_zip_file_));
228 FilePath target_path(FILE_PATH_LITERAL("/evil.txt"));
229 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
230 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
231 EXPECT_EQ(target_path, current_entry_info->file_path());
232
233 // This file is unsafe because of the absolute file name.
234 EXPECT_TRUE(current_entry_info->is_unsafe());
235 EXPECT_FALSE(current_entry_info->is_directory());
236 }
237
238 TEST_F(ZipReaderTest, current_entry_info_Directory) {
239 ZipReader reader;
240 ASSERT_TRUE(reader.Open(test_zip_file_));
241 FilePath target_path(FILE_PATH_LITERAL("foo/bar/"));
242 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
243 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
244
245 EXPECT_EQ(FilePath(FILE_PATH_LITERAL("foo/bar/")),
246 current_entry_info->file_path());
247 // The directory size should be zero.
248 EXPECT_EQ(0, current_entry_info->original_size());
249
250 // The expected time stamp: 2009-05-31 15:49:52
251 base::Time::Exploded exploded = {}; // Zero-clear.
252 current_entry_info->last_modified().LocalExplode(&exploded);
253 EXPECT_EQ(2009, exploded.year);
254 EXPECT_EQ(5, exploded.month);
255 EXPECT_EQ(31, exploded.day_of_month);
256 EXPECT_EQ(15, exploded.hour);
257 EXPECT_EQ(49, exploded.minute);
258 EXPECT_EQ(52, exploded.second);
259 EXPECT_EQ(0, exploded.millisecond);
260
261 EXPECT_FALSE(current_entry_info->is_unsafe());
262 EXPECT_TRUE(current_entry_info->is_directory());
263 }
264
265 } // namespace zip
OLDNEW
« no previous file with comments | « chrome/common/zip_reader.cc ('k') | chrome/common/zip_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698