Index: third_party/zlib/google/zip_unittest.cc |
diff --git a/third_party/zlib/google/zip_unittest.cc b/third_party/zlib/google/zip_unittest.cc |
index afa92f137c14283b1fc912a1cb7237a0eeb47fa1..4c4782d8ce0919e1c503b890d98b5f35f94757a0 100644 |
--- a/third_party/zlib/google/zip_unittest.cc |
+++ b/third_party/zlib/google/zip_unittest.cc |
@@ -10,8 +10,10 @@ |
#include "base/files/file_enumerator.h" |
#include "base/files/file_path.h" |
#include "base/files/scoped_temp_dir.h" |
+#include "base/memory/ref_counted_memory.h" |
#include "base/path_service.h" |
#include "base/strings/string_util.h" |
+#include "base/strings/stringprintf.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "testing/platform_test.h" |
#include "third_party/zlib/google/zip.h" |
@@ -156,6 +158,56 @@ class ZipTest : public PlatformTest { |
} |
} |
+ void PushFileToZipContents(zip::ZipContents* files, |
+ const char* file_name, |
+ const char* contents) { |
+ (*files)[base::FilePath::FromUTF8Unsafe(file_name)] = |
+ contents ? new base::RefCountedStaticMemory( |
+ contents, strlen(contents)) : |
+ NULL; |
+ } |
+ |
+ void RemoveFileFromZipContents(zip::ZipContents* files, |
+ const char* file_name) { |
+ files->erase(base::FilePath::FromUTF8Unsafe(file_name)); |
+ } |
+ |
+ void TestZipFileHasMemoryContents(const base::FilePath& zip_file, |
+ const zip::ZipContents& in_files) { |
+ zip::ZipReader reader; |
+ |
+ bool open_success = reader.Open(zip_file); |
+ EXPECT_TRUE(open_success); |
+ if (!open_success) |
+ // Else ZipReader will assert while using its API. |
+ return; |
+ |
+ EXPECT_EQ(in_files.size(), static_cast<size_t>(reader.num_entries())); |
+ for (zip::ZipContents::const_iterator it = in_files.begin(); |
+ it != in_files.end(); |
+ ++it) { |
+ DCHECK(it->second.get()); |
+ bool found_entry = reader.LocateAndOpenEntry(it->first); |
+ EXPECT_TRUE(found_entry); |
+ if (!found_entry) |
+ // Else entry_info will be NULL. |
+ continue; |
+ |
+ const zip::ZipReader::EntryInfo* entry_info = |
+ reader.current_entry_info(); |
+ EXPECT_EQ(entry_info->file_path(), it->first); |
+ EXPECT_EQ(entry_info->is_directory(), it->first.EndsWithSeparator()); |
+ EXPECT_EQ(entry_info->original_size(), |
+ static_cast<int64>(it->second->size())); |
+ |
+ if (it->second->size() != 0) { |
+ scoped_refptr<base::RefCountedMemory> mem; |
+ ASSERT_TRUE(reader.ExtractCurrentEntryToRefCountedMemory(1024, &mem)); |
+ EXPECT_TRUE(it->second->Equals(mem)); |
+ } |
+ } |
+ } |
+ |
// The path to temporary directory used to contain the test operations. |
base::FilePath test_dir_; |
@@ -301,5 +353,144 @@ TEST_F(ZipTest, ZipFiles) { |
} |
#endif // defined(OS_POSIX) |
+TEST_F(ZipTest, UnzipFilesWithIncorrectSize) { |
+ base::FilePath test_data_folder; |
+ ASSERT_TRUE(GetTestDataDirectory(&test_data_folder)); |
+ |
+ // test_mismatch_size.zip contains files with names from 0.txt to 7.txt with |
+ // sizes from 0 to 7 respectively, but the metadata in the zip file says the |
+ // size is 3 bytes. The reader code needs to be clever enough to get all the |
+ // data out. |
+ base::FilePath test_zip_file = |
+ test_data_folder.AppendASCII("test_mismatch_size.zip"); |
+ |
+ base::ScopedTempDir scoped_temp_dir; |
+ ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); |
+ const base::FilePath& temp_dir = scoped_temp_dir.path(); |
+ |
+ ASSERT_TRUE(zip::Unzip(test_zip_file, temp_dir)); |
+ |
+ EXPECT_TRUE(base::DirectoryExists(temp_dir.AppendASCII("d"))); |
+ |
+ for (int k = 0; k < 8; k++) { |
+ SCOPED_TRACE(base::StringPrintf("<loop:%d>", static_cast<int>(k))); |
+ base::FilePath file_path = temp_dir.AppendASCII( |
+ base::StringPrintf(FILE_PATH_LITERAL("%d.txt"), static_cast<int>(k))); |
+ int64 file_size = -1; |
+ EXPECT_TRUE(base::GetFileSize(file_path, &file_size)); |
+ EXPECT_EQ(file_size, static_cast<int64>(k)); |
+ } |
+} |
+ |
+TEST_F(ZipTest, ZipFilesFromMemoryEmptyFileNameError) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ |
+ base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
+ |
+ zip::ZipContents in_files; |
+ PushFileToZipContents(&in_files, "", "a"); |
+ |
+ EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
+} |
+ |
+TEST_F(ZipTest, ZipFilesFromMemoryFolderWithDataError) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ |
+ base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
+ |
+ // Folder must have null or empty contents. |
+ zip::ZipContents in_files; |
+ PushFileToZipContents(&in_files, "a/", "a"); |
+ |
+ EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
+} |
+ |
+TEST_F(ZipTest, ZipFilesFromMemoryAbsoluteFileNameError) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ |
+ base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
+ |
+ zip::ZipContents in_files; |
+ in_files[temp_dir.path().AppendASCII("foo.bar")] = NULL; |
+ |
+ EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
+} |
+ |
+TEST_F(ZipTest, ZipFilesFromMemoryRefsParentFileError) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ |
+ base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
+ |
+ zip::ZipContents in_files; |
+ PushFileToZipContents(&in_files, "..", "a"); |
+ EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
+ |
+ in_files.clear(); |
+ PushFileToZipContents(&in_files, "a/../b", "a"); |
+ EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
+ |
+ in_files.clear(); |
+ PushFileToZipContents(&in_files, "a/..", "a"); |
+ EXPECT_FALSE(zip::ZipFromMemory(zip_file, in_files, false)); |
+} |
+ |
+TEST_F(ZipTest, ZipFilesFromMemoryLotsOfData) { |
+ base::ScopedTempDir temp_dir; |
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
+ |
+ base::FilePath zip_file = temp_dir.path().AppendASCII("out.zip"); |
+ EXPECT_FALSE(base::PathExists(zip_file)); |
+ |
+ // Nothing to do. |
+ zip::ZipContents in_files; |
+ EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, true)); |
+ |
+ // Add some files. |
+ PushFileToZipContents(&in_files, "a", ""); |
+ PushFileToZipContents(&in_files, "b", "y"); |
+ PushFileToZipContents(&in_files, "c", "x"); |
+ PushFileToZipContents(&in_files, "D/", ""); |
+ PushFileToZipContents(&in_files, "E/a", "a"); |
+ EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, true)); |
+ |
+ TestZipFileHasMemoryContents(zip_file, in_files); |
+ |
+ // Add new file, and remove old one. |
+ zip::ZipContents in_files_2; |
+ PushFileToZipContents(&in_files_2, "h", "h"); |
+ PushFileToZipContents(&in_files_2, "E/a", NULL); |
+ EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files_2, true)); |
+ |
+ PushFileToZipContents(&in_files, "h", "h"); |
+ RemoveFileFromZipContents(&in_files, "E/a"); |
+ TestZipFileHasMemoryContents(zip_file, in_files); |
+ |
+ // Modify, add and remove all in one set. |
+ PushFileToZipContents(&in_files, "a", "aaa"); |
+ RemoveFileFromZipContents(&in_files, "b"); // Must be preserved. |
+ PushFileToZipContents(&in_files, "c", ""); |
+ PushFileToZipContents(&in_files, "D/", NULL); |
+ PushFileToZipContents(&in_files, "not-here/", NULL); |
+ PushFileToZipContents(&in_files, "not-here-2", NULL); |
+ PushFileToZipContents(&in_files, "E/a", ""); |
+ PushFileToZipContents(&in_files, "X/c/a", "xx"); |
+ PushFileToZipContents(&in_files, "X/c/", ""); |
+ EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, true)); |
+ |
+ RemoveFileFromZipContents(&in_files, "D/"); |
+ RemoveFileFromZipContents(&in_files, "not-here/"); |
+ RemoveFileFromZipContents(&in_files, "not-here-2"); |
+ PushFileToZipContents(&in_files, "b", "y"); |
+ TestZipFileHasMemoryContents(zip_file, in_files); |
+ |
+ // Recreate file from scratch. |
+ EXPECT_TRUE(zip::ZipFromMemory(zip_file, in_files, false)); |
+ TestZipFileHasMemoryContents(zip_file, in_files); |
+} |
+ |
} // namespace |