Skip to content

Commit

Permalink
Merge pull request #2608 from cloudflare/yagiz/add-zlib-codes
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig authored Aug 27, 2024
2 parents 8c02685 + 4ca3486 commit 450b591
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 4 deletions.
28 changes: 28 additions & 0 deletions src/node/internal/internal_zlib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ import { isArrayBufferView } from 'node-internal:internal_types';
import { Zlib } from 'node-internal:internal_zlib_base';

const {
CONST_Z_OK,
CONST_Z_STREAM_END,
CONST_Z_NEED_DICT,
CONST_Z_ERRNO,
CONST_Z_STREAM_ERROR,
CONST_Z_DATA_ERROR,
CONST_Z_MEM_ERROR,
CONST_Z_BUF_ERROR,
CONST_Z_VERSION_ERROR,
CONST_DEFLATE,
CONST_DEFLATERAW,
CONST_INFLATE,
Expand Down Expand Up @@ -41,6 +50,25 @@ Object.defineProperties(
)
);

// Translation table for return codes.
const rawCodes: Record<string, number | string> = {
Z_OK: CONST_Z_OK,
Z_STREAM_END: CONST_Z_STREAM_END,
Z_NEED_DICT: CONST_Z_NEED_DICT,
Z_ERRNO: CONST_Z_ERRNO,
Z_STREAM_ERROR: CONST_Z_STREAM_ERROR,
Z_DATA_ERROR: CONST_Z_DATA_ERROR,
Z_MEM_ERROR: CONST_Z_MEM_ERROR,
Z_BUF_ERROR: CONST_Z_BUF_ERROR,
Z_VERSION_ERROR: CONST_Z_VERSION_ERROR,
};

for (const key of Object.keys(rawCodes)) {
rawCodes[rawCodes[key] as number] = key;
}

export const codes = Object.freeze(rawCodes);

export function crc32(
data: ArrayBufferView | string,
value: number = 0
Expand Down
4 changes: 3 additions & 1 deletion src/node/zlib.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as zlib from 'node-internal:internal_zlib';
import { crc32, constants } from 'node-internal:internal_zlib';
import { crc32, constants, codes } from 'node-internal:internal_zlib';
import { default as compatFlags } from 'workerd:compatibility-flags';

const { nodeJsZlib } = compatFlags;
Expand Down Expand Up @@ -31,6 +31,7 @@ const createUnzip = protectMethod(zlib.createUnzip);

export {
crc32,
codes,
constants,

// Classes
Expand All @@ -54,6 +55,7 @@ export {

export default {
crc32,
codes,
constants,

// Classes
Expand Down
107 changes: 104 additions & 3 deletions src/workerd/api/node/tests/zlib-nodejs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,107 @@ export const testZlibBytesRead = {
},
};

// Tests are taken from:
// https://github.com/nodejs/node/blob/3a71ccf6c473357e89be61b26739fd9139dce4db/test/parallel/test-zlib-const.js
export const zlibConst = {
test() {
strictEqual(zlib.constants.Z_OK, 0, 'Expected Z_OK to be 0');
throws(() => {
zlib.constants.Z_OK = 1;
}, /Cannot assign to read only property/);
strictEqual(zlib.constants.Z_OK, 0, 'Z_OK should be immutable');
strictEqual(
zlib.codes.Z_OK,
0,
`Expected Z_OK to be 0; got ${zlib.codes.Z_OK}`
);
throws(() => {
zlib.codes.Z_OK = 1;
}, /Cannot assign to read only property/);
strictEqual(zlib.codes.Z_OK, 0, 'Z_OK should be immutable');
assert(Object.isFrozen(zlib.codes), 'Expected zlib.codes to be frozen');

deepStrictEqual(zlib.codes, {
'-1': 'Z_ERRNO',
'-2': 'Z_STREAM_ERROR',
'-3': 'Z_DATA_ERROR',
'-4': 'Z_MEM_ERROR',
'-5': 'Z_BUF_ERROR',
'-6': 'Z_VERSION_ERROR',
0: 'Z_OK',
1: 'Z_STREAM_END',
2: 'Z_NEED_DICT',
Z_BUF_ERROR: -5,
Z_DATA_ERROR: -3,
Z_ERRNO: -1,
Z_MEM_ERROR: -4,
Z_NEED_DICT: 2,
Z_OK: 0,
Z_STREAM_END: 1,
Z_STREAM_ERROR: -2,
Z_VERSION_ERROR: -6,
});
},
};

// Tests are taken from:
// https://github.com/nodejs/node/blob/3a71ccf6c473357e89be61b26739fd9139dce4db/test/parallel/test-zlib-object-write.js

export const zlibObjectWrite = {
async test() {
const { promise, resolve, reject } = Promise.withResolvers();
const gunzip = new zlib.Gunzip({ objectMode: true });
gunzip.on('error', reject);
assert.throws(
() => {
gunzip.write({});
},
{
name: 'TypeError',
code: 'ERR_INVALID_ARG_TYPE',
}
);
gunzip.on('close', resolve);
gunzip.close();
await promise;
},
};

// Tests are taken from:
// https://github.com/nodejs/node/blob/3a71ccf6c473357e89be61b26739fd9139dce4db/test/parallel/test-zlib-zero-byte.js
export const zlibZeroByte = {
async test() {
// TODO(soon): Add BrotliCompress once it is implemented
for (const Compressor of [zlib.Gzip]) {
const { promise, resolve, reject } = Promise.withResolvers();
let endCalled = false;
const gz = new Compressor();
const emptyBuffer = Buffer.alloc(0);
let received = 0;
gz.on('data', function (c) {
received += c.length;
});

gz.on('end', function () {
const expected = Compressor === zlib.Gzip ? 20 : 1;
assert.strictEqual(
received,
expected,
`${received}, ${expected}, ${Compressor.name}`
);
endCalled = true;
});
gz.on('error', reject);
gz.on('finish', resolve);
gz.write(emptyBuffer);
gz.end();

await promise;
assert(endCalled, 'End should have been called');
}
},
};

// Node.js tests relevant to zlib
//
// - [ ] test-zlib-brotli-16GB.js
Expand Down Expand Up @@ -794,13 +895,13 @@ export const testZlibBytesRead = {
// - [x] test-zlib-bytes-read.js
// - [ ] test-zlib-destroy-pipe.js
// - [ ] test-zlib-from-gzip.js
// - [ ] test-zlib-object-write.js
// - [x] test-zlib-object-write.js
// - [ ] test-zlib-write-after-flush.js
// - [x] test-zlib-close-after-error.js
// - [ ] test-zlib-dictionary-fail.js
// - [ ] test-zlib-from-gzip-with-trailing-garbage.js
// - [ ] test-zlib-params.js
// - [ ] test-zlib-zero-byte.js
// - [x] test-zlib-zero-byte.js
// - [ ] test-zlib-close-after-write.js
// - [ ] test-zlib-dictionary.js
// - [ ] test-zlib-from-string.js
Expand All @@ -810,7 +911,7 @@ export const testZlibBytesRead = {
// - [ ] test-zlib-empty-buffer.js
// - [ ] test-zlib-invalid-arg-value-brotli-compress.js
// - [ ] test-zlib-random-byte-pipes.js
// - [ ] test-zlib-const.js
// - [x] test-zlib-const.js
// - [x] test-zlib-failed-init.js
// - [ ] test-zlib-invalid-input.js
// - [ ] test-zlib-reset-before-write.js

0 comments on commit 450b591

Please sign in to comment.