Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 91383e4

Browse filesBrowse 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
Copy full SHA for 91383e4

File tree

Expand file treeCollapse file tree

6 files changed

+176
-87
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+176
-87
lines changed
Open diff view settings
Collapse file

‎doc/api/zlib.md‎

Copy file name to clipboardExpand all lines: doc/api/zlib.md
+107-32Lines changed: 107 additions & 32 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,9 @@ Compression strategy.
278278
<!-- YAML
279279
added: v0.11.1
280280
changes:
281+
- version: REPLACEME
282+
pr-url: https://github.com/nodejs/node/pull/12001
283+
description: The `dictionary` option can be an Uint8Array now.
281284
- version: v5.11.0
282285
pr-url: https://github.com/nodejs/node/pull/6069
283286
description: The `finishFlush` option is supported now.
@@ -290,14 +293,15 @@ Each class takes an `options` object. All options are optional.
290293
Note that some options are only relevant when compressing, and are
291294
ignored by the decompression classes.
292295

293-
* `flush` (default: `zlib.constants.Z_NO_FLUSH`)
294-
* `finishFlush` (default: `zlib.constants.Z_FINISH`)
295-
* `chunkSize` (default: 16*1024)
296-
* `windowBits`
297-
* `level` (compression only)
298-
* `memLevel` (compression only)
299-
* `strategy` (compression only)
300-
* `dictionary` (deflate/inflate only, empty dictionary by default)
296+
* `flush` {integer} (default: `zlib.constants.Z_NO_FLUSH`)
297+
* `finishFlush` {integer} (default: `zlib.constants.Z_FINISH`)
298+
* `chunkSize` {integer} (default: 16\*1024)
299+
* `windowBits` {integer}
300+
* `level` {integer} (compression only)
301+
* `memLevel` {integer} (compression only)
302+
* `strategy` {integer} (compression only)
303+
* `dictionary` {Buffer|Uint8Array} (deflate/inflate only, empty dictionary by
304+
default)
301305

302306
See the description of `deflateInit2` and `inflateInit2` at
303307
<http://zlib.net/manual.html#Advanced> for more information on these.
@@ -473,89 +477,159 @@ Returns a new [Unzip][] object with an [options][].
473477

474478
<!--type=misc-->
475479

476-
All of these take a [Buffer][] or string as the first argument, an optional
477-
second argument to supply options to the `zlib` classes and will call the
478-
supplied callback with `callback(error, result)`.
480+
All of these take a [Buffer][], [Uint8Array][], or string as the first
481+
argument, an optional second argument to supply options to the `zlib` classes
482+
and will call the supplied callback with `callback(error, result)`.
479483

480484
Every method has a `*Sync` counterpart, which accept the same arguments, but
481485
without a callback.
482486

483-
### zlib.deflate(buf[, options], callback)
487+
### zlib.deflate(buffer[, options], callback)
484488
<!-- YAML
485489
added: v0.6.0
490+
changes:
491+
- version: REPLACEME
492+
pr-url: https://github.com/nodejs/node/pull/12001
493+
description: The `buffer` parameter can be an Uint8Array now.
486494
-->
487-
### zlib.deflateSync(buf[, options])
495+
### zlib.deflateSync(buffer[, options])
488496
<!-- YAML
489497
added: v0.11.12
498+
changes:
499+
- version: REPLACEME
500+
pr-url: https://github.com/nodejs/node/pull/12001
501+
description: The `buffer` parameter can be an Uint8Array now.
490502
-->
491503

492-
Compress a [Buffer][] or string with [Deflate][].
504+
- `buffer` {Buffer|Uint8Array|string}
505+
506+
Compress a chunk of data with [Deflate][].
493507

494-
### zlib.deflateRaw(buf[, options], callback)
508+
### zlib.deflateRaw(buffer[, options], callback)
495509
<!-- YAML
496510
added: v0.6.0
511+
changes:
512+
- version: REPLACEME
513+
pr-url: https://github.com/nodejs/node/pull/12001
514+
description: The `buffer` parameter can be an Uint8Array now.
497515
-->
498-
### zlib.deflateRawSync(buf[, options])
516+
### zlib.deflateRawSync(buffer[, options])
499517
<!-- YAML
500518
added: v0.11.12
519+
changes:
520+
- version: REPLACEME
521+
pr-url: https://github.com/nodejs/node/pull/12001
522+
description: The `buffer` parameter can be an Uint8Array now.
501523
-->
502524

503-
Compress a [Buffer][] or string with [DeflateRaw][].
525+
- `buffer` {Buffer|Uint8Array|string}
526+
527+
Compress a chunk of data with [DeflateRaw][].
504528

505-
### zlib.gunzip(buf[, options], callback)
529+
### zlib.gunzip(buffer[, options], callback)
506530
<!-- YAML
507531
added: v0.6.0
532+
changes:
533+
- version: REPLACEME
534+
pr-url: https://github.com/nodejs/node/pull/12001
535+
description: The `buffer` parameter can be an Uint8Array now.
508536
-->
509-
### zlib.gunzipSync(buf[, options])
537+
### zlib.gunzipSync(buffer[, options])
510538
<!-- YAML
511539
added: v0.11.12
540+
changes:
541+
- version: REPLACEME
542+
pr-url: https://github.com/nodejs/node/pull/12001
543+
description: The `buffer` parameter can be an Uint8Array now.
512544
-->
513545

