@@ -47,6 +47,12 @@ public class GZipInputStream : InflaterInputStream
4747 /// This is tracked per-block as the file is parsed.
4848 /// </summary>
4949 bool readGZIPHeader ;
50+
51+ /// <summary>
52+ /// Flag to indicate if at least one block in a stream with concatenated blocks was read successfully.
53+ /// This allows us to exit gracefully if downstream data is not in gzip format.
54+ /// </summary>
55+ bool completedLastBlock ;
5056 #endregion
5157
5258 #region Constructors
@@ -100,12 +106,23 @@ public override int Read(byte[] buffer, int offset, int count)
100106 // If we haven't read the header for this block, read it
101107 if ( ! readGZIPHeader ) {
102108
103- // Try to read header. If there is no header (0 bytes available), this is EOF. If there is
104- // an incomplete header, this will throw an exception.
105- if ( ! ReadHeader ( ) ) {
106- return 0 ;
107- }
108- }
109+ // Try to read header. If there is no header (0 bytes available), this is EOF. If there is
110+ // an incomplete header, this will throw an exception.
111+ try
112+ {
113+ if ( ! ReadHeader ( ) )
114+ {
115+ return 0 ;
116+ }
117+ }
118+ catch ( Exception ex ) when ( completedLastBlock && ( ex is GZipException || ex is EndOfStreamException ) )
119+ {
120+ // if we completed the last block (i.e. we're in a stream that has multiple blocks concatenated
121+ // we want to return gracefully from any header parsing exceptions since sometimes there may
122+ // be trailing garbage on a stream
123+ return 0 ;
124+ }
125+ }
109126
110127 // Try to read compressed data
111128 int bytesRead = base . Read ( buffer , offset , count ) ;
@@ -151,14 +168,14 @@ bool ReadHeader()
151168
152169 headCRC . Update ( magic ) ;
153170 if ( magic != ( GZipConstants . GZIP_MAGIC >> 8 ) ) {
154- throw new GZipException ( "Error GZIP header, first magic byte doesn't match" ) ;
171+ throw new GZipException ( "Error GZIP header, first magic byte doesn't match" ) ;
155172 }
156173
157174 //magic = baseInputStream.ReadByte();
158175 magic = inputBuffer . ReadLeByte ( ) ;
159176
160177 if ( magic < 0 ) {
161- throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
178+ throw new EndOfStreamException ( "EOS reading GZIP header" ) ;
162179 }
163180
164181 if ( magic != ( GZipConstants . GZIP_MAGIC & 0xFF ) ) {
@@ -324,6 +341,9 @@ void ReadFooter()
324341
325342 // Mark header read as false so if another header exists, we'll continue reading through the file
326343 readGZIPHeader = false ;
344+
345+ // Indicate that we succeeded on at least one block so we can exit gracefully if there is trailing garbage downstream
346+ completedLastBlock = true ;
327347 }
328348 #endregion
329349 }
0 commit comments