@@ -124,6 +124,11 @@ function zlibBufferOnData(chunk) {
124
124
else
125
125
this . buffers . push ( chunk ) ;
126
126
this . nread += chunk . length ;
127
+ if ( this . nread > this . _maxOutputLength ) {
128
+ this . close ( ) ;
129
+ this . removeAllListeners ( 'end' ) ;
130
+ this . cb ( new ERR_BUFFER_TOO_LARGE ( this . _maxOutputLength ) ) ;
131
+ }
127
132
}
128
133
129
134
function zlibBufferOnError ( err ) {
@@ -134,9 +139,7 @@ function zlibBufferOnError(err) {
134
139
function zlibBufferOnEnd ( ) {
135
140
let buf ;
136
141
let err ;
137
- if ( this . nread >= kMaxLength ) {
138
- err = new ERR_BUFFER_TOO_LARGE ( ) ;
139
- } else if ( this . nread === 0 ) {
142
+ if ( this . nread === 0 ) {
140
143
buf = Buffer . alloc ( 0 ) ;
141
144
} else {
142
145
const bufs = this . buffers ;
@@ -231,6 +234,7 @@ const checkRangesOrGetDefault = hideStackFrames(
231
234
// The base class for all Zlib-style streams.
232
235
function ZlibBase ( opts , mode , handle , { flush, finishFlush, fullFlush } ) {
233
236
let chunkSize = Z_DEFAULT_CHUNK ;
237
+ let maxOutputLength = kMaxLength ;
234
238
// The ZlibBase class is not exported to user land, the mode should only be
235
239
// passed in by us.
236
240
assert ( typeof mode === 'number' ) ;
@@ -253,6 +257,10 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) {
253
257
opts . finishFlush , 'options.finishFlush' ,
254
258
Z_NO_FLUSH , Z_BLOCK , finishFlush ) ;
255
259
260
+ maxOutputLength = checkRangesOrGetDefault (
261
+ opts . maxOutputLength , 'options.maxOutputLength' ,
262
+ 1 , kMaxLength , kMaxLength ) ;
263
+
256
264
if ( opts . encoding || opts . objectMode || opts . writableObjectMode ) {
257
265
opts = { ...opts } ;
258
266
opts . encoding = null ;
@@ -276,6 +284,7 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) {
276
284
this . _finishFlushFlag = finishFlush ;
277
285
this . _defaultFullFlushFlag = fullFlush ;
278
286
this . _info = opts && opts . info ;
287
+ this . _maxOutputLength = maxOutputLength ;
279
288
}
280
289
ObjectSetPrototypeOf ( ZlibBase . prototype , Transform . prototype ) ;
281
290
ObjectSetPrototypeOf ( ZlibBase , Transform ) ;
@@ -450,6 +459,12 @@ function processChunkSync(self, chunk, flushFlag) {
450
459
else
451
460
buffers . push ( out ) ;
452
461
nread += out . byteLength ;
462
+
463
+ if ( nread > self . _maxOutputLength ) {
464
+ _close ( self ) ;
465
+ throw new ERR_BUFFER_TOO_LARGE ( self . _maxOutputLength ) ;
466
+ }
467
+
453
468
} else {
454
469
assert ( have === 0 , 'have should not go down' ) ;
455
470
}
@@ -476,10 +491,6 @@ function processChunkSync(self, chunk, flushFlag) {
476
491
self . bytesWritten = inputRead ;
477
492
_close ( self ) ;
478
493
479
- if ( nread >= kMaxLength ) {
480
- throw new ERR_BUFFER_TOO_LARGE ( ) ;
481
- }
482
-
483
494
if ( nread === 0 )
484
495
return Buffer . alloc ( 0 ) ;
485
496
0 commit comments