Skip to content

Commit 2ced07c

Browse files
committed
zlib: support all ArrayBufferView types
PR-URL: #12223 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent a8f460f commit 2ced07c

6 files changed

Lines changed: 89 additions & 43 deletions

File tree

‎doc/api/zlib.md‎

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ ignored by the decompression classes.
300300
*`level` {integer} (compression only)
301301
*`memLevel` {integer} (compression only)
302302
*`strategy` {integer} (compression only)
303-
*`dictionary` {Buffer|Uint8Array} (deflate/inflate only, empty dictionary by
303+
*`dictionary` {Buffer|TypedArray|DataView} (deflate/inflate only, empty dictionary by
304304
default)
305305

306306
See the description of `deflateInit2` and `inflateInit2` at
@@ -477,9 +477,9 @@ Returns a new [Unzip][] object with an [options][].
477477

478478
<!--type=misc-->
479479

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)`.
480+
All of these take a [`Buffer`][], [`TypedArray`][], [`DataView`][], or string as
481+
the first argument, an optional second argument to supply options to the `zlib`
482+
classes and will call the supplied callback with `callback(error, result)`.
483483

484484
Every method has a `*Sync` counterpart, which accept the same arguments, but
485485
without a callback.
@@ -488,6 +488,9 @@ without a callback.
488488
<!-- YAML
489489
added: v0.6.0
490490
changes:
491+
- version: REPLACEME
492+
pr-url: REPLACEME
493+
description: The `buffer` parameter can be any TypedArray or DataView now.
491494
- version: REPLACEME
492495
pr-url: https://github.com/nodejs/node/pull/12001
493496
description: The `buffer` parameter can be an Uint8Array now.
@@ -496,19 +499,25 @@ changes:
496499
<!-- YAML
497500
added: v0.11.12
498501
changes:
502+
- version: REPLACEME
503+
pr-url: REPLACEME
504+
description: The `buffer` parameter can be any TypedArray or DataView now.
499505
- version: REPLACEME
500506
pr-url: https://github.com/nodejs/node/pull/12001
501507
description: The `buffer` parameter can be an Uint8Array now.
502508
-->
503509

504-
-`buffer` {Buffer|Uint8Array|string}
510+
-`buffer` {Buffer|TypedArray|DataView|string}
505511

506512
Compress a chunk of data with [Deflate][].
507513

508514
### zlib.deflateRaw(buffer[, options], callback)
509515
<!-- YAML
510516
added: v0.6.0
511517
changes:
518+
- version: REPLACEME
519+
pr-url: REPLACEME
520+
description: The `buffer` parameter can be any TypedArray or DataView now.
512521
- version: REPLACEME
513522
pr-url: https://github.com/nodejs/node/pull/12001
514523
description: The `buffer` parameter can be an Uint8Array now.
@@ -517,19 +526,25 @@ changes:
517526
<!-- YAML
518527
added: v0.11.12
519528
changes:
529+
- version: REPLACEME
530+
pr-url: REPLACEME
531+
description: The `buffer` parameter can be any TypedArray or DataView now.
520532
- version: REPLACEME
521533
pr-url: https://github.com/nodejs/node/pull/12001
522534
description: The `buffer` parameter can be an Uint8Array now.
523535
-->
524536

525-
-`buffer` {Buffer|Uint8Array|string}
537+
-`buffer` {Buffer|TypedArray|DataView|string}
526538

527539
Compress a chunk of data with [DeflateRaw][].
528540

529541
### zlib.gunzip(buffer[, options], callback)
530542
<!-- YAML
531543
added: v0.6.0
532544
changes:
545+
- version: REPLACEME
546+
pr-url: REPLACEME
547+
description: The `buffer` parameter can be any TypedArray or DataView now.
533548
- version: REPLACEME
534549
pr-url: https://github.com/nodejs/node/pull/12001
535550
description: The `buffer` parameter can be an Uint8Array now.
@@ -538,19 +553,25 @@ changes:
538553
<!-- YAML
539554
added: v0.11.12
540555
changes:
556+
- version: REPLACEME
557+
pr-url: REPLACEME
558+
description: The `buffer` parameter can be any TypedArray or DataView now.
541559
- version: REPLACEME
542560
pr-url: https://github.com/nodejs/node/pull/12001
543561
description: The `buffer` parameter can be an Uint8Array now.
544562
-->
545563

546-
-`buffer` {Buffer|Uint8Array|string}
564+
-`buffer` {Buffer|TypedArray|DataView|string}
547565

548566
Decompress a chunk of data with [Gunzip][].
549567

550568
### zlib.gzip(buffer[, options], callback)
551569
<!-- YAML
552570
added: v0.6.0
553571
changes:
572+
- version: REPLACEME
573+
pr-url: REPLACEME
574+
description: The `buffer` parameter can be any TypedArray or DataView now.
554575
- version: REPLACEME
555576
pr-url: https://github.com/nodejs/node/pull/12001
556577
description: The `buffer` parameter can be an Uint8Array now.
@@ -559,19 +580,25 @@ changes:
559580
<!-- YAML
560581
added: v0.11.12
561582
changes:
583+
- version: REPLACEME
584+
pr-url: REPLACEME
585+
description: The `buffer` parameter can be any TypedArray or DataView now.
562586
- version: REPLACEME
563587
pr-url: https://github.com/nodejs/node/pull/12001
564588
description: The `buffer` parameter can be an Uint8Array now.
565589
-->
566590

567-
-`buffer` {Buffer|Uint8Array|string}
591+
-`buffer` {Buffer|TypedArray|DataView|string}
568592

569593
Compress a chunk of data with [Gzip][].
570594

571595
### zlib.inflate(buffer[, options], callback)
572596
<!-- YAML
573597
added: v0.6.0
574598
changes:
599+
- version: REPLACEME
600+
pr-url: REPLACEME
601+
description: The `buffer` parameter can be any TypedArray or DataView now.
575602
- version: REPLACEME
576603
pr-url: https://github.com/nodejs/node/pull/12001
577604
description: The `buffer` parameter can be an Uint8Array now.
@@ -580,19 +607,25 @@ changes:
580607
<!-- YAML
581608
added: v0.11.12
582609
changes:
610+
- version: REPLACEME
611+
pr-url: REPLACEME
612+
description: The `buffer` parameter can be any TypedArray or DataView now.
583613
- version: REPLACEME
584614
pr-url: https://github.com/nodejs/node/pull/12001
585615
description: The `buffer` parameter can be an Uint8Array now.
586616
-->
587617

588-
-`buffer` {Buffer|Uint8Array|string}
618+
-`buffer` {Buffer|TypedArray|DataView|string}
589619

590620
Decompress a chunk of data with [Inflate][].
591621

592622
### zlib.inflateRaw(buffer[, options], callback)
593623
<!-- YAML
594624
added: v0.6.0
595625
changes:
626+
- version: REPLACEME
627+
pr-url: REPLACEME
628+
description: The `buffer` parameter can be any TypedArray or DataView now.
596629
- version: REPLACEME
597630
pr-url: https://github.com/nodejs/node/pull/12001
598631
description: The `buffer` parameter can be an Uint8Array now.
@@ -601,19 +634,25 @@ changes:
601634
<!-- YAML
602635
added: v0.11.12
603636
changes:
637+
- version: REPLACEME
638+
pr-url: REPLACEME
639+
description: The `buffer` parameter can be any TypedArray or DataView now.
604640
- version: REPLACEME
605641
pr-url: https://github.com/nodejs/node/pull/12001
606642
description: The `buffer` parameter can be an Uint8Array now.
607643
-->
608644

609-
-`buffer` {Buffer|Uint8Array|string}
645+
-`buffer` {Buffer|TypedArray|DataView|string}
610646

611647
Decompress a chunk of data with [InflateRaw][].
612648

613649
### zlib.unzip(buffer[, options], callback)
614650
<!-- YAML
615651
added: v0.6.0
616652
changes:
653+
- version: REPLACEME
654+
pr-url: REPLACEME
655+
description: The `buffer` parameter can be any TypedArray or DataView now.
617656
- version: REPLACEME
618657
pr-url: https://github.com/nodejs/node/pull/12001
619658
description: The `buffer` parameter can be an Uint8Array now.
@@ -622,12 +661,15 @@ changes:
622661
<!-- YAML
623662
added: v0.11.12
624663
changes:
664+
- version: REPLACEME
665+
pr-url: REPLACEME
666+
description: The `buffer` parameter can be any TypedArray or DataView now.
625667
- version: REPLACEME
626668
pr-url: https://github.com/nodejs/node/pull/12001
627669
description: The `buffer` parameter can be an Uint8Array now.
628670
-->
629671

630-
-`buffer` {Buffer|Uint8Array|string}
672+
-`buffer` {Buffer|TypedArray|DataView|string}
631673

632674
Decompress a chunk of data with [Unzip][].
633675

@@ -644,5 +686,6 @@ Decompress a chunk of data with [Unzip][].
644686
[InflateRaw]: #zlib_class_zlib_inflateraw
645687
[Unzip]: #zlib_class_zlib_unzip
646688
[`.flush()`]: #zlib_zlib_flush_kind_callback
647-
[Buffer]: buffer.html
648-
[Uint8Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
689+
[`Buffer`]: buffer.html#buffer_class_buffer
690+
[`DataView`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
691+
[`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray

