deps: update zlib to 1.3.1-363a126

This commit is contained in:
nodejs-github-bot 2025-08-10 00:42:35 +00:00 committed by github-actions[bot]
parent a93c1c0aa5
commit b17549d4e0
11 changed files with 287 additions and 65 deletions

2
deps/zlib/BUILD.gn vendored
View file

@ -419,7 +419,7 @@ static_library("minizip") {
] ]
} }
if (is_apple || is_android || is_nacl) { if (is_apple || is_android) {
# Mac, Android and the BSDs don't have fopen64, ftello64, or fseeko64. We # Mac, Android and the BSDs don't have fopen64, ftello64, or fseeko64. We
# use fopen, ftell, and fseek instead on these systems. # use fopen, ftell, and fseek instead on these systems.
defines = [ "USE_FILE32API" ] defines = [ "USE_FILE32API" ]

View file

@ -3,6 +3,7 @@ Short Name: zlib
URL: http://zlib.net/ URL: http://zlib.net/
Version: 1.3.1 Version: 1.3.1
Revision: 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf Revision: 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf
Update Mechanism: Manual
CPEPrefix: cpe:/a:zlib:zlib:1.3.1 CPEPrefix: cpe:/a:zlib:zlib:1.3.1
Security Critical: yes Security Critical: yes
Shipped: yes Shipped: yes

View file

@ -3,6 +3,7 @@ Short Name: minizip
URL: https://github.com/madler/zlib/tree/master/contrib/minizip URL: https://github.com/madler/zlib/tree/master/contrib/minizip
Version: 1.3.1.1 Version: 1.3.1.1
Revision: ef24c4c7502169f016dcd2a26923dbaf3216748c Revision: ef24c4c7502169f016dcd2a26923dbaf3216748c
Update Mechanism: Manual
License: Zlib License: Zlib
License File: //third_party/zlib/LICENSE License File: //third_party/zlib/LICENSE
Shipped: yes Shipped: yes

View file

@ -64,6 +64,7 @@
*/ */
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -837,6 +838,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
uLong uMagic; uLong uMagic;
long lSeek=0; long lSeek=0;
uLong uL; uLong uL;
uLong uFileNameCrc;
if (file==NULL) if (file==NULL)
return UNZ_PARAMERROR; return UNZ_PARAMERROR;
@ -908,21 +910,34 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
file_info_internal.offset_curfile = uL; file_info_internal.offset_curfile = uL;
lSeek+=file_info.size_filename; lSeek+=file_info.size_filename;
if ((err==UNZ_OK) && (szFileName!=NULL)) if (err==UNZ_OK)
{ {
uLong uSizeRead ; char szCurrentFileName[UINT16_MAX] = {0};
if (file_info.size_filename<fileNameBufferSize)
{
*(szFileName+file_info.size_filename)='\0';
uSizeRead = file_info.size_filename;
}
else
uSizeRead = fileNameBufferSize;
if ((file_info.size_filename>0) && (fileNameBufferSize>0)) if (file_info.size_filename > 0)
if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) {
if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename)
{
err=UNZ_ERRNO; err=UNZ_ERRNO;
lSeek -= uSizeRead; }
}
uFileNameCrc = crc32(0, (unsigned char*)szCurrentFileName, file_info.size_filename);
if (szFileName != NULL)
{
if (fileNameBufferSize <= file_info.size_filename)
{
memcpy(szFileName, szCurrentFileName, fileNameBufferSize);
}
else
{
memcpy(szFileName, szCurrentFileName, file_info.size_filename);
szFileName[file_info.size_filename] = '\0';
}
}
lSeek -= file_info.size_filename;
} }
// Read extrafield // Read extrafield
@ -1012,7 +1027,15 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
{ {
int version = 0; int version = 0;
if (unz64local_getByte(&s->z_filefunc, s->filestream, &version) != UNZ_OK) if (dataSize < 1 + 4)
{
/* dataSize includes version (1 byte), uCrc (4 bytes), and
* the filename data. If it's too small, fileNameSize below
* would overflow. */
err = UNZ_ERRNO;
break;
}
else if (unz64local_getByte(&s->z_filefunc, s->filestream, &version) != UNZ_OK)
{ {
err = UNZ_ERRNO; err = UNZ_ERRNO;
} }
@ -1025,16 +1048,16 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
} }
else else
{ {
uLong uCrc, uHeaderCrc, fileNameSize; uLong uCrc, fileNameSize;
if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK) if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK)
{ {
err = UNZ_ERRNO; err = UNZ_ERRNO;
} }
uHeaderCrc = crc32(0, (const unsigned char *)szFileName, file_info.size_filename); fileNameSize = dataSize - (1 + 4); /* 1 for version, 4 for uCrc */
fileNameSize = dataSize - (2 * sizeof (short) + 1);
/* Check CRC against file name in the header. */ /* Check CRC against file name in the header. */
if (uHeaderCrc != uCrc) if (uCrc != uFileNameCrc)
{ {
if (ZSEEK64(s->z_filefunc, s->filestream, fileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) if (ZSEEK64(s->z_filefunc, s->filestream, fileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0)
{ {
@ -1043,26 +1066,30 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
} }
else else
{ {
uLong uSizeRead;
file_info.size_filename = fileNameSize; file_info.size_filename = fileNameSize;
if (fileNameSize < fileNameBufferSize) char szCurrentFileName[UINT16_MAX] = {0};
if (file_info.size_filename > 0)
{ {
*(szFileName + fileNameSize) = '\0'; if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename)
uSizeRead = fileNameSize;
}
else
{
uSizeRead = fileNameBufferSize;
}
if ((fileNameSize > 0) && (fileNameBufferSize > 0))
{
if (ZREAD64(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead)
{ {
err = UNZ_ERRNO; err = UNZ_ERRNO;
} }
} }
if (szFileName != NULL)
{
if (fileNameBufferSize <= file_info.size_filename)
{
memcpy(szFileName, szCurrentFileName, fileNameBufferSize);
}
else
{
memcpy(szFileName, szCurrentFileName, file_info.size_filename);
szFileName[file_info.size_filename] = '\0';
}
}
} }
} }
} }

