From 6e6c7f13fe7b2f76fa3e588eb47c247312bd6f86 Mon Sep 17 00:00:00 2001 From: nodejs-github-bot <18269663+nodejs-github-bot@users.noreply.github.com> Date: Sun, 8 Feb 2026 00:59:55 +0000 Subject: [PATCH] deps: update zlib to 1.3.1-7eda07b --- deps/zlib/contrib/minizip/README.chromium | 3 ++ deps/zlib/contrib/minizip/unzip.c | 24 ++++++++++-- deps/zlib/google/zip_reader.cc | 26 ++++++++----- deps/zlib/google/zip_reader.h | 9 +++-- deps/zlib/google/zip_reader_unittest.cc | 10 ++--- deps/zlib/google/zip_unittest.cc | 5 ++- deps/zlib/google/zip_writer.cc | 18 +++++---- deps/zlib/patches/0019-fix-zip64-in-zip.patch | 37 +++++++++++++++++++ src/zlib_version.h | 2 +- 9 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 deps/zlib/patches/0019-fix-zip64-in-zip.patch diff --git a/deps/zlib/contrib/minizip/README.chromium b/deps/zlib/contrib/minizip/README.chromium index 0299a7e331f9ee..45a6ce38912651 100644 --- a/deps/zlib/contrib/minizip/README.chromium +++ b/deps/zlib/contrib/minizip/README.chromium @@ -40,3 +40,6 @@ Local Modifications: large CRX files). 0018-support-prefixed-zip64.patch +- Added stricter parsing for zip64 candidates to avoid an issue where a zip64 + could be embedded in a non-zip64 zip. + 0019-fix-zip64-in-zip.patch diff --git a/deps/zlib/contrib/minizip/unzip.c b/deps/zlib/contrib/minizip/unzip.c index b77b787ccc0dbe..78663ec2d53a83 100644 --- a/deps/zlib/contrib/minizip/unzip.c +++ b/deps/zlib/contrib/minizip/unzip.c @@ -444,12 +444,28 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; - for (i=(int)uReadSize-3; (i--)>0;) + /* Search for the non-zip64 EoCDR and confirm zip64 EoCDL is 20 bytes + earlier. This avoids false positives if the file is a non-zip64 zip + but contains an uncompressed zip64 near its end. Note: zip64 EoCDL is + 20 bytes long. */ + for (i=(int)uReadSize-3; (i--)>20;) + // End of central directory record signature (PK\5\6) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { - uPosFound = uReadPos+(unsigned)i; - break; + // Zip64 end of central directory locator signature (PK\6\7) + if (((*(buf+i-20))==0x50) && ((*(buf+i+1-20))==0x4b) && + ((*(buf+i+2-20))==0x06) && ((*(buf+i+3-20))==0x07)) + { + uPosFound = uReadPos+(unsigned)i-20; + break; + } + else + { + /* This is a non-zip64 zip; abandon the search. */ + free(buf); + return CENTRALDIRINVALID; + } } if (uPosFound!=CENTRALDIRINVALID) diff --git a/deps/zlib/google/zip_reader.cc b/deps/zlib/google/zip_reader.cc index eb3adcaee35c0b..88f075ec7739a6 100644 --- a/deps/zlib/google/zip_reader.cc +++ b/deps/zlib/google/zip_reader.cc @@ -5,11 +5,14 @@ #include "third_party/zlib/google/zip_reader.h" #include +#include #include #include #include "base/check.h" +#include "base/containers/span.h" #include "base/containers/heap_array.h" +#include "base/strings/string_view_util.h" #include "base/files/file.h" #include "base/files/file_util.h" #include "base/functional/bind.h" @@ -86,8 +89,8 @@ class StringWriterDelegate : public WriterDelegate { explicit StringWriterDelegate(std::string* output) : output_(output) {} // WriterDelegate methods: - bool WriteBytes(const char* data, int num_bytes) override { - output_->append(data, num_bytes); + bool WriteBytes(base::span data) override { + *output_ += base::as_string_view(data); return true; } @@ -485,8 +488,10 @@ bool ZipReader::ExtractCurrentEntry(WriterDelegate* delegate, uint64_t num_bytes_to_write = std::min( remaining_capacity, base::checked_cast(num_bytes_read)); - if (!delegate->WriteBytes(buf, num_bytes_to_write)) + if (!delegate->WriteBytes(base::as_byte_span(buf).first( + base::checked_cast(num_bytes_to_write)))) { break; + } if (remaining_capacity == base::checked_cast(num_bytes_read)) { // Ensures function returns true if the entire file has been read. @@ -679,7 +684,9 @@ void ZipReader::ExtractChunk(base::File output_file, return; } - if (num_bytes_read != output_file.Write(offset, buffer, num_bytes_read)) { + if (!output_file.WriteAndCheck( + offset, base::as_byte_span(buffer).first( + static_cast(num_bytes_read)))) { LOG(ERROR) << "Cannot write " << num_bytes_read << " bytes to file at offset " << offset; std::move(failure_callback).Run(); @@ -734,11 +741,12 @@ bool FileWriterDelegate::PrepareOutput() { return true; } -bool FileWriterDelegate::WriteBytes(const char* data, int num_bytes) { - int bytes_written = file_->WriteAtCurrentPos(data, num_bytes); - if (bytes_written > 0) - file_length_ += bytes_written; - return bytes_written == num_bytes; +bool FileWriterDelegate::WriteBytes(base::span data) { + const std::optional bytes_written = file_->WriteAtCurrentPos(data); + if (bytes_written > 0) { + file_length_ += *bytes_written; + } + return bytes_written == data.size(); } void FileWriterDelegate::SetTimeModified(const base::Time& time) { diff --git a/deps/zlib/google/zip_reader.h b/deps/zlib/google/zip_reader.h index 26c4f716c14cf2..8bc4a21d27c344 100644 --- a/deps/zlib/google/zip_reader.h +++ b/deps/zlib/google/zip_reader.h @@ -12,6 +12,7 @@ #include #include +#include "base/containers/span.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/functional/callback.h" @@ -39,7 +40,7 @@ class WriterDelegate { // Invoked to write the next chunk of data. Return false on failure to cancel // extraction. - virtual bool WriteBytes(const char* data, int num_bytes) { return true; } + virtual bool WriteBytes(base::span data) { return true; } // Sets the last-modified time of the data. virtual void SetTimeModified(const base::Time& time) {} @@ -377,9 +378,9 @@ class FileWriterDelegate : public WriterDelegate { // Returns true if the file handle passed to the constructor is valid. bool PrepareOutput() override; - // Writes |num_bytes| bytes of |data| to the file, returning false on error or - // if not all bytes could be written. - bool WriteBytes(const char* data, int num_bytes) override; + // Writes |data| to the file, returning false on error or if not all bytes + // could be written. + bool WriteBytes(base::span data) override; // Sets the last-modified time of the data. void SetTimeModified(const base::Time& time) override; diff --git a/deps/zlib/google/zip_reader_unittest.cc b/deps/zlib/google/zip_reader_unittest.cc index 10ad64b4ce9b24..7a9f24b434ec20 100644 --- a/deps/zlib/google/zip_reader_unittest.cc +++ b/deps/zlib/google/zip_reader_unittest.cc @@ -119,7 +119,7 @@ class MockUnzipListener final { class MockWriterDelegate : public zip::WriterDelegate { public: MOCK_METHOD0(PrepareOutput, bool()); - MOCK_METHOD2(WriteBytes, bool(const char*, int)); + MOCK_METHOD1(WriteBytes, bool(base::span)); MOCK_METHOD1(SetTimeModified, void(const base::Time&)); MOCK_METHOD1(SetPosixFilePermissions, void(int)); MOCK_METHOD0(OnError, void()); @@ -896,7 +896,7 @@ TEST_F(ZipReaderTest, ExtractCurrentEntryWriteBytesFailure) { testing::StrictMock mock_writer; EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(true)); - EXPECT_CALL(mock_writer, WriteBytes(_, _)).WillOnce(Return(false)); + EXPECT_CALL(mock_writer, WriteBytes).WillOnce(Return(false)); EXPECT_CALL(mock_writer, OnError()); base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); @@ -912,7 +912,7 @@ TEST_F(ZipReaderTest, ExtractCurrentEntrySuccess) { testing::StrictMock mock_writer; EXPECT_CALL(mock_writer, PrepareOutput()).WillOnce(Return(true)); - EXPECT_CALL(mock_writer, WriteBytes(_, _)).WillRepeatedly(Return(true)); + EXPECT_CALL(mock_writer, WriteBytes).WillRepeatedly(Return(true)); EXPECT_CALL(mock_writer, SetPosixFilePermissions(_)); EXPECT_CALL(mock_writer, SetTimeModified(_)); @@ -1002,7 +1002,7 @@ TEST_F(FileWriterDelegateTest, WriteToEnd) { FileWriterDelegate writer(&file_); EXPECT_EQ(0, writer.file_length()); ASSERT_TRUE(writer.PrepareOutput()); - ASSERT_TRUE(writer.WriteBytes(payload.data(), payload.size())); + ASSERT_TRUE(writer.WriteBytes(base::as_byte_span(payload))); EXPECT_EQ(payload.size(), writer.file_length()); } @@ -1016,7 +1016,7 @@ TEST_F(FileWriterDelegateTest, EmptyOnError) { FileWriterDelegate writer(&file_); EXPECT_EQ(0, writer.file_length()); ASSERT_TRUE(writer.PrepareOutput()); - ASSERT_TRUE(writer.WriteBytes(payload.data(), payload.size())); + ASSERT_TRUE(writer.WriteBytes(base::as_byte_span(payload))); EXPECT_EQ(payload.size(), writer.file_length()); EXPECT_EQ(payload.size(), file_.GetLength()); writer.OnError(); diff --git a/deps/zlib/google/zip_unittest.cc b/deps/zlib/google/zip_unittest.cc index 494ffed2d297d8..4b037bf8dae705 100644 --- a/deps/zlib/google/zip_unittest.cc +++ b/deps/zlib/google/zip_unittest.cc @@ -15,6 +15,7 @@ #include #include +#include "base/containers/span.h" #include "base/files/file.h" #include "base/files/file_enumerator.h" #include "base/files/file_path.h" @@ -81,8 +82,8 @@ class ProgressWriterDelegate : public zip::WriterDelegate { CHECK_GT(expected_size_, 0); } - bool WriteBytes(const char* data, int num_bytes) override { - received_bytes_ += num_bytes; + bool WriteBytes(base::span data) override { + received_bytes_ += data.size(); LogProgressIfNecessary(); return true; } diff --git a/deps/zlib/google/zip_writer.cc b/deps/zlib/google/zip_writer.cc index 34ab0ad9ef2887..291e34ae9dab87 100644 --- a/deps/zlib/google/zip_writer.cc +++ b/deps/zlib/google/zip_writer.cc @@ -7,8 +7,10 @@ #include #include +#include "base/containers/span.h" #include "base/files/file.h" #include "base/logging.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "third_party/zlib/google/redact.h" @@ -34,27 +36,29 @@ bool ZipWriter::ShouldContinue() { } bool ZipWriter::AddFileContent(const base::FilePath& path, base::File file) { - char buf[zip::internal::kZipBufSize]; + uint8_t buf[zip::internal::kZipBufSize]; while (ShouldContinue()) { - const int num_bytes = - file.ReadAtCurrentPos(buf, zip::internal::kZipBufSize); + const std::optional num_bytes = file.ReadAtCurrentPos(buf); - if (num_bytes < 0) { + if (!num_bytes) { PLOG(ERROR) << "Cannot read file " << Redact(path); return false; } - if (num_bytes == 0) + if (*num_bytes == 0) { return true; + } - if (zipWriteInFileInZip(zip_file_, buf, num_bytes) != ZIP_OK) { + if (zipWriteInFileInZip(zip_file_, buf, + base::checked_cast(*num_bytes)) != + ZIP_OK) { PLOG(ERROR) << "Cannot write data from file " << Redact(path) << " to ZIP"; return false; } - progress_.bytes += num_bytes; + progress_.bytes += *num_bytes; } return false; diff --git a/deps/zlib/patches/0019-fix-zip64-in-zip.patch b/deps/zlib/patches/0019-fix-zip64-in-zip.patch new file mode 100644 index 00000000000000..26b8528645af75 --- /dev/null +++ b/deps/zlib/patches/0019-fix-zip64-in-zip.patch @@ -0,0 +1,37 @@ +diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c +index b77b787ccc0db..78663ec2d53a8 100644 +--- a/third_party/zlib/contrib/minizip/unzip.c ++++ b/third_party/zlib/contrib/minizip/unzip.c +@@ -444,12 +444,28 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + +- for (i=(int)uReadSize-3; (i--)>0;) ++ /* Search for the non-zip64 EoCDR and confirm zip64 EoCDL is 20 bytes ++ earlier. This avoids false positives if the file is a non-zip64 zip ++ but contains an uncompressed zip64 near its end. Note: zip64 EoCDL is ++ 20 bytes long. */ ++ for (i=(int)uReadSize-3; (i--)>20;) ++ // End of central directory record signature (PK\5\6) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && +- ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) ++ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { +- uPosFound = uReadPos+(unsigned)i; +- break; ++ // Zip64 end of central directory locator signature (PK\6\7) ++ if (((*(buf+i-20))==0x50) && ((*(buf+i+1-20))==0x4b) && ++ ((*(buf+i+2-20))==0x06) && ((*(buf+i+3-20))==0x07)) ++ { ++ uPosFound = uReadPos+(unsigned)i-20; ++ break; ++ } ++ else ++ { ++ /* This is a non-zip64 zip; abandon the search. */ ++ free(buf); ++ return CENTRALDIRINVALID; ++ } + } + + if (uPosFound!=CENTRALDIRINVALID) diff --git a/src/zlib_version.h b/src/zlib_version.h index 7ce58e3077bade..81dfb6ef49b06f 100644 --- a/src/zlib_version.h +++ b/src/zlib_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-zlib.sh #ifndef SRC_ZLIB_VERSION_H_ #define SRC_ZLIB_VERSION_H_ -#define ZLIB_VERSION "1.3.1-e00f703" +#define ZLIB_VERSION "1.3.1-7eda07b" #endif // SRC_ZLIB_VERSION_H_