Skip to content

Commit 9d2b23b

Browse files
Reset ZLibStreamHandle when parsing concatenated GZip streams (#113587)
* Reset ZLib inflater state where possible * Add CompressionNative_InflateReset2_ to Unix exports --------- Co-authored-by: Carlos Sánchez López <[email protected]>
1 parent 840fc4a commit 9d2b23b

File tree

8 files changed

+41
-11
lines changed

8 files changed

+41
-11
lines changed

src/libraries/Common/src/Interop/Interop.zlib.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ internal static unsafe partial ZLibNative.ErrorCode DeflateInit2_(
2626
[LibraryImport(Libraries.CompressionNative, EntryPoint = "CompressionNative_InflateInit2_")]
2727
internal static unsafe partial ZLibNative.ErrorCode InflateInit2_(ZLibNative.ZStream* stream, int windowBits);
2828

29+
[LibraryImport(Libraries.CompressionNative, EntryPoint = "CompressionNative_InflateReset2_")]
30+
internal static unsafe partial ZLibNative.ErrorCode InflateReset2_(ZLibNative.ZStream* stream, int windowBits);
31+
2932
[LibraryImport(Libraries.CompressionNative, EntryPoint = "CompressionNative_Inflate")]
3033
internal static unsafe partial ZLibNative.ErrorCode Inflate(ZLibNative.ZStream* stream, ZLibNative.FlushCode flush);
3134

src/libraries/Common/src/System/IO/Compression/ZLibNative.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,17 @@ public unsafe ErrorCode InflateInit2_(int windowBits)
280280
}
281281
}
282282

283+
public unsafe ErrorCode InflateReset2_(int windowBits)
284+
{
285+
EnsureNotDisposed();
286+
EnsureState(State.InitializedForInflate);
287+
288+
fixed (ZStream* stream = &_zStream)
289+
{
290+
return Interop.ZLib.InflateReset2_(stream, windowBits);
291+
}
292+
}
293+
283294
public unsafe ErrorCode Inflate(FlushCode flush)
284295
{
285296
EnsureNotDisposed();

src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,25 +149,18 @@ private unsafe bool ResetStreamForLeftoverInput()
149149

150150
lock (SyncLock)
151151
{
152-
IntPtr nextInPtr = _zlibStream.NextIn;
153-
byte* nextInPointer = (byte*)nextInPtr.ToPointer();
152+
byte* nextInPointer = (byte*)_zlibStream.NextIn;
154153
uint nextAvailIn = _zlibStream.AvailIn;
155154

156-
// Check the leftover bytes to see if they start with he gzip header ID bytes
155+
// Check the leftover bytes to see if they start with the gzip header ID bytes
157156
if (*nextInPointer != ZLibNative.GZip_Header_ID1 || (nextAvailIn > 1 && *(nextInPointer + 1) != ZLibNative.GZip_Header_ID2))
158157
{
159158
return true;
160159
}
161160

162-
// Trash our existing zstream.
163-
_zlibStream.Dispose();
161+
// Reset our existing zstream.
162+
_zlibStream.InflateReset2_(_windowBits);
164163

165-
// Create a new zstream
166-
InflateInit(_windowBits);
167-
168-
// SetInput on the new stream to the bits remaining from the last stream
169-
_zlibStream.NextIn = nextInPtr;
170-
_zlibStream.AvailIn = nextAvailIn;
171164
_finished = false;
172165
}
173166

src/native/libs/System.IO.Compression.Native/System.IO.Compression.Native.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ EXPORTS
2020
CompressionNative_Inflate
2121
CompressionNative_InflateEnd
2222
CompressionNative_InflateInit2_
23+
CompressionNative_InflateReset2_

src/native/libs/System.IO.Compression.Native/System.IO.Compression.Native_unixexports.src

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ CompressionNative_DeflateInit2_
2020
CompressionNative_Inflate
2121
CompressionNative_InflateEnd
2222
CompressionNative_InflateInit2_
23+
CompressionNative_InflateReset2_

src/native/libs/System.IO.Compression.Native/entrypoints.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ static const Entry s_compressionNative[] =
3131
DllImportEntry(CompressionNative_Inflate)
3232
DllImportEntry(CompressionNative_InflateEnd)
3333
DllImportEntry(CompressionNative_InflateInit2_)
34+
DllImportEntry(CompressionNative_InflateReset2_)
3435
};
3536

3637
EXTERN_C const void* CompressionResolveDllImport(const char* name);

src/native/libs/System.IO.Compression.Native/pal_zlib.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,17 @@ int32_t CompressionNative_InflateEnd(PAL_ZStream* stream)
181181
return result;
182182
}
183183

184+
int32_t CompressionNative_InflateReset2_(PAL_ZStream* stream, int32_t windowBits)
185+
{
186+
assert(stream != NULL);
187+
188+
z_stream* zStream = GetCurrentZStream(stream);
189+
int32_t result = inflateReset2(zStream, windowBits);
190+
TransferStateToPalZStream(zStream, stream);
191+
192+
return result;
193+
}
194+
184195
uint32_t CompressionNative_Crc32(uint32_t crc, uint8_t* buffer, int32_t len)
185196
{
186197
assert(buffer != NULL);

src/native/libs/System.IO.Compression.Native/pal_zlib.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ Returns a PAL_ErrorCode indicating success or an error number on failure.
124124
*/
125125
FUNCTIONEXPORT int32_t FUNCTIONCALLINGCONVENTION CompressionNative_InflateEnd(PAL_ZStream* stream);
126126

127+
/*
128+
This function is equivalent to InflateEnd followed by InflateInit, but does not free and reallocate
129+
the internal decompression state. The stream's window size will be modified and its memory may be
130+
reallocated if necessary.
131+
132+
Returns a PAL_ErrorCode indicating success or an error number on failure.
133+
*/
134+
FUNCTIONEXPORT int32_t FUNCTIONCALLINGCONVENTION CompressionNative_InflateReset2_(PAL_ZStream* stream, int32_t windowBits);
135+
127136
/*
128137
Update a running CRC-32 with the bytes buffer[0..len-1] and return the
129138
updated CRC-32.

0 commit comments

Comments
 (0)