View file

@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <fuzzer/FuzzedDataProvider.h>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <memory>
#include <vector> #include <vector>
#include "unzip.h" #include "unzip.h"
@ -19,11 +21,30 @@
} while (0) } while (0)
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);
unsigned long filename_sz = fdp.ConsumeIntegralInRange(0, UINT16_MAX + 3);
unsigned long extra_sz = fdp.ConsumeIntegralInRange(0, UINT16_MAX + 3);
unsigned long comment_sz = fdp.ConsumeIntegralInRange(0, UINT16_MAX + 3);
std::unique_ptr<char[]> filename;
if (fdp.ConsumeBool()) {
filename = std::make_unique<char[]>(filename_sz);
}
std::unique_ptr<char[]> extra;
if (fdp.ConsumeBool()) {
extra = std::make_unique<char[]>(extra_sz);
}
std::unique_ptr<char[]> comment;
if (fdp.ConsumeBool()) {
comment = std::make_unique<char[]>(comment_sz);
}
// Mock read-only filesystem with only one file, file_data. In the calls // Mock read-only filesystem with only one file, file_data. In the calls
// below, 'opaque' points to file_data, and 'strm' points to the file's seek // below, 'opaque' points to file_data, and 'strm' points to the file's seek
// position, which is heap allocated so that failing to "close" it triggers a // position, which is heap allocated so that failing to "close" it triggers a
// leak error. // leak error.
std::vector<uint8_t> file_data(data, data + size); std::vector<uint8_t> file_data = fdp.ConsumeRemainingBytes<uint8_t>();
zlib_filefunc64_def file_func = { zlib_filefunc64_def file_func = {
.zopen64_file = [](void* opaque, const void* filename, .zopen64_file = [](void* opaque, const void* filename,
int mode) -> void* { int mode) -> void* {
@ -83,19 +104,23 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
while (true) { while (true) {
unz_file_info64 info = {0}; unz_file_info64 info = {0};
// TODO: Pass nullptrs and different buffer sizes to cover more code. if (unzGetCurrentFileInfo64(uzf, &info, filename.get(), filename_sz, extra.get(),
char filename[UINT16_MAX + 1]; // +1 for the null terminator. extra_sz, comment.get(), comment_sz) == UNZ_OK) {
char extra[UINT16_MAX]; // No null terminator. if (filename) {
char comment[UINT16_MAX + 1]; // +1 for the null terminator. ASSERT(info.size_filename <= UINT16_MAX);
if (info.size_filename < filename_sz) {
if (unzGetCurrentFileInfo64(uzf, &info, filename, sizeof(filename), extra, ASSERT(filename[info.size_filename] == '\0');
sizeof(extra), comment, sizeof(comment)) == UNZ_OK) { }
ASSERT(info.size_filename <= UINT16_MAX); }
ASSERT(info.size_file_extra <= UINT16_MAX); if (extra) {
ASSERT(info.size_file_comment <= UINT16_MAX); ASSERT(info.size_file_extra <= UINT16_MAX);
}
ASSERT(filename[info.size_filename] == '\0'); if (comment) {
ASSERT(comment[info.size_file_comment] == '\0'); ASSERT(info.size_file_comment <= UINT16_MAX);
if (info.size_file_comment < comment_sz) {
ASSERT(comment[info.size_file_comment] == '\0');
}
}
} }
if (unzOpenCurrentFile(uzf) == UNZ_OK) { if (unzOpenCurrentFile(uzf) == UNZ_OK) {

View file

@ -13,6 +13,7 @@
#if !defined(CMAKE_STANDALONE_UNITTESTS) #if !defined(CMAKE_STANDALONE_UNITTESTS)
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "third_party/zlib/contrib/minizip/unzip.h" #include "third_party/zlib/contrib/minizip/unzip.h"
#include "third_party/zlib/contrib/minizip/zip.h" #include "third_party/zlib/contrib/minizip/zip.h"
@ -1287,4 +1288,62 @@ TEST(ZlibTest, ZipExtraFieldSize) {
EXPECT_EQ(unzClose(uzf), UNZ_OK); EXPECT_EQ(unzClose(uzf), UNZ_OK);
} }
static base::FilePath TestDataDir() {
base::FilePath path;
bool success = base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &path);
EXPECT_TRUE(success);
return path
.AppendASCII("third_party")
.AppendASCII("zlib")
.AppendASCII("google")
.AppendASCII("test")
.AppendASCII("data");
}
TEST(ZlibTest, ZipUnicodePathExtraSizeFilenameOverflow) {
// This is based on components/test/data/unzip_service/bug953599.zip (added
// in https://crrev.com/1004132), with the Unicode Path Extra Field's
// dataSize hex edited to four.
base::FilePath zip_file = TestDataDir().AppendASCII("unicode_path_extra_overflow.zip");
unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str());
ASSERT_NE(uzf, nullptr);
EXPECT_EQ(unzGoToFirstFile(uzf), UNZ_ERRNO);
EXPECT_EQ(unzClose(uzf), UNZ_OK);
}
TEST(ZlibTest, ZipUnicodePathExtra) {
// This is components/test/data/unzip_service/bug953599.zip (added in
// https://crrev.com/1004132).
base::FilePath zip_file = TestDataDir().AppendASCII("unicode_path_extra.zip");
unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str());
ASSERT_NE(uzf, nullptr);
char long_buf[15], short_buf[3];
unz_file_info file_info;
ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK);
ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, long_buf, sizeof(long_buf),
nullptr, 0, nullptr, 0), UNZ_OK);
ASSERT_EQ(file_info.size_filename, 14);
ASSERT_EQ(std::string(long_buf), "\xec\x83\x88 \xeb\xac\xb8\xec\x84\x9c.txt");
// Even if the file name buffer is too short to hold the whole filename, the
// unicode path extra field should get parsed correctly, size_filename set,
// and the file name buffer should receive the first bytes.
ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK);
ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, short_buf, sizeof(short_buf),
nullptr, 0, nullptr, 0), UNZ_OK);
ASSERT_EQ(file_info.size_filename, 14);
ASSERT_EQ(std::string(short_buf, sizeof(short_buf)), "\xec\x83\x88");
// Also with a null filename buffer, the unicode path extra field should get
// parsed and size_filename set correctly.
ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK);
ASSERT_EQ(unzGetCurrentFileInfo(uzf, &file_info, nullptr, 0, nullptr, 0,
nullptr, 0), UNZ_OK);
ASSERT_EQ(file_info.size_filename, 14);
EXPECT_EQ(unzClose(uzf), UNZ_OK);
}
#endif #endif

