Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 36 additions & 30 deletions deps/zlib/zlib.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -111,33 +111,41 @@
}],
],
}, # zlib_arm_crc32
# {
# 'target_name': 'zlib_crc32_simd',
# 'type': 'static_library',
# 'conditions': [
# ['OS!="win" or clang==1', {
# 'cflags': [
# '-msse4.2',
# '-mpclmul',
# ],
# 'xcode_settings': {
# 'OTHER_CFLAGS': [
# '-msse4.2',
# '-mpclmul',
# ],
# },
# }]
# ],
# 'defines': [ 'CRC32_SIMD_SSE42_PCLMUL' ],
# 'include_dirs': [ '<(ZLIB_ROOT)' ],
# 'direct_dependent_settings': {
# 'defines': [ 'CRC32_SIMD_SSE42_PCLMUL' ],
# 'include_dirs': [ '<(ZLIB_ROOT)' ],
# },
# 'sources': [
# '<!@pymod_do_main(GN-scraper "<(ZLIB_ROOT)/BUILD.gn" "\\"zlib_crc32_simd\\".*?sources = ")',
# ],
# }, # zlib_crc32_simd
{
'target_name': 'zlib_crc32_simd',
'type': 'static_library',
'conditions': [
['OS!="win" or clang==1', {
'cflags': [
'-msse4.2',
'-mpclmul',
],
'xcode_settings': {
'OTHER_CFLAGS': [
'-msse4.2',
'-mpclmul',
],
},
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': [
'-msse4.2',
'-mpclmul',
],
},
},
}]
],
'defines': [ 'CRC32_SIMD_SSE42_PCLMUL' ],
'include_dirs': [ '<(ZLIB_ROOT)' ],
'direct_dependent_settings': {
'defines': [ 'CRC32_SIMD_SSE42_PCLMUL' ],
'include_dirs': [ '<(ZLIB_ROOT)' ],
},
'sources': [
'<!@pymod_do_main(GN-scraper "<(ZLIB_ROOT)/BUILD.gn" "\\"zlib_crc32_simd\\".*?sources = ")',
],
}, # zlib_crc32_simd
{
'target_name': 'zlib_data_chunk_simd',
'type': 'static_library',
Expand Down Expand Up @@ -212,9 +220,7 @@
['target_arch in "ia32 x64" and OS!="ios"', {
'dependencies': [
'zlib_adler32_simd',
# Disabled due to memory corruption.
# See https://github.com/nodejs/node/issues/45268.
# 'zlib_crc32_simd',
'zlib_crc32_simd',
],
'defines': [ 'DEFLATE_SLIDE_HASH_SSE2' ],
'conditions': [
Expand Down
6 changes: 6 additions & 0 deletions src/node_zlib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2184,6 +2184,12 @@ void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
// The bundled zlib only detects CPU features in deflateInit2() and when
// crc32() or adler32() is called with a NULL buffer. zlib.crc32() always
// passes a buffer, so trigger detection here to let it use the SIMD path
// before any stream has been created.
crc32(0, nullptr, 0);

Environment* env = Environment::GetCurrent(context);

MakeClass<ZlibStream>::Make(env, target, "Zlib");
Expand Down
30 changes: 30 additions & 0 deletions test/parallel/test-zlib-gzip-stored-output-boundary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

// Regression test for https://github.com/nodejs/node/issues/45268.
// With gzip and level 0, deflate_stored() copies input directly into the
// output buffer through the SIMD CRC32 copy routine. An old version of that
// routine stored 16 bytes for the final (len % 16) bytes and wrote past the
// end of the output buffer, corrupting the heap. Exercise output buffers that
// end at every offset modulo 16 and check the round trip.

require('../common');
const assert = require('assert');
const zlib = require('zlib');

for (let i = 0; i < 400; i++) {
const size = 40000 + i * 517;
const input = Buffer.alloc(size, i & 0xff);
for (let j = 0; j < size; j += 97) input[j] = j & 0xff;
const chunkSize = 65536 + (i % 17);
const gz = zlib.gzipSync(input, { level: 0, chunkSize });
assert.deepStrictEqual(zlib.gunzipSync(gz), input);
}

// Small inputs finished straight into a nearly full output buffer.
for (let len = 1; len <= 64; len++) {
const input = Buffer.alloc(len, 0x61);
for (let chunkSize = 64; chunkSize <= 96; chunkSize++) {
const gz = zlib.gzipSync(input, { level: 0, chunkSize });
assert.deepStrictEqual(zlib.gunzipSync(gz), input);
}
}