zlib: support Uint8Array in convenience methods · nodejs/node@91383e4 · GitHub
Skip to content

Commit 91383e4

Browse files
TimothyGuaddaleax
authored andcommitted
zlib: support Uint8Array in convenience methods
Also support Uint8Array as a `dictionary` option. PR-URL: #12001 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent 2d039ff commit 91383e4

6 files changed

Lines changed: 176 additions & 87 deletions

File tree

doc/api/zlib.md

Lines changed: 107 additions & 32 deletions

lib/zlib.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
const Buffer = require('buffer').Buffer;
2525
const internalUtil = require('internal/util');
2626
const Transform = require('_stream_transform');
27+
const { isUint8Array } = process.binding('util');
2728
const binding = process.binding('zlib');
2829
const assert = require('assert').ok;
2930
const kMaxLength = require('buffer').kMaxLength;
@@ -78,6 +79,13 @@ function isInvalidStrategy(strategy) {
7879
}
7980

8081
function zlibBuffer(engine, buffer, callback) {
82+
// Streams do not support non-Buffer Uint8Arrays yet. Convert it to a
83+
// Buffer without copying.
84+
if (isUint8Array(buffer) &&
85+
Object.getPrototypeOf(buffer) !== Buffer.prototype) {
86+
buffer = Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength);
87+
}
88+
8189
var buffers = [];
8290
var nread = 0;
8391

@@ -121,8 +129,9 @@ function zlibBuffer(engine, buffer, callback) {
121129
function zlibBufferSync(engine, buffer) {
122130
if (typeof buffer === 'string')
123131
buffer = Buffer.from(buffer);
124-
if (!(buffer instanceof Buffer))
125-
throw new TypeError('Not a string or buffer');
132+
else if (!isUint8Array(buffer))
133+
throw new TypeError('"buffer" argument must be a string, Buffer, or ' +
134+
'Uint8Array');
126135

127136
var flushFlag = engine._finishFlushFlag;
128137

@@ -205,9 +214,9 @@ class Zlib extends Transform {
205214
throw new TypeError('Invalid strategy: ' + opts.strategy);
206215

207216
if (opts.dictionary) {
208-
if (!(opts.dictionary instanceof Buffer)) {
217+
if (!isUint8Array(opts.dictionary)) {
209218
throw new TypeError(
210-
'Invalid dictionary: it should be a Buffer instance');
219+
'Invalid dictionary: it should be a Buffer or an Uint8Array');
211220
}
212221
}
213222

@@ -302,7 +311,7 @@ class Zlib extends Transform {
302311
var ending = ws.ending || ws.ended;
303312
var last = ending && (!chunk || ws.length === chunk.length);
304313

305-
if (chunk !== null && !(chunk instanceof Buffer))
314+
if (chunk !== null && !isUint8Array(chunk))
306315
return cb(new TypeError('invalid input'));
307316

308317
if (!this._handle)

test/parallel/test-zlib-convenience-methods.js

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,59 +22,60 @@
2222
'use strict';
2323
// test convenience methods with and without options supplied
2424

25-
require('../common');
25+
const common = require('../common');
2626
const assert = require('assert');
2727
const zlib = require('zlib');
2828

29-
let hadRun = 0;
30-
31-
const expect = 'blahblahblahblahblahblah';
29+
const expectStr = 'blahblahblahblahblahblah';
30+
const expectBuf = Buffer.from(expectStr);
31+
const expectUint8Array = new Uint8Array(expectBuf);
3232
const opts = {
3333
level: 9,
3434
chunkSize: 1024,
3535
};
3636

37-
[
37+
for (const method of [
3838
['gzip', 'gunzip'],
3939
['gzip', 'unzip'],
4040
['deflate', 'inflate'],
4141
['deflateRaw', 'inflateRaw'],
42-
].forEach(function(method) {
43-
44-
zlib[method[0]](expect, opts, function(err, result) {
45-
zlib[method[1]](result, opts, function(err, result) {
46-
assert.strictEqual(result.toString(), expect,
47-
'Should get original string after ' +
48-
method[0] + '/' + method[1] + ' with options.');
49-
hadRun++;
50-
});
51-
});
52-
53-
zlib[method[0]](expect, function(err, result) {
54-
zlib[method[1]](result, function(err, result) {
55-
assert.strictEqual(result.toString(), expect,
56-
'Should get original string after ' +
57-
method[0] + '/' + method[1] + ' without options.');
58-
hadRun++;
59-
});
60-
});
42+
]) {
43+
for (const [type, expect] of [
44+
['string', expectStr],
45+
['Buffer', expectBuf],
46+
['Uint8Array', expectUint8Array]
47+
]) {
48+
zlib[method[0]](expect, opts, common.mustCall((err, result) => {
49+
zlib[method[1]](result, opts, common.mustCall((err, result) => {
50+
assert.strictEqual(result.toString(), expectStr,
51+
`Should get original string after ${method[0]}/` +
52+
`${method[1]} ${type} with options.`);
53+
}));
54+
}));
6155

62-
let result = zlib[method[0] + 'Sync'](expect, opts);
63-
result = zlib[method[1] + 'Sync'](result, opts);
64-
assert.strictEqual(result.toString(), expect,
65-
'Should get original string after ' +
66-
method[0] + '/' + method[1] + ' with options.');
67-
hadRun++;
56+
zlib[method[0]](expect, common.mustCall((err, result) => {
57+
zlib[method[1]](result, common.mustCall((err, result) => {
58+
assert.strictEqual(result.toString(), expectStr,
59+
`Should get original string after ${method[0]}/` +
60+
`${method[1]} ${type} without options.`);
61+
}));
62+
}));
6863

69-
result = zlib[method[0] + 'Sync'](expect);
70-
result = zlib[method[1] + 'Sync'](result);
71-
assert.strictEqual(result.toString(), expect,
72-
'Should get original string after ' +
73-
method[0] + '/' + method[1] + ' without options.');
74-
hadRun++;
64+
{
65+
const compressed = zlib[method[0] + 'Sync'](expect, opts);
66+
const decompressed = zlib[method[1] + 'Sync'](compressed, opts);
67+
assert.strictEqual(decompressed.toString(), expectStr,
68+
`Should get original string after ${method[0]}Sync/` +
69+
`${method[1]}Sync ${type} with options.`);
70+
}
7571

76-
});
7772

78-
process.on('exit', function() {
79-
assert.strictEqual(hadRun, 16, 'expect 16 compressions');
80-
});
73+
{
74+
const compressed = zlib[method[0] + 'Sync'](expect);
75+
const decompressed = zlib[method[1] + 'Sync'](compressed);
76+
assert.strictEqual(decompressed.toString(), expectStr,
77+
`Should get original string after ${method[0]}Sync/` +
78+
`${method[1]}Sync ${type} without options.`);
79+
}
80+
}
81+
}

test/parallel/test-zlib-deflate-constructors.js

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)