Binary file not shown.

Binary file not shown.

View file

@ -37,3 +37,5 @@ test/data/test_encrypted.zip
test/data/test_mismatch_size.zip test/data/test_mismatch_size.zip
test/data/test_nocompress.zip test/data/test_nocompress.zip
test/data/test_posix_permissions.zip test/data/test_posix_permissions.zip
test/data/unicode_path_extra.zip
test/data/unicode_path_extra_overflow.zip

View file

@ -35,10 +35,51 @@ Date: Fri May 16 15:48:19 2025 +0200
Change-Id: Ifab65f470736b45b1b51a1cc130a5753a2b20583 Change-Id: Ifab65f470736b45b1b51a1cc130a5753a2b20583
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6553931 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6553931
commit 9f6e08ef47d3bc9438fdc3b1ab77126a7b36cce9
Author: Hans Wennborg <hans@chromium.org>
Date: Thu Jul 3 17:47:55 2025 +0200
[minizip] Fix Unicode Path Extra Field filename length overflow
If dataSize is too small, fileNameSize would overflow.
Bug: 428744375
Change-Id: I714fc1e30cb1634c31cb97ce87be225518368e57
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6701714
Author: Hans Wennborg <hans@chromium.org>
Date: Fri Jul 11 13:04:30 2025 +0200
[minizip] Fix potential OOB in unicode path extra field parsing
The code needs to compare the CRC of the "regular" filename with the
NameCRC32 value in the unicode path extra field. However, the caller may
not have passed in a szFileName buffer large enough to hold the whole
filename, or indeed any buffer at all.
To fix this, always read the full filename into a temporary buffer, and
compute the CRC on that.
This also simplifies the logic for writing the filename to szFileName,
at the expense of using a small bit of extra memory, which shouldn't be
an issue for our use cases.
Bug: 431119343
Change-Id: Ib06e1009b6e25d2d14e36858385df46d72b7bc3e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6725677
diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c
index c8a01b23efd42..42677cff82c96 100644 index c8a01b23efd42..42677cff82c96 100644
--- a/third_party/zlib/contrib/minizip/unzip.c --- a/third_party/zlib/contrib/minizip/unzip.c
+++ b/third_party/zlib/contrib/minizip/unzip.c +++ b/third_party/zlib/contrib/minizip/unzip.c
@@ -64,6 +64,7 @@
*/
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -193,6 +193,26 @@ typedef struct @@ -193,6 +193,26 @@ typedef struct
Reads a long in LSB order from the given gz_stream. Sets Reads a long in LSB order from the given gz_stream. Sets
*/ */
@ -66,7 +107,61 @@ index c8a01b23efd42..42677cff82c96 100644
local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def,
voidpf filestream, voidpf filestream,
uLong *pX) { uLong *pX) {
@@ -948,6 +968,62 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file, @@ -777,6 +838,7 @@ local int unz64local_GetCurrentFileInfoI
uLong uMagic;
long lSeek=0;
uLong uL;
+ uLong uFileNameCrc;
if (file==NULL)
return UNZ_PARAMERROR;
@@ -848,21 +910,34 @@ local int unz64local_GetCurrentFileInfoI
file_info_internal.offset_curfile = uL;
lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
+ if (err==UNZ_OK)
{
- uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
+ char szCurrentFileName[UINT16_MAX] = {0};
+
+ if (file_info.size_filename > 0)
{
- *(szFileName+file_info.size_filename)='\0';
- uSizeRead = file_info.size_filename;
+ if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename)
+ {
+ err=UNZ_ERRNO;
+ }
}
- else
- uSizeRead = fileNameBufferSize;
- if ((file_info.size_filename>0) && (fileNameBufferSize>0))
- if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek -= uSizeRead;
+ uFileNameCrc = crc32(0, (unsigned char*)szCurrentFileName, file_info.size_filename);
+
+ if (szFileName != NULL)
+ {
+ if (fileNameBufferSize <= file_info.size_filename)
+ {
+ memcpy(szFileName, szCurrentFileName, fileNameBufferSize);
+ }
+ else
+ {
+ memcpy(szFileName, szCurrentFileName, file_info.size_filename);
+ szFileName[file_info.size_filename] = '\0';
+ }
+ }
+
+ lSeek -= file_info.size_filename;
}
// Read extrafield
@@ -948,6 +1023,76 @@ local int unz64local_GetCurrentFileInfoI
} }
} }
@ -74,7 +169,15 @@ index c8a01b23efd42..42677cff82c96 100644
+ { + {
+ int version = 0; + int version = 0;
+ +
+ if (unz64local_getByte(&s->z_filefunc, s->filestream, &version) != UNZ_OK) + if (dataSize < 1 + 4)
+ {
+ /* dataSize includes version (1 byte), uCrc (4 bytes), and
+ * the filename data. If it's too small, fileNameSize below
+ * would overflow. */
+ err = UNZ_ERRNO;
+ break;
+ }
+ else if (unz64local_getByte(&s->z_filefunc, s->filestream, &version) != UNZ_OK)
+ { + {
+ err = UNZ_ERRNO; + err = UNZ_ERRNO;
+ } + }
@ -87,16 +190,16 @@ index c8a01b23efd42..42677cff82c96 100644
+ } + }
+ else + else
+ { + {
+ uLong uCrc, uHeaderCrc, fileNameSize; + uLong uCrc, fileNameSize;
+ +
+ if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK) + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uCrc) != UNZ_OK)
+ { + {
+ err = UNZ_ERRNO; + err = UNZ_ERRNO;
+ } + }
+ uHeaderCrc = crc32(0, (const unsigned char *)szFileName, file_info.size_filename); + fileNameSize = dataSize - (1 + 4); /* 1 for version, 4 for uCrc */
+ fileNameSize = dataSize - (2 * sizeof (short) + 1); +
+ /* Check CRC against file name in the header. */ + /* Check CRC against file name in the header. */
+ if (uHeaderCrc != uCrc) + if (uCrc != uFileNameCrc)
+ { + {
+ if (ZSEEK64(s->z_filefunc, s->filestream, fileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) + if (ZSEEK64(s->z_filefunc, s->filestream, fileNameSize, ZLIB_FILEFUNC_SEEK_CUR) != 0)
+ { + {
@ -105,26 +208,30 @@ index c8a01b23efd42..42677cff82c96 100644
+ } + }
+ else + else
+ { + {
+ uLong uSizeRead;
+
+ file_info.size_filename = fileNameSize; + file_info.size_filename = fileNameSize;
+ +
+ if (fileNameSize < fileNameBufferSize) + char szCurrentFileName[UINT16_MAX] = {0};
+
+ if (file_info.size_filename > 0)
+ { + {
+ *(szFileName + fileNameSize) = '\0'; + if (ZREAD64(s->z_filefunc, s->filestream, szCurrentFileName, file_info.size_filename) != file_info.size_filename)
+ uSizeRead = fileNameSize;
+ }
+ else
+ {
+ uSizeRead = fileNameBufferSize;
+ }
+ if ((fileNameSize > 0) && (fileNameBufferSize > 0))
+ {
+ if (ZREAD64(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead)
+ { + {
+ err = UNZ_ERRNO; + err = UNZ_ERRNO;
+ } + }
+ } + }
+
+ if (szFileName != NULL)
+ {
+ if (fileNameBufferSize <= file_info.size_filename)
+ {
+ memcpy(szFileName, szCurrentFileName, fileNameBufferSize);
+ }
+ else
+ {
+ memcpy(szFileName, szCurrentFileName, file_info.size_filename);
+ szFileName[file_info.size_filename] = '\0';
+ }
+ }
+ } + }
+ } + }
+ } + }

View file

@ -2,5 +2,5 @@
// Refer to tools/dep_updaters/update-zlib.sh // Refer to tools/dep_updaters/update-zlib.sh
#ifndef SRC_ZLIB_VERSION_H_ #ifndef SRC_ZLIB_VERSION_H_
#define SRC_ZLIB_VERSION_H_ #define SRC_ZLIB_VERSION_H_
#define ZLIB_VERSION "1.3.1-470d3a2" #define ZLIB_VERSION "1.3.1-363a126"
#endif // SRC_ZLIB_VERSION_H_ #endif // SRC_ZLIB_VERSION_H_