Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix zlib error messages #2673

Merged
merged 1 commit into from
Sep 9, 2024
Merged
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
13 changes: 9 additions & 4 deletions src/workerd/api/node/tests/zlib-nodejs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,9 @@ export const testZeroWindowBits = {
assert.throws(() => zlib.createGzip({ windowBits: 0 }), {
code: 'ERR_OUT_OF_RANGE',
name: 'RangeError',
message:
'The value of "options.windowBits" is out of range. ' +
'It must be >= 9 and <= 15. Received 0',
});
},
};
Expand Down Expand Up @@ -2301,8 +2304,9 @@ export const brotli = {
{
//code: 'ERR_OUT_OF_RANGE',
name: 'RangeError',
//message: 'The value of "options.flush" is out of range. It must be >= 0 ' +
// 'and <= 3. Received 4',
message:
'The value of "options.flush" is out of range. It must be >= 0 ' +
'and <= 3. Received 4',
}
);

Expand All @@ -2315,8 +2319,9 @@ export const brotli = {
{
//code: 'ERR_OUT_OF_RANGE',
name: 'RangeError',
//message: 'The value of "options.finishFlush" is out of range. It must be ' +
// '>= 0 and <= 3. Received 4',
message:
'The value of "options.finishFlush" is out of range. It must be ' +
'>= 0 and <= 3. Received 4',
}
);
}
Expand Down
42 changes: 29 additions & 13 deletions src/workerd/api/node/zlib-util.c++
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,17 @@ void ZlibContext::initialize(int _level,
jsg::Optional<kj::Array<kj::byte>> _dictionary) {
if (!((_windowBits == 0) &&
(mode == ZlibMode::INFLATE || mode == ZlibMode::GUNZIP || mode == ZlibMode::UNZIP))) {
JSG_ASSERT(_windowBits >= Z_MIN_WINDOWBITS && _windowBits <= Z_MAX_WINDOWBITS, Error,
"Invalid windowBits"_kj);
JSG_ASSERT(_windowBits >= Z_MIN_WINDOWBITS && _windowBits <= Z_MAX_WINDOWBITS, RangeError,
kj::str("The value of \"options.windowBits\" is out of range. It must be >= ",
Z_MIN_WINDOWBITS, " and <= ", Z_MAX_WINDOWBITS, ". Received ", _windowBits));
}

JSG_REQUIRE(
_level >= Z_MIN_LEVEL && _level <= Z_MAX_LEVEL, Error, "Invalid compression level"_kj);
JSG_REQUIRE(
_memLevel >= Z_MIN_MEMLEVEL && _memLevel <= Z_MAX_MEMLEVEL, Error, "Invalid memlevel"_kj);
JSG_REQUIRE(_level >= Z_MIN_LEVEL && _level <= Z_MAX_LEVEL, RangeError,
kj::str("The value of \"options.level\" is out of range. It must be >= ", Z_MIN_LEVEL,
" and <= ", Z_MAX_LEVEL, ". Received ", _level));
JSG_REQUIRE(_memLevel >= Z_MIN_MEMLEVEL && _memLevel <= Z_MAX_MEMLEVEL, RangeError,
kj::str("The value of \"options.memLevel\" is out of range. It must be >= ", Z_MIN_MEMLEVEL,
" and <= ", Z_MAX_MEMLEVEL, ". Received ", _memLevel));
JSG_REQUIRE(_strategy == Z_FILTERED || _strategy == Z_HUFFMAN_ONLY || _strategy == Z_RLE ||
_strategy == Z_FIXED || _strategy == Z_DEFAULT_STRATEGY,
Error, "invalid strategy"_kj);
Expand Down Expand Up @@ -876,20 +879,25 @@ kj::Array<kj::byte> ZlibUtil::zlibSync(
auto maxOutputLength = opts.maxOutputLength.orDefault(Z_MAX_CHUNK);

// TODO(soon): Extend JSG_REQUIRE so we can pass the full level of info NodeJS provides, like the code field
JSG_REQUIRE(Z_MIN_CHUNK <= chunkSize && chunkSize <= Z_MAX_CHUNK, Error, "Invalid chunkSize"_kj);
JSG_REQUIRE(maxOutputLength <= Z_MAX_CHUNK, Error, "Invalid maxOutputLength"_kj);
JSG_REQUIRE(Z_MIN_CHUNK <= chunkSize && chunkSize <= Z_MAX_CHUNK, RangeError,
kj::str("The value of \"options.chunkSize\" is out of range. It must be >= ", Z_MIN_CHUNK,
" and <= ", Z_MAX_CHUNK, ". Received ", chunkSize));
JSG_REQUIRE(maxOutputLength <= Z_MAX_CHUNK, RangeError, "Invalid maxOutputLength"_kj);
GrowableBuffer result(ZLIB_PERFORMANT_CHUNK_SIZE, maxOutputLength);

ctx.initialize(opts.level.orDefault(Z_DEFAULT_LEVEL),
opts.windowBits.orDefault(Z_DEFAULT_WINDOWBITS), opts.memLevel.orDefault(Z_DEFAULT_MEMLEVEL),
opts.strategy.orDefault(Z_DEFAULT_STRATEGY), kj::mv(opts.dictionary));

auto flush = opts.flush.orDefault(Z_NO_FLUSH);
JSG_REQUIRE(Z_NO_FLUSH <= flush && flush <= Z_TREES, RangeError, "invalid flush value"_kj);
JSG_REQUIRE(Z_NO_FLUSH <= flush && flush <= Z_TREES, RangeError,
kj::str("The value of \"options.flush\" is out of range. It must be >= ", Z_NO_FLUSH,
" and <= ", Z_TREES, ". Received ", flush));

auto finishFlush = opts.finishFlush.orDefault(Z_FINISH);
JSG_REQUIRE(Z_NO_FLUSH <= finishFlush && finishFlush <= Z_TREES, RangeError,
"invalid finishFlush value"_kj);
kj::str("The value of \"options.finishFlush\" is out of range. It must be >= ", Z_NO_FLUSH,
" and <= ", Z_TREES, ". Received ", flush));

ctx.setFlush(finishFlush);
ctx.setInputBuffer(getInputFromSource(data));
Expand Down Expand Up @@ -920,7 +928,9 @@ kj::Array<kj::byte> ZlibUtil::brotliSync(InputSource data, BrotliContext::Option
auto maxOutputLength = opts.maxOutputLength.orDefault(Z_MAX_CHUNK);

// TODO(soon): Extend JSG_REQUIRE so we can pass the full level of info NodeJS provides, like the code field
JSG_REQUIRE(Z_MIN_CHUNK <= chunkSize && chunkSize <= Z_MAX_CHUNK, Error, "Invalid chunkSize"_kj);
JSG_REQUIRE(Z_MIN_CHUNK <= chunkSize && chunkSize <= Z_MAX_CHUNK, RangeError,
kj::str("The value of \"options.chunkSize\" is out of range. It must be >= ", Z_MIN_CHUNK,
" and <= ", Z_MAX_CHUNK, ". Received ", chunkSize));
JSG_REQUIRE(maxOutputLength <= Z_MAX_CHUNK, Error, "Invalid maxOutputLength"_kj);
GrowableBuffer result(ZLIB_PERFORMANT_CHUNK_SIZE, maxOutputLength);

Expand All @@ -939,12 +949,18 @@ kj::Array<kj::byte> ZlibUtil::brotliSync(InputSource data, BrotliContext::Option

auto flush = opts.flush.orDefault(BROTLI_OPERATION_PROCESS);
JSG_REQUIRE(BROTLI_OPERATION_PROCESS <= flush && flush <= BROTLI_OPERATION_EMIT_METADATA,
RangeError, "invalid flush value"_kj);
RangeError,
kj::str("The value of \"options.flush\" is out of range. It must be >= ",
BROTLI_OPERATION_PROCESS, " and <= ", BROTLI_OPERATION_EMIT_METADATA, ". Received ",
flush));

auto finishFlush = opts.finishFlush.orDefault(BROTLI_OPERATION_FINISH);
JSG_REQUIRE(
BROTLI_OPERATION_PROCESS <= finishFlush && finishFlush <= BROTLI_OPERATION_EMIT_METADATA,
RangeError, "invalid finishFlush value"_kj);
RangeError,
kj::str("The value of \"options.finishFlush\" is out of range. It must be >= ",
BROTLI_OPERATION_PROCESS, " and <= ", BROTLI_OPERATION_EMIT_METADATA, ". Received ",
finishFlush));

ctx.setFlush(finishFlush);
ctx.setInputBuffer(getInputFromSource(data));
Expand Down