Skip to content

Commit de065f3

Browse files
committed
Fix integer overflow in sequence number for compressed packets.
1 parent 6cf3459 commit de065f3

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

src/MySqlConnector/Protocol/Serialization/CompressedPayloadHandler.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public ValueTask<int> WritePayloadAsync(ReadOnlyMemory<byte> payload, IOBehavior
4848
return ProtocolUtility.WritePayloadAsync(m_uncompressedStreamByteHandler!, GetNextUncompressedSequenceNumber, payload, ioBehavior).ContinueWith(_ =>
4949
{
5050
if (m_uncompressedStream!.Length == 0)
51-
return default(ValueTask<int>);
51+
return default;
5252

5353
if (!m_uncompressedStream.TryGetBuffer(out var uncompressedData))
5454
throw new InvalidOperationException("Couldn't get uncompressed stream buffer.");
@@ -81,20 +81,20 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
8181
if (headerReadBytes.Count < 7)
8282
{
8383
return protocolErrorBehavior == ProtocolErrorBehavior.Ignore ?
84-
default(ValueTask<int>) :
84+
default :
8585
ValueTaskExtensions.FromException<int>(new EndOfStreamException("Wanted to read 7 bytes but only read {0} when reading compressed packet header".FormatInvariant(headerReadBytes.Count)));
8686
}
8787

8888
var payloadLength = (int) SerializationUtility.ReadUInt32(headerReadBytes.Array!, headerReadBytes.Offset, 3);
89-
int packetSequenceNumber = headerReadBytes.Array![headerReadBytes.Offset + 3];
89+
var packetSequenceNumber = headerReadBytes.Array![headerReadBytes.Offset + 3];
9090
var uncompressedLength = (int) SerializationUtility.ReadUInt32(headerReadBytes.Array, headerReadBytes.Offset + 4, 3);
9191

9292
// verify the compressed packet sequence number
93-
var expectedSequenceNumber = GetNextCompressedSequenceNumber() % 256;
93+
var expectedSequenceNumber = GetNextCompressedSequenceNumber();
9494
if (packetSequenceNumber != expectedSequenceNumber)
9595
{
9696
if (protocolErrorBehavior == ProtocolErrorBehavior.Ignore)
97-
return default(ValueTask<int>);
97+
return default;
9898

9999
var exception = MySqlProtocolException.CreateForPacketOutOfOrder(expectedSequenceNumber, packetSequenceNumber);
100100
return ValueTaskExtensions.FromException<int>(exception);
@@ -116,7 +116,7 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
116116
if (payloadReadBytes.Count < payloadLength)
117117
{
118118
return protocolErrorBehavior == ProtocolErrorBehavior.Ignore ?
119-
default(ValueTask<int>) :
119+
default :
120120
ValueTaskExtensions.FromException<int>(new EndOfStreamException("Wanted to read {0} bytes but only read {1} when reading compressed payload".FormatInvariant(payloadLength, payloadReadBytes.Count)));
121121
}
122122

@@ -136,7 +136,7 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
136136
// FLG & 0x40: has preset dictionary (not supported)
137137
// CMF*256+FLG is a multiple of 31: header checksum
138138
return protocolErrorBehavior == ProtocolErrorBehavior.Ignore ?
139-
default(ValueTask<int>) :
139+
default :
140140
ValueTaskExtensions.FromException<int>(new NotSupportedException("Unsupported zlib header: {0:X2}{1:X2}".FormatInvariant(cmf, flg)));
141141
}
142142

@@ -151,14 +151,14 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
151151
m_remainingData = new(uncompressedData, 0, bytesRead);
152152

153153
var checksum = ComputeAdler32Checksum(uncompressedData, 0, bytesRead);
154-
int adlerStartOffset = payloadReadBytes.Offset + payloadReadBytes.Count - 4;
154+
var adlerStartOffset = payloadReadBytes.Offset + payloadReadBytes.Count - 4;
155155
if (payloadReadBytes.Array[adlerStartOffset + 0] != ((checksum >> 24) & 0xFF) ||
156156
payloadReadBytes.Array[adlerStartOffset + 1] != ((checksum >> 16) & 0xFF) ||
157157
payloadReadBytes.Array[adlerStartOffset + 2] != ((checksum >> 8) & 0xFF) ||
158158
payloadReadBytes.Array[adlerStartOffset + 3] != (checksum & 0xFF))
159159
{
160160
return protocolErrorBehavior == ProtocolErrorBehavior.Ignore ?
161-
default(ValueTask<int>) :
161+
default :
162162
ValueTaskExtensions.FromException<int>(new NotSupportedException("Invalid Adler-32 checksum of uncompressed data."));
163163
}
164164
}
@@ -171,7 +171,7 @@ private ValueTask<int> ReadBytesAsync(Memory<byte> buffer, ProtocolErrorBehavior
171171
});
172172
}
173173

