Skip to content

Commit 108d186

Browse files
committed
Loop to read all data when decompressing. Fixes #1120
1 parent 7773a75 commit 108d186

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

.ci/integration-tests-steps.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ steps:
4343
image: ${{ parameters.image }}
4444
unsupportedFeatures: ${{ parameters.unsupportedFeatures }}
4545
connectionString: 'server=localhost;port=3300;user id=mysqltest;password=test;database=mysqltest;ssl mode=none;UseCompression=True;DefaultCommandTimeout=3600'
46-
platform: 'net5.0'
46+
platform: 'net6.0'
4747
description: 'Compression'
4848
- template: 'sidebyside-test-steps.yml'
4949
parameters:

src/MySqlConnector/Protocol/Serialization/CompressedPayloadHandler.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,15 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
128128
var uncompressedData = new byte[uncompressedLength];
129129
using var compressedStream = new MemoryStream(payloadReadBytes.Array!, payloadReadBytes.Offset, payloadReadBytes.Count);
130130
using var decompressingStream = new ZLibStream(compressedStream, CompressionMode.Decompress);
131-
var bytesRead = decompressingStream.Read(uncompressedData, 0, uncompressedLength);
132-
m_remainingData = new(uncompressedData, 0, bytesRead);
131+
int bytesRead, totalBytesRead = 0;
132+
do
133+
{
134+
bytesRead = decompressingStream.Read(uncompressedData, totalBytesRead, uncompressedLength - totalBytesRead);
135+
totalBytesRead += bytesRead;
136+
} while (bytesRead > 0);
137+
if (totalBytesRead != uncompressedLength && protocolErrorBehavior == ProtocolErrorBehavior.Throw)
138+
return ValueTaskExtensions.FromException<int>(new InvalidOperationException("Expected to read {0:n0} uncompressed bytes but only read {1:n0}".FormatInvariant(uncompressedLength, totalBytesRead)));
139+
m_remainingData = new(uncompressedData, 0, totalBytesRead);
133140
#else
134141
// check CMF (Compression Method and Flags) and FLG (Flags) bytes for expected values
135142
var cmf = payloadReadBytes.Array![payloadReadBytes.Offset];
@@ -151,10 +158,17 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
151158
var uncompressedData = new byte[uncompressedLength];
152159
using var compressedStream = new MemoryStream(payloadReadBytes.Array, payloadReadBytes.Offset + headerSize, payloadReadBytes.Count - headerSize - checksumSize);
153160
using var decompressingStream = new DeflateStream(compressedStream, CompressionMode.Decompress);
154-
var bytesRead = decompressingStream.Read(uncompressedData, 0, uncompressedLength);
155-
m_remainingData = new(uncompressedData, 0, bytesRead);
156-
157-
var checksum = Adler32.Calculate(uncompressedData, 0, (uint)bytesRead);
161+
int bytesRead, totalBytesRead = 0;
162+
do
163+
{
164+
bytesRead = decompressingStream.Read(uncompressedData, totalBytesRead, uncompressedLength - totalBytesRead);
165+
totalBytesRead += bytesRead;
166+
} while (bytesRead > 0);
167+
if (totalBytesRead != uncompressedLength && protocolErrorBehavior == ProtocolErrorBehavior.Throw)
168+
return ValueTaskExtensions.FromException<int>(new InvalidOperationException("Expected to read {0:n0} uncompressed bytes but only read {1:n0}".FormatInvariant(uncompressedLength, totalBytesRead)));
169+
m_remainingData = new(uncompressedData, 0, totalBytesRead);
170+
171+
var checksum = Adler32.Calculate(uncompressedData, 0, (uint) totalBytesRead);
158172

159173
var adlerStartOffset = payloadReadBytes.Offset + payloadReadBytes.Count - 4;
160174
if (payloadReadBytes.Array[adlerStartOffset + 0] != ((checksum >> 24) & 0xFF) ||

0 commit comments

Comments
 (0)