OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <set> | 5 #include <set> |
6 #include <string> | 6 #include <string> |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/memory/ref_counted_memory.h" |
13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/stringprintf.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
17 #include "third_party/zlib/google/zip.h" | 19 #include "third_party/zlib/google/zip.h" |
18 #include "third_party/zlib/google/zip_reader.h" | 20 #include "third_party/zlib/google/zip_reader.h" |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 // Make the test a PlatformTest to setup autorelease pools properly on Mac. | 24 // Make the test a PlatformTest to setup autorelease pools properly on Mac. |
23 class ZipTest : public PlatformTest { | 25 class ZipTest : public PlatformTest { |
24 protected: | 26 protected: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 EXPECT_EQ(file_info.size, 1); | 151 EXPECT_EQ(file_info.size, 1); |
150 | 152 |
151 if (valid_year == VALID_YEAR) { | 153 if (valid_year == VALID_YEAR) { |
152 EXPECT_EQ(file_info.last_modified, test_mtime); | 154 EXPECT_EQ(file_info.last_modified, test_mtime); |
153 } else { | 155 } else { |
154 // Invalid date means the modification time will default to 'now'. | 156 // Invalid date means the modification time will default to 'now'. |
155 EXPECT_GE(file_info.last_modified, now_time); | 157 EXPECT_GE(file_info.last_modified, now_time); |
156 } | 158 } |
157 } | 159 } |
158 | 160 |
| 161 void PushFileToZipContents(zip::ZipContents* files, |
| 162 const char* file_name, |
| 163 const char* contents) { |
| 164 (*files)[base::FilePath::FromUTF8Unsafe(file_name)] = |
| 165 contents ? new base::RefCountedStaticMemory( |
| 166 contents, strlen(contents)) : |
| 167 NULL; |
| 168 } |
| 169 |
| 170 void RemoveFileFromZipContents(zip::ZipContents* files, |
| 171 const char* file_name) { |
| 172 files->erase(base::FilePath::FromUTF8Unsafe(file_name)); |
| 173 } |
| 174 |
| 175 void TestZipFileHasMemoryContents(const base::FilePath& zip_file, |
| 176 const zip::ZipContents& in_files) { |
| 177 zip::ZipReader reader; |
| 178 |
| 179 bool open_success = reader.Open(zip_file); |
| 180 EXPECT_TRUE(open_success); |
| 181 if (!open_success) |
| 182 // Else ZipReader will assert while using its API. |
| 183 return; |
| 184 |
| 185 EXPECT_EQ(in_files.size(), static_cast<size_t>(reader.num_entries())); |
| 186 for (zip::ZipContents::const_iterator it = in_files.begin(); |
| 187 it != in_files.end(); |
| 188 ++it) { |
| 189 DCHECK(it->second.get()); |
| 190 bool found_entry = reader.LocateAndOpenEntry(it->first); |
| 191 EXPECT_TRUE(found_entry); |
| 192 if (!found_entry) |
| 193 // Else entry_info will be NULL. |
| 194 continue; |
| 195 |
| 196 const zip::ZipReader::EntryInfo* entry_info = |
| 197 reader.current_entry_info(); |
| 198 EXPECT_EQ(entry_info->file_path(), it->first); |
| 199 EXPECT_EQ(entry_info->is_directory(), it->first.EndsWithSeparator()); |
| 200 EXPECT_EQ(entry_info->original_size(), |
| 201 static_cast<int64>(it->second->size())); |
| 202 |
| 203 if (it->second->size() != 0) { |
| 204 scoped_refptr<base::RefCountedMemory> mem; |
| 205 ASSERT_TRUE(reader.ExtractCurrentEntryToRefCountedMemory(1024, &mem)); |
| 206 EXPECT_TRUE(it->second->Equals(mem)); |
| 207 } |
| 208 } |
| 209 } |
| 210 |
159 // The path to temporary directory used to contain the test operations. | 211 // The path to temporary directory used to contain the test operations. |
160 base::FilePath test_dir_; | 212 base::FilePath test_dir_; |
161 | 213 |
162 base::ScopedTempDir temp_dir_; | 214 base::ScopedTempDir temp_dir_; |
163 | 215 |
164 // Hard-coded contents of a known zip file. | 216 // Hard-coded contents of a known zip file. |
165 std::set<base::FilePath> zip_contents_; | 217 std::set<base::FilePath> zip_contents_; |
166 | 218 |
167 // Hard-coded list of relative paths for a zip file created with ZipFiles. | 219 // Hard-coded list of relative paths for a zip file created with ZipFiles. |
168 std::vector<base::FilePath> zip_file_list_; | 220 std::vector<base::FilePath> zip_file_list_; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 EXPECT_EQ(zip_file_list_.size(), static_cast<size_t>(reader.num_entries())); | 346 EXPECT_EQ(zip_file_list_.size(), static_cast<size_t>(reader.num_entries())); |
295 for (size_t i = 0; i < zip_file_list_.size(); ++i) { | 347 for (size_t i = 0; i < zip_file_list_.size(); ++i) { |
296 EXPECT_TRUE(reader.LocateAndOpenEntry(zip_file_list_[i])); | 348 EXPECT_TRUE(reader.LocateAndOpenEntry(zip_file_list_[i])); |
297 // Check the path in the entry just in case. | 349 // Check the path in the entry just in case. |
298 const zip::ZipReader::EntryInfo* entry_info = reader.current_entry_info(); | 350 const zip::ZipReader::EntryInfo* entry_info = reader.current_entry_info(); |
299 EXPECT_EQ(entry_info->file_path(), zip_file_list_[i]); | 351 EXPECT_EQ(entry_info->file_path(), zip_file_list_[i]); |
300 } | 352 } |
301 } | 353 } |
302 #endif // defined(OS_POSIX) | 354 #endif // defined(OS_POSIX) |
303 | 355 |
| 356 TEST_F(ZipTest, UnzipFilesWithIncorrectSize) { |
| 357 base::FilePath test_data_folder; |
| 358 ASSERT_TRUE(GetTestDataDirectory(&test_data_folder)); |
| 359 |
| 360 // test_mismatch_size.zip contains files with names from 0.txt to 7.txt with |
| 361 // sizes from 0 to 7 respectively, but the metadata in the zip file says the |
| 362 // size is 3 bytes. The reader code needs to be clever enough to get all the |
| 363 // data out. |
| 364 base::FilePath test_zip_file = |
| 365 test_data_folder.AppendASCII("test_mismatch_size.zip"); |
| 366 |
| 367 base::ScopedTempDir scoped_temp_dir; |
| 368 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); |
| 369 const base::FilePath& temp_dir = scoped_temp_dir.path(); |
| 370 |
| 371 ASSERT_TRUE(zip::Unzip(test_zip_file, temp_dir)); |
| 372 |
| 373 EXPECT_TRUE(base::DirectoryExists(temp_dir.AppendASCII("d"))); |
| 374 |
| 375 for (int k = 0; k < 8; k++) { |
| 376 SCOPED_TRACE(base::StringPrintf("<loop:%d>", static_cast<int>(k))); |
| 377 base::FilePath file_path = temp_dir.AppendASCII( |
| 378 base::StringPrintf(FILE_PATH_LITERAL("%d.txt"), static_cast<int>(k))); |
| 379 int64 file_size = -1; |
| 380 EXPECT_TRUE(base::GetFileSize(file_path, &file_size)); |
| 381 EXPECT_EQ(file_size, static_cast<int64>(k)); |
| 382 } |
| 383 } |
| 384 |
| 385 TEST_F(ZipTest, ZipFilesFromMemoryEmptyFileNameError) { |
| 386 base::ScopedTempDir temp_dir; |
| 387 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 388 |
| 389 base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
| 390 |
| 391 zip::ZipContents in_files; |
| 392 PushFileToZipContents(&in_files, "", "a"); |
| 393 |
| 394 EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 395 } |
| 396 |
| 397 TEST_F(ZipTest, ZipFilesFromMemoryFolderWithDataError) { |
| 398 base::ScopedTempDir temp_dir; |
| 399 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 400 |
| 401 base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
| 402 |
| 403 // Folder must have null or empty contents. |
| 404 zip::ZipContents in_files; |
| 405 PushFileToZipContents(&in_files, "a/", "a"); |
| 406 |
| 407 EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 408 } |
| 409 |
| 410 TEST_F(ZipTest, ZipFilesFromMemoryAbsoluteFileNameError) { |
| 411 base::ScopedTempDir temp_dir; |
| 412 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 413 |
| 414 base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
| 415 |
| 416 zip::ZipContents in_files; |
| 417 in_files[temp_dir.path().AppendASCII("foo.bar")] = NULL; |
| 418 |
| 419 EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 420 } |
| 421 |
| 422 TEST_F(ZipTest, ZipFilesFromMemoryRefsParentFileError) { |
| 423 base::ScopedTempDir temp_dir; |
| 424 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 425 |
| 426 base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
| 427 |
| 428 zip::ZipContents in_files; |
| 429 PushFileToZipContents(&in_files, "..", "a"); |
| 430 EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 431 |
| 432 in_files.clear(); |
| 433 PushFileToZipContents(&in_files, "a/../b", "a"); |
| 434 EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 435 |
| 436 in_files.clear(); |
| 437 PushFileToZipContents(&in_files, "a/..", "a"); |
| 438 EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 439 } |
| 440 |
| 441 TEST_F(ZipTest, ZipFilesFromMemoryLotsOfData) { |
| 442 base::ScopedTempDir temp_dir; |
| 443 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 444 |
| 445 base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
| 446 EXPECT_FALSE(base::PathExists(zip_file)); |
| 447 |
| 448 // Nothing to do. |
| 449 zip::ZipContents in_files; |
| 450 EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, true)); |
| 451 |
| 452 // Add some files. |
| 453 PushFileToZipContents(&in_files, "a", ""); |
| 454 PushFileToZipContents(&in_files, "b", "y"); |
| 455 PushFileToZipContents(&in_files, "c", "x"); |
| 456 PushFileToZipContents(&in_files, "D/", ""); |
| 457 PushFileToZipContents(&in_files, "E/a", "a"); |
| 458 EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, true)); |
| 459 |
| 460 TestZipFileHasMemoryContents(zip_file, in_files); |
| 461 |
| 462 // Add new file, and remove old one. |
| 463 zip::ZipContents in_files_2; |
| 464 PushFileToZipContents(&in_files_2, "h", "h"); |
| 465 PushFileToZipContents(&in_files_2, "E/a", NULL); |
| 466 EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files_2, true)); |
| 467 |
| 468 PushFileToZipContents(&in_files, "h", "h"); |
| 469 RemoveFileFromZipContents(&in_files, "E/a"); |
| 470 TestZipFileHasMemoryContents(zip_file, in_files); |
| 471 |
| 472 // Modify, add and remove all in one set. |
| 473 PushFileToZipContents(&in_files, "a", "aaa"); |
| 474 RemoveFileFromZipContents(&in_files, "b"); // Must be preserved. |
| 475 PushFileToZipContents(&in_files, "c", ""); |
| 476 PushFileToZipContents(&in_files, "D/", NULL); |
| 477 PushFileToZipContents(&in_files, "not-here/", NULL); |
| 478 PushFileToZipContents(&in_files, "not-here-2", NULL); |
| 479 PushFileToZipContents(&in_files, "E/a", ""); |
| 480 PushFileToZipContents(&in_files, "X/c/a", "xx"); |
| 481 PushFileToZipContents(&in_files, "X/c/", ""); |
| 482 EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, true)); |
| 483 |
| 484 RemoveFileFromZipContents(&in_files, "D/"); |
| 485 RemoveFileFromZipContents(&in_files, "not-here/"); |
| 486 RemoveFileFromZipContents(&in_files, "not-here-2"); |
| 487 PushFileToZipContents(&in_files, "b", "y"); |
| 488 TestZipFileHasMemoryContents(zip_file, in_files); |
| 489 |
| 490 // Recreate file from scratch. |
| 491 EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, false)); |
| 492 TestZipFileHasMemoryContents(zip_file, in_files); |
| 493 } |
| 494 |
304 } // namespace | 495 } // namespace |
305 | 496 |
OLD | NEW |