diff --git a/graal-nodejs/deps/zlib/BUILD.gn b/graal-nodejs/deps/zlib/BUILD.gn index ecf2a095bcb..8ed0807a994 100644 --- a/graal-nodejs/deps/zlib/BUILD.gn +++ b/graal-nodejs/deps/zlib/BUILD.gn @@ -512,6 +512,7 @@ if (build_with_chromium) { } deps = [ + ":minizip", ":zlib", "google:compression_utils", "google:zip", diff --git a/graal-nodejs/deps/zlib/contrib/minizip/README.chromium b/graal-nodejs/deps/zlib/contrib/minizip/README.chromium index eefad439760..9c780f94682 100644 --- a/graal-nodejs/deps/zlib/contrib/minizip/README.chromium +++ b/graal-nodejs/deps/zlib/contrib/minizip/README.chromium @@ -15,3 +15,6 @@ Local Modifications: - Add parsing of the 'Info-ZIP Unicode Path Extra Field' as described in https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT section 4.6.9. (see crrev.com/1002476) + +- Check for overly long filename, comment, or extra field in + zipOpenNewFileInZip4_64 (crbug.com/1470539). diff --git a/graal-nodejs/deps/zlib/contrib/minizip/zip.c b/graal-nodejs/deps/zlib/contrib/minizip/zip.c index 44e88a9cb98..f21d4954286 100644 --- a/graal-nodejs/deps/zlib/contrib/minizip/zip.c +++ b/graal-nodejs/deps/zlib/contrib/minizip/zip.c @@ -1083,6 +1083,17 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, return ZIP_PARAMERROR; #endif + // The filename and comment length must fit in 16 bits. + if ((filename!=NULL) && (strlen(filename)>0xffff)) + return ZIP_PARAMERROR; + if ((comment!=NULL) && (strlen(comment)>0xffff)) + return ZIP_PARAMERROR; + // The extra field length must fit in 16 bits. If the member also requires + // a Zip64 extra block, that will also need to fit within that 16-bit + // length, but that will be checked for later. + if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) diff --git a/graal-nodejs/deps/zlib/contrib/tests/DEPS b/graal-nodejs/deps/zlib/contrib/tests/DEPS index 42751740686..67973613c74 100644 --- a/graal-nodejs/deps/zlib/contrib/tests/DEPS +++ b/graal-nodejs/deps/zlib/contrib/tests/DEPS @@ -1,4 +1,5 @@ include_rules = [ "+testing/gtest", + "+third_party/zlib/contrib/minizip", "+base", ] diff --git a/graal-nodejs/deps/zlib/contrib/tests/utils_unittest.cc b/graal-nodejs/deps/zlib/contrib/tests/utils_unittest.cc index 5745939f24f..7270d0af908 100644 --- a/graal-nodejs/deps/zlib/contrib/tests/utils_unittest.cc +++ b/graal-nodejs/deps/zlib/contrib/tests/utils_unittest.cc @@ -7,8 +7,12 @@ #include #include +#include "base/files/file_path.h" +#include "base/files/scoped_temp_dir.h" #include "compression_utils_portable.h" #include "gtest.h" +#include "third_party/zlib/contrib/minizip/unzip.h" +#include "third_party/zlib/contrib/minizip/zip.h" #include "zlib.h" void TestPayloads(size_t input_size, zlib_internal::WrapperType type) { @@ -1015,3 +1019,122 @@ TEST(ZlibTest, DeflateZFixedCorruption) { memcmp(zFixedCorruptionData, decompressed.data(), decompressed.size()), 0); } + +TEST(ZlibTest, ZipFilenameCommentSize) { + // Check that minizip rejects zip member filenames or comments longer than + // the zip format can represent. + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath zip_file = temp_dir.GetPath().AppendASCII("crbug1470539.zip"); + + zipFile zf = zipOpen(zip_file.AsUTF8Unsafe().c_str(), APPEND_STATUS_CREATE); + ASSERT_NE(zf, nullptr); + + // Adding a member with 2^16 byte filename is okay. + std::string long_filename(UINT16_MAX, 'a'); + EXPECT_EQ(zipOpenNewFileInZip(zf, long_filename.c_str(), nullptr, nullptr, 0, + nullptr, 0, nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_OK); + EXPECT_EQ(zipWriteInFileInZip(zf, "1", 1), ZIP_OK); + EXPECT_EQ(zipCloseFileInZip(zf), ZIP_OK); + + // Adding a member with 2^16+1 byte filename is NOT okay. + std::string too_long_filename = long_filename + 'a'; + EXPECT_EQ(zipOpenNewFileInZip(zf, too_long_filename.c_str(), nullptr, nullptr, + 0, nullptr, 0, nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + + // Adding a member with 2^16 byte comment is okay. + std::string long_comment(UINT16_MAX, 'x'); + EXPECT_EQ(zipOpenNewFileInZip(zf, "x", nullptr, nullptr, 0, nullptr, 0, + long_comment.c_str(), Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_OK); + EXPECT_EQ(zipCloseFileInZip(zf), ZIP_OK); + + // Adding a member with 2^16+1 byte comment is NOT okay. + std::string too_long_comment = long_comment + 'x'; + EXPECT_EQ(zipOpenNewFileInZip(zf, "x", nullptr, nullptr, 0, nullptr, 0, + too_long_comment.c_str(), Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + + EXPECT_EQ(zipClose(zf, nullptr), ZIP_OK); + + // Check that the long filename and comment members were successfully added. + unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str()); + ASSERT_NE(uzf, nullptr); + char buf[UINT16_MAX + 2]; + + ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, nullptr, buf, sizeof(buf), nullptr, 0, + nullptr, 0), + UNZ_OK); + EXPECT_EQ(std::string(buf), long_filename); + + ASSERT_EQ(unzGoToNextFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, nullptr, nullptr, 0, nullptr, 0, buf, + sizeof(buf)), + UNZ_OK); + EXPECT_EQ(std::string(buf), long_comment); + + EXPECT_EQ(unzGoToNextFile(uzf), UNZ_END_OF_LIST_OF_FILE); + EXPECT_EQ(unzClose(uzf), UNZ_OK); +} + +TEST(ZlibTest, ZipExtraFieldSize) { + // Check that minizip rejects zip members with too large extra fields. + + std::string extra_field; + extra_field.append("\x12\x34"); // Header ID. + extra_field.append("\xfb\xff"); // Data size (not including the header). + extra_field.append(UINT16_MAX - 4, 'a'); + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath zip_file = temp_dir.GetPath().AppendASCII("extrafield.zip"); + + zipFile zf = zipOpen(zip_file.AsUTF8Unsafe().c_str(), APPEND_STATUS_CREATE); + ASSERT_NE(zf, nullptr); + + // Adding a member with 2^16 byte extra field should work. + EXPECT_EQ(zipOpenNewFileInZip(zf, "a", nullptr, extra_field.data(), + extra_field.size(), extra_field.data(), + extra_field.size(), nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_OK); + EXPECT_EQ(zipWriteInFileInZip(zf, "1", 1), ZIP_OK); + EXPECT_EQ(zipCloseFileInZip(zf), ZIP_OK); + + // More then 2^16 bytes doesn't work. Neither for size_extrafield_local, nor + // size_extrafield_global. + std::string extra_field_long = extra_field + 'x'; + EXPECT_EQ( + zipOpenNewFileInZip(zf, "b", nullptr, nullptr, 0, extra_field_long.data(), + extra_field_long.size(), nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + EXPECT_EQ(zipOpenNewFileInZip(zf, "b", nullptr, extra_field_long.data(), + extra_field_long.size(), nullptr, 0, nullptr, + Z_DEFLATED, Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + + EXPECT_EQ(zipClose(zf, nullptr), ZIP_OK); + + // Check that the data can be read back. + unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str()); + ASSERT_NE(uzf, nullptr); + char buf[UINT16_MAX + 1] = {0}; + + ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, nullptr, nullptr, 0, buf, + sizeof(buf) - 1, nullptr, 0), + UNZ_OK); + EXPECT_EQ(std::string(buf), extra_field); + + EXPECT_EQ(unzGoToNextFile(uzf), UNZ_END_OF_LIST_OF_FILE); + EXPECT_EQ(unzClose(uzf), UNZ_OK); +} diff --git a/graal-nodejs/doc/contributing/maintaining/maintaining-dependencies.md b/graal-nodejs/doc/contributing/maintaining/maintaining-dependencies.md index 2a71075c4f0..916da9cb295 100644 --- a/graal-nodejs/doc/contributing/maintaining/maintaining-dependencies.md +++ b/graal-nodejs/doc/contributing/maintaining/maintaining-dependencies.md @@ -30,7 +30,7 @@ This a list of all the dependencies: * [uv][] * [uvwasi 0.0.19][] * [V8][] -* [zlib 1.2.13.1-motley-526382e][] +* [zlib 1.2.13.1-motley-f5fd0ad][] Any code which meets one or more of these conditions should be managed as a dependency: @@ -304,7 +304,7 @@ See [maintaining-web-assembly][] for more informations. high-performance JavaScript and WebAssembly engine, written in C++. See [maintaining-V8][] for more informations. -### zlib 1.2.13.1-motley-526382e +### zlib 1.2.13.1-motley-f5fd0ad The [zlib](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/zlib) dependency lossless data-compression library, @@ -341,4 +341,4 @@ performance improvements not currently available in standard zlib. [uv]: #uv [uvwasi 0.0.19]: #uvwasi-0019 [v8]: #v8 -[zlib 1.2.13.1-motley-526382e]: #zlib-12131-motley-526382e +[zlib 1.2.13.1-motley-f5fd0ad]: #zlib-12131-motley-f5fd0ad