‎lib/zlib.js‎

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
constBuffer=require('buffer').Buffer;
2525
constinternalUtil=require('internal/util');
2626
constTransform=require('_stream_transform');
27-
const{ isUint8Array }=process.binding('util');
2827
constbinding=process.binding('zlib');
2928
constassert=require('assert').ok;
3029
constkMaxLength=require('buffer').kMaxLength;
@@ -79,9 +78,9 @@ function isInvalidStrategy(strategy) {
7978
}
8079

8180
functionzlibBuffer(engine,buffer,callback){
82-
// Streams do not support non-Buffer Uint8Arrays yet. Convert it to a
81+
// Streams do not support non-Buffer ArrayBufferViews yet. Convert it to a
8382
// Buffer without copying.
84-
if(isUint8Array(buffer)&&
83+
if(ArrayBuffer.isView(buffer)&&
8584
Object.getPrototypeOf(buffer)!==Buffer.prototype){
8685
buffer=Buffer.from(buffer.buffer,buffer.byteOffset,buffer.byteLength);
8786
}
@@ -99,7 +98,7 @@ function zlibBuffer(engine, buffer, callback) {
9998
varchunk;
10099
while(null!==(chunk=engine.read())){
101100
buffers.push(chunk);
102-
nread+=chunk.length;
101+
nread+=chunk.byteLength;
103102
}
104103
engine.once('readable',flow);
105104
}
@@ -129,9 +128,9 @@ function zlibBuffer(engine, buffer, callback) {
129128
functionzlibBufferSync(engine,buffer){
130129
if(typeofbuffer==='string')
131130
buffer=Buffer.from(buffer);
132-
elseif(!isUint8Array(buffer))
133-
thrownewTypeError('"buffer" argument must be a string, Buffer, or '+
134-
'Uint8Array');
131+
elseif(!ArrayBuffer.isView(buffer))
132+
thrownewTypeError('"buffer" argument must be a string, Buffer, '+
133+
'TypedArray, or DataView');
135134

136135
varflushFlag=engine._finishFlushFlag;
137136

@@ -214,9 +213,9 @@ class Zlib extends Transform {
214213
thrownewTypeError('Invalid strategy: '+opts.strategy);
215214

216215
if(opts.dictionary){
217-
if(!isUint8Array(opts.dictionary)){
216+
if(!ArrayBuffer.isView(opts.dictionary)){
218217
thrownewTypeError(
219-
'Invalid dictionary: it should be a Bufferor an Uint8Array');
218+
'Invalid dictionary: it should be a Buffer, TypedArray, or DataView');
220219
}
221220
}
222221

@@ -309,9 +308,9 @@ class Zlib extends Transform {
309308
varflushFlag;
310309
varws=this._writableState;
311310
varending=ws.ending||ws.ended;
312-
varlast=ending&&(!chunk||ws.length===chunk.length);
311+
varlast=ending&&(!chunk||ws.length===chunk.byteLength);
313312

314-
if(chunk!==null&&!isUint8Array(chunk))
313+
if(chunk!==null&&!ArrayBuffer.isView(chunk))
315314
returncb(newTypeError('invalid input'));
316315

317316
if(!this._handle)
@@ -328,7 +327,7 @@ class Zlib extends Transform {
328327
flushFlag=this._flushFlag;
329328
// once we've flushed the last of the queue, stop flushing and
330329
// go back to the normal behavior.
331-
if(chunk.length>=ws.length){
330+
if(chunk.byteLength>=ws.length){
332331
this._flushFlag=this._opts.flush||constants.Z_NO_FLUSH;
333332
}
334333
}
@@ -337,7 +336,7 @@ class Zlib extends Transform {
337336
}
338337

339338
_processChunk(chunk,flushFlag,cb){
340-
varavailInBefore=chunk&&chunk.length;
339+
varavailInBefore=chunk&&chunk.byteLength;
341340
varavailOutBefore=this._chunkSize-this._offset;
342341
varinOff=0;
343342

@@ -417,7 +416,7 @@ class Zlib extends Transform {
417416
self.push(out);
418417
}else{
419418
buffers.push(out);
420-
nread+=out.length;
419+
nread+=out.byteLength;
421420
}
422421
}
423422

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

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,28 @@ const common = require('../common');
2626
constassert=require('assert');
2727
constzlib=require('zlib');
2828

29-
constexpectStr='blahblahblahblahblahblah';
29+
// Must be a multiple of 4 characters in total to test all ArrayBufferView
30+
// types.
31+
constexpectStr='blah'.repeat(8);
3032
constexpectBuf=Buffer.from(expectStr);
31-
constexpectUint8Array=newUint8Array(expectBuf);
33+
3234
constopts={
3335
level: 9,
3436
chunkSize: 1024,
3537
};
3638

37-
for(constmethodof[
38-
['gzip','gunzip'],
39-
['gzip','unzip'],
40-
['deflate','inflate'],
41-
['deflateRaw','inflateRaw'],
39+
for(const[type,expect]of[
40+
['string',expectStr],
41+
['Buffer',expectBuf],
42+
...common.getArrayBufferViews(expectBuf).map((obj)=>
43+
[obj[Symbol.toStringTag],obj]
44+
)
4245
]){
43-
for(const[type,expect]of[
44-
['string',expectStr],
45-
['Buffer',expectBuf],
46-
['Uint8Array',expectUint8Array]
46+
for(constmethodof[
47+
['gzip','gunzip'],
48+
['gzip','unzip'],
49+
['deflate','inflate'],
50+
['deflateRaw','inflateRaw'],
4751
]){
4852
zlib[method[0]](expect,opts,common.mustCall((err,result)=>{
4953
zlib[method[1]](result,opts,common.mustCall((err,result)=>{

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,6 @@ assert.throws(
107107
// Throws if opts.dictionary is not a Buffer
108108
assert.throws(
109109
()=>{newzlib.Deflate({dictionary: 'not a buffer'});},
110-
/^TypeError:Invaliddictionary:itshouldbeaBufferoranUint8Array$/
110+
newRegExp('^TypeError: Invalid dictionary: it should be a Buffer, '+
111+
'TypedArray, or DataView$')
111112
);

‎test/parallel/test-zlib-dictionary.js‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ const spdyDict = Buffer.from([
4141
'ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1',
4242
'.1statusversionurl\0'
4343
].join(''));
44-
constspdyDictUint8Array=newUint8Array(spdyDict);
4544

4645
constinput=[
4746
'HTTP/1.1 200 Ok',
@@ -168,7 +167,7 @@ function deflateRawResetDictionaryTest(spdyDict) {
168167
});
169168
}
170169

171-
for(constdictof[spdyDict,spdyDictUint8Array]){
170+
for(constdictof[spdyDict,...common.getArrayBufferViews(spdyDict)]){
172171
basicDictionaryTest(dict);
173172
deflateResetDictionaryTest(dict);
174173
rawDictionaryTest(dict);

‎test/parallel/test-zlib-not-string-or-buffer.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ require('../common');
77
constassert=require('assert');
88
constzlib=require('zlib');
99

10-
constexpected=
11-
/^TypeError:"buffer"argumentmustbeastring,Buffer,orUint8Array$/;
10+
constexpected=newRegExp('^TypeError: "buffer" argument must be a string, '+
11+
'Buffer, TypedArray, or DataView$');
1212

1313
assert.throws(()=>{zlib.deflateSync(undefined);},expected);
1414
assert.throws(()=>{zlib.deflateSync(null);},expected);

0 commit comments

Comments
 (0)