22// SPDX-License-Identifier: Apache-2.0
33package com .amazon .ion .impl ;
44
5+ import com .amazon .ion .IonBufferConfiguration ;
56import com .amazon .ion .IonCatalog ;
67import com .amazon .ion .IonException ;
78import com .amazon .ion .IonReader ;
89import com .amazon .ion .IonTextReader ;
910import com .amazon .ion .IonValue ;
1011import com .amazon .ion .util .InputStreamInterceptor ;
12+ import com .amazon .ion .util .LimitedInflaterInputStream ;
1113import com .amazon .ion .system .IonReaderBuilder ;
1214import com .amazon .ion .util .IonStreamUtils ;
1315
@@ -205,6 +207,24 @@ private static void validateHeaderLength(int maxHeaderLength) {
205207 }
206208 }
207209
210+ /**
211+ * Wraps the given InputStream with a {@link LimitedInflaterInputStream} if the interceptor is for GZIP
212+ * and a finite maximum buffer size is configured.
213+ */
214+ private static InputStream wrapWithInflationLimitIfNeeded (
215+ _Private_IonReaderBuilder builder ,
216+ InputStreamInterceptor streamInterceptor ,
217+ InputStream interceptedStream
218+ ) {
219+ if ("gzip" .equals (streamInterceptor .formatName ())) {
220+ long maxDecompressedBytes = builder .getBufferConfiguration ().getMaximumBufferSize ();
221+ if (maxDecompressedBytes > 0 ) {
222+ return new LimitedInflaterInputStream (interceptedStream , maxDecompressedBytes );
223+ }
224+ }
225+ return interceptedStream ;
226+ }
227+
208228 static IonReader buildReader (
209229 _Private_IonReaderBuilder builder ,
210230 byte [] ionData ,
@@ -222,9 +242,11 @@ static IonReader buildReader(
222242 }
223243 if (streamInterceptor .isMatch (ionData , offset , length )) {
224244 try {
245+ InputStream decompressedStream = streamInterceptor .newInputStream (new ByteArrayInputStream (ionData , offset , length ));
246+ decompressedStream = wrapWithInflationLimitIfNeeded (builder , streamInterceptor , decompressedStream );
225247 return buildReader (
226248 builder ,
227- streamInterceptor . newInputStream ( new ByteArrayInputStream ( ionData , offset , length )) ,
249+ decompressedStream ,
228250 _Private_IonReaderFactory ::makeReaderBinary ,
229251 _Private_IonReaderFactory ::makeReaderText ,
230252 // The builder provides only one level of detection, e.g. GZIP-compressed binary Ion *or*
@@ -275,7 +297,7 @@ private static boolean startsWithIvm(byte[] buffer, int length) {
275297
276298 @ FunctionalInterface
277299 interface IonReaderFromInputStreamFactoryText {
278- IonReader makeReader (IonCatalog catalog , InputStream source , _Private_LocalSymbolTableFactory lstFactory );
300+ IonReader makeReader (IonCatalog catalog , InputStream source , _Private_LocalSymbolTableFactory lstFactory , long maximumTotalBytes );
279301 }
280302
281303 @ FunctionalInterface
@@ -357,6 +379,7 @@ static IonReader buildReader(
357379 ionData = streamInterceptor .newInputStream (
358380 new TwoElementInputStream (new ByteArrayInputStream (possibleIVM , 0 , bytesRead ), ionData )
359381 );
382+ ionData = wrapWithInflationLimitIfNeeded (builder , streamInterceptor , ionData );
360383 } catch (IOException e ) {
361384 throw new IonException (e );
362385 }
@@ -376,7 +399,7 @@ static IonReader buildReader(
376399 } else {
377400 wrapper = ionData ;
378401 }
379- return text .makeReader (builder .validateCatalog (), wrapper , builder .lstFactory );
402+ return text .makeReader (builder .validateCatalog (), wrapper , builder .lstFactory , builder . getBufferConfiguration (). getMaximumBufferSize () );
380403 }
381404
382405 @ Override
@@ -393,7 +416,7 @@ public IonReader build(InputStream source)
393416
394417 @ Override
395418 public IonReader build (Reader ionText ) {
396- return makeReaderText (validateCatalog (), ionText , lstFactory );
419+ return makeReaderText (validateCatalog (), ionText , lstFactory , getBufferConfiguration (). getMaximumBufferSize () );
397420 }
398421
399422 @ Override
0 commit comments