@@ -122,6 +122,11 @@ function zlibBufferOnData(chunk) {
122
122
else
123
123
this . buffers . push ( chunk ) ;
124
124
this . nread += chunk . length ;
125
+ if ( this . nread > this . _maxOutputLength ) {
126
+ this . close ( ) ;
127
+ this . removeAllListeners ( 'end' ) ;
128
+ this . cb ( new ERR_BUFFER_TOO_LARGE ( this . _maxOutputLength ) ) ;
129
+ }
125
130
}
126
131
127
132
function zlibBufferOnError ( err ) {
@@ -132,9 +137,7 @@ function zlibBufferOnError(err) {
132
137
function zlibBufferOnEnd ( ) {
133
138
let buf ;
134
139
let err ;
135
- if ( this . nread >= kMaxLength ) {
136
- err = new ERR_BUFFER_TOO_LARGE ( ) ;
137
- } else if ( this . nread === 0 ) {
140
+ if ( this . nread === 0 ) {
138
141
buf = Buffer . alloc ( 0 ) ;
139
142
} else {
140
143
const bufs = this . buffers ;
@@ -230,6 +233,7 @@ const checkRangesOrGetDefault = hideStackFrames(
230
233
// The base class for all Zlib-style streams.
231
234
function ZlibBase ( opts , mode , handle , { flush, finishFlush, fullFlush } ) {
232
235
let chunkSize = Z_DEFAULT_CHUNK ;
236
+ let maxOutputLength = kMaxLength ;
233
237
// The ZlibBase class is not exported to user land, the mode should only be
234
238
// passed in by us.
235
239
assert ( typeof mode === 'number' ) ;
@@ -252,6 +256,10 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) {
252
256
opts . finishFlush , 'options.finishFlush' ,
253
257
Z_NO_FLUSH , Z_BLOCK , finishFlush ) ;
254
258
259
+ maxOutputLength = checkRangesOrGetDefault (
260
+ opts . maxOutputLength , 'options.maxOutputLength' ,
261
+ 1 , kMaxLength , kMaxLength ) ;
262
+
255
263
if ( opts . encoding || opts . objectMode || opts . writableObjectMode ) {
256
264
opts = { ...opts } ;
257
265
opts . encoding = null ;
@@ -276,6 +284,7 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) {
276
284
this . _defaultFullFlushFlag = fullFlush ;
277
285
this . once ( 'end' , _close . bind ( null , this ) ) ;
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 ) ;
@@ -445,6 +454,12 @@ function processChunkSync(self, chunk, flushFlag) {
445
454
else
446
455
buffers . push ( out ) ;
447
456
nread += out . byteLength ;
457
+
458
+ if ( nread > self . _maxOutputLength ) {
459
+ _close ( self ) ;
460
+ throw new ERR_BUFFER_TOO_LARGE ( self . _maxOutputLength ) ;
461
+ }
462
+
448
463
} else {
449
464
assert ( have === 0 , 'have should not go down' ) ;
450
465
}
@@ -471,10 +486,6 @@ function processChunkSync(self, chunk, flushFlag) {
471
486
self . bytesWritten = inputRead ;
472
487
_close ( self ) ;
473
488
474
- if ( nread >= kMaxLength ) {
475
- throw new ERR_BUFFER_TOO_LARGE ( ) ;
476
- }
477
-
478
489
if ( nread === 0 )
479
490
return Buffer . alloc ( 0 ) ;
480
491
0 commit comments