174-
private int GetNextCompressedSequenceNumber() => m_compressedSequenceNumber++;
174+
private byte GetNextCompressedSequenceNumber() => m_compressedSequenceNumber++;
175175

176176
private int GetNextUncompressedSequenceNumber() => m_uncompressedSequenceNumber++;
177177

@@ -205,7 +205,7 @@ private ValueTask<int> CompressAndWrite(ArraySegment<byte> remainingUncompressed
205205
throw new InvalidOperationException("Couldn't get compressed stream buffer.");
206206
}
207207

208-
uint uncompressedLength = (uint) remainingUncompressedBytes;
208+
var uncompressedLength = (uint) remainingUncompressedBytes;
209209
if (compressedData.Array is null || compressedData.Count >= remainingUncompressedBytes)
210210
{
211211
// setting the length to 0 indicates sending uncompressed data
@@ -215,20 +215,20 @@ private ValueTask<int> CompressAndWrite(ArraySegment<byte> remainingUncompressed
215215

216216
var buffer = new byte[compressedData.Count + 7];
217217
SerializationUtility.WriteUInt32((uint) compressedData.Count, buffer, 0, 3);
218-
buffer[3] = (byte) GetNextCompressedSequenceNumber();
218+
buffer[3] = GetNextCompressedSequenceNumber();
219219
SerializationUtility.WriteUInt32(uncompressedLength, buffer, 4, 3);
220220
Buffer.BlockCopy(compressedData.Array!, compressedData.Offset, buffer, 7, compressedData.Count);
221221

222222
remainingUncompressedData = remainingUncompressedData.Slice(remainingUncompressedBytes);
223223
return m_byteHandler!.WriteBytesAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), ioBehavior)
224-
.ContinueWith(_ => remainingUncompressedData.Count == 0 ? default(ValueTask<int>) :
224+
.ContinueWith(_ => remainingUncompressedData.Count == 0 ? default :
225225
CompressAndWrite(remainingUncompressedData, ioBehavior));
226226
}
227227

228228
private uint ComputeAdler32Checksum(byte[] data, int offset, int length)
229229
{
230230
int s1 = 1, s2 = 0;
231-
for (int i = 0; i < length; i++)
231+
for (var i = 0; i < length; i++)
232232
{
233233
s1 = (s1 + data[offset + i]) % 65521;
234234
s2 = (s2 + s1) % 65521;
@@ -269,8 +269,8 @@ public ValueTask<int> ReadBytesAsync(Memory<byte> buffer, IOBehavior ioBehavior)
269269
IByteHandler? m_byteHandler;
270270
readonly BufferedByteReader m_bufferedByteReader;
271271
readonly BufferedByteReader m_compressedBufferedByteReader;
272-
int m_compressedSequenceNumber;
273-
int m_uncompressedSequenceNumber;
272+
byte m_compressedSequenceNumber;
273+
byte m_uncompressedSequenceNumber;
274274
ArraySegment<byte> m_remainingData;
275275
bool m_isContinuationPacket;
276276
}

0 commit comments

Comments
 (0)