514-
Decompress a [Buffer][] or string with [Gunzip][].
546+
- `buffer` {Buffer|Uint8Array|string}
547+
548+
Decompress a chunk of data with [Gunzip][].
515549

516-
### zlib.gzip(buf[, options], callback)
550+
### zlib.gzip(buffer[, options], callback)
517551
<!-- YAML
518552
added: v0.6.0
553+
changes:
554+
- version: REPLACEME
555+
pr-url: https://github.com/nodejs/node/pull/12001
556+
description: The `buffer` parameter can be an Uint8Array now.
519557
-->
520-
### zlib.gzipSync(buf[, options])
558+
### zlib.gzipSync(buffer[, options])
521559
<!-- YAML
522560
added: v0.11.12
561+
changes:
562+
- version: REPLACEME
563+
pr-url: https://github.com/nodejs/node/pull/12001
564+
description: The `buffer` parameter can be an Uint8Array now.
523565
-->
524566

525-
Compress a [Buffer][] or string with [Gzip][].
567+
- `buffer` {Buffer|Uint8Array|string}
526568

527-
### zlib.inflate(buf[, options], callback)
569+
Compress a chunk of data with [Gzip][].
570+
571+
### zlib.inflate(buffer[, options], callback)
528572
<!-- YAML
529573
added: v0.6.0
574+
changes:
575+
- version: REPLACEME
576+
pr-url: https://github.com/nodejs/node/pull/12001
577+
description: The `buffer` parameter can be an Uint8Array now.
530578
-->
531-
### zlib.inflateSync(buf[, options])
579+
### zlib.inflateSync(buffer[, options])
532580
<!-- YAML
533581
added: v0.11.12
582+
changes:
583+
- version: REPLACEME
584+
pr-url: https://github.com/nodejs/node/pull/12001
585+
description: The `buffer` parameter can be an Uint8Array now.
534586
-->
535587

536-
Decompress a [Buffer][] or string with [Inflate][].
588+
- `buffer` {Buffer|Uint8Array|string}
537589

538-
### zlib.inflateRaw(buf[, options], callback)
590+
Decompress a chunk of data with [Inflate][].
591+
592+
### zlib.inflateRaw(buffer[, options], callback)
539593
<!-- YAML
540594
added: v0.6.0
595+
changes:
596+
- version: REPLACEME
597+
pr-url: https://github.com/nodejs/node/pull/12001
598+
description: The `buffer` parameter can be an Uint8Array now.
541599
-->
542-
### zlib.inflateRawSync(buf[, options])
600+
### zlib.inflateRawSync(buffer[, options])
543601
<!-- YAML
544602
added: v0.11.12
603+
changes:
604+
- version: REPLACEME
605+
pr-url: https://github.com/nodejs/node/pull/12001
606+
description: The `buffer` parameter can be an Uint8Array now.
545607
-->
546608

547-
Decompress a [Buffer][] or string with [InflateRaw][].
609+
- `buffer` {Buffer|Uint8Array|string}
610+
611+
Decompress a chunk of data with [InflateRaw][].
548612

549-
### zlib.unzip(buf[, options], callback)
613+
### zlib.unzip(buffer[, options], callback)
550614
<!-- YAML
551615
added: v0.6.0
616+
changes:
617+
- version: REPLACEME
618+
pr-url: https://github.com/nodejs/node/pull/12001
619+
description: The `buffer` parameter can be an Uint8Array now.
552620
-->
553-
### zlib.unzipSync(buf[, options])
621+
### zlib.unzipSync(buffer[, options])
554622
<!-- YAML
555623
added: v0.11.12
624+
changes:
625+
- version: REPLACEME
626+
pr-url: https://github.com/nodejs/node/pull/12001
627+
description: The `buffer` parameter can be an Uint8Array now.
556628
-->
557629

558-
Decompress a [Buffer][] or string with [Unzip][].
630+
- `buffer` {Buffer|Uint8Array|string}
631+
632+
Decompress a chunk of data with [Unzip][].
559633

560634
[`Accept-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
561635
[`Content-Encoding`]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11
@@ -571,3 +645,4 @@ Decompress a [Buffer][] or string with [Unzip][].
571645
[Unzip]: #zlib_class_zlib_unzip
572646
[`.flush()`]: #zlib_zlib_flush_kind_callback
573647
[Buffer]: buffer.html
648+
[Uint8Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
Collapse file

‎lib/zlib.js‎

Copy file name to clipboardExpand all lines: lib/zlib.js
+14-5Lines 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)
Collapse file

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

Copy file name to clipboardExpand all lines: test/parallel/test-zlib-convenience-methods.js
+41-40Lines 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+
}
Collapse file

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

Copy file name to clipboardExpand all lines: test/parallel/test-zlib-deflate-constructors.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,5 @@ assert.throws(
107107
// Throws if opts.dictionary is not a Buffer
108108
assert.throws(
109109
() => { new zlib.Deflate({dictionary: 'not a buffer'}); },
110-
/^TypeError: Invalid dictionary: it should be a Buffer instance$/
110+
/^TypeError: Invalid dictionary: it should be a Buffer or an Uint8Array$/
111111
);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.