Skip to content

Commit 5edadd9

Browse files
committed
Removed [ActiveIssue] from websocket deflate tests. Created a new test that replicates Autobahn Test Case 13.3.1 which causes "invalid distance too far" zlib error.
1 parent 437b7e7 commit 5edadd9

File tree

1 file changed

+102
-84
lines changed

1 file changed

+102
-84
lines changed

src/libraries/System.Net.WebSockets/tests/WebSocketDeflateTests.cs

Lines changed: 102 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -277,83 +277,6 @@ public async Task Duplex(bool clientContextTakover, bool serverContextTakover)
277277
}
278278
}
279279

280-
[Fact]
281-
[ActiveIssue("https://github.com/dotnet/runtime/issues/50235")]
282-
public async Task LargeMessageSplitInMultipleFramesActiveIssue()
283-
{
284-
// This test is exactly the same as LargeMessageSplitInMultipleFrames, but
285-
// for the data seed it uses Random(0) where the other uses Random(10). This is done
286-
// only because it was found that there is a bug in the deflate somewhere and it only appears
287-
// so far when using 10 window bits and data generated using Random(0). Once
288-
// the issue is resolved this test can be deleted and LargeMessageSplitInMultipleFrames should be
289-
// updated to use Random(0).
290-
WebSocketTestStream stream = new();
291-
using WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
292-
{
293-
IsServer = true,
294-
DangerousDeflateOptions = new()
295-
{
296-
ClientMaxWindowBits = 10
297-
}
298-
});
299-
using WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
300-
{
301-
DangerousDeflateOptions = new()
302-
{
303-
ClientMaxWindowBits = 10
304-
}
305-
});
306-
307-
Memory<byte> testData = new byte[ushort.MaxValue];
308-
Memory<byte> receivedData = new byte[testData.Length];
309-
310-
// Make the data incompressible to make sure that the output is larger than the input
311-
var rng = new Random(0);
312-
rng.NextBytes(testData.Span);
313-
314-
// Test it a few times with different frame sizes
315-
for (var i = 0; i < 10; ++i)
316-
{
317-
var frameSize = rng.Next(1024, 2048);
318-
var position = 0;
319-
320-
while (position < testData.Length)
321-
{
322-
var currentFrameSize = Math.Min(frameSize, testData.Length - position);
323-
var eof = position + currentFrameSize == testData.Length;
324-
325-
await server.SendAsync(testData.Slice(position, currentFrameSize), WebSocketMessageType.Binary, eof, CancellationToken);
326-
position += currentFrameSize;
327-
}
328-
329-
Assert.True(testData.Length < stream.Remote.Available, "The compressed data should be bigger.");
330-
Assert.Equal(testData.Length, position);
331-
332-
// Receive the data from the client side
333-
receivedData.Span.Clear();
334-
position = 0;
335-
336-
// Intentionally receive with a frame size that is less than what the sender used
337-
frameSize /= 3;
338-
339-
while (true)
340-
{
341-
int currentFrameSize = Math.Min(frameSize, testData.Length - position);
342-
ValueWebSocketReceiveResult result = await client.ReceiveAsync(receivedData.Slice(position, currentFrameSize), CancellationToken);
343-
344-
Assert.Equal(WebSocketMessageType.Binary, result.MessageType);
345-
position += result.Count;
346-
347-
if (result.EndOfMessage)
348-
break;
349-
}
350-
351-
Assert.Equal(0, stream.Remote.Available);
352-
Assert.Equal(testData.Length, position);
353-
Assert.True(testData.Span.SequenceEqual(receivedData.Span));
354-
}
355-
}
356-
357280
[Theory]
358281
[MemberData(nameof(SupportedWindowBits))]
359282
public async Task LargeMessageSplitInMultipleFrames(int windowBits)
@@ -379,7 +302,7 @@ public async Task LargeMessageSplitInMultipleFrames(int windowBits)
379302
Memory<byte> receivedData = new byte[testData.Length];
380303

381304
// Make the data incompressible to make sure that the output is larger than the input
382-
var rng = new Random(10);
305+
var rng = new Random(0);
383306
rng.NextBytes(testData.Span);
384307

385308
// Test it a few times with different frame sizes
@@ -445,12 +368,12 @@ public async Task ReceiveUncompressedMessageWhenCompressionEnabled()
445368
// We should be able to handle the situation where even if we have
446369
// deflate compression enabled, uncompressed messages are OK
447370
WebSocketTestStream stream = new();
448-
WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
371+
using WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
449372
{
450373
IsServer = true,
451374
DangerousDeflateOptions = null
452375
});
453-
WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
376+
using WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
454377
{
455378
DangerousDeflateOptions = new WebSocketDeflateOptions()
456379
});
@@ -479,7 +402,7 @@ public async Task ReceiveUncompressedMessageWhenCompressionEnabled()
479402
public async Task ReceiveInvalidCompressedData()
480403
{
481404
WebSocketTestStream stream = new();
482-
WebSocket client = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
405+
using WebSocket client = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
483406
{
484407
DangerousDeflateOptions = new WebSocketDeflateOptions()
485408
});
@@ -499,7 +422,7 @@ public async Task ReceiveInvalidCompressedData()
499422
public async Task PayloadShouldHaveSimilarSizeWhenSplitIntoSegments(int windowBits)
500423
{
501424
MemoryStream stream = new();
502-
WebSocket client = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
425+
using WebSocket client = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
503426
{
504427
DangerousDeflateOptions = new WebSocketDeflateOptions()
505428
{
@@ -540,7 +463,7 @@ public async Task PayloadShouldHaveSimilarSizeWhenSplitIntoSegments(int windowBi
540463
public async Task SendReceiveWithDifferentWindowBits(int clientWindowBits, int serverWindowBits)
541464
{
542465
WebSocketTestStream stream = new();
543-
WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
466+
using WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
544467
{
545468
IsServer = true,
546469
DangerousDeflateOptions = new()
@@ -551,7 +474,7 @@ public async Task SendReceiveWithDifferentWindowBits(int clientWindowBits, int s
551474
ServerMaxWindowBits = serverWindowBits
552475
}
553476
});
554-
WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
477+
using WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
555478
{
556479
DangerousDeflateOptions = new()
557480
{
@@ -583,6 +506,101 @@ public async Task SendReceiveWithDifferentWindowBits(int clientWindowBits, int s
583506
Assert.True(data.Span.SequenceEqual(buffer.Span));
584507
}
585508

509+
[Fact]
510+
public async Task AutobahnTestCase13_3_1()
511+
{
512+
// When running Autobahn Test Suite some tests failed with zlib error "invalid distance too far back".
513+
// Further investigation lead to a bug fix in zlib intel's implementation - https://github.com/dotnet/runtime/issues/50235.
514+
// This test replicates one of the Autobahn tests to make sure this issue doesn't appear again.
515+
byte[][] messages = new[]
516+
{
517+
new byte[] { 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x22, 0x41, 0x75, 0x74, 0x6F, 0x62, 0x61, 0x68, 0x6E, 0x50, 0x79 },
518+
new byte[] { 0x74, 0x68, 0x6F, 0x6E, 0x2F, 0x30, 0x2E, 0x36, 0x2E, 0x30, 0x22, 0x3A, 0x20, 0x7B, 0x0A, 0x20 },
519+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x2E, 0x31, 0x2E, 0x31, 0x22, 0x3A, 0x20, 0x7B, 0x0A },
520+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69 },
521+
new byte[] { 0x6F, 0x72, 0x22, 0x3A, 0x20, 0x22, 0x4F, 0x4B, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20 },
522+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x43, 0x6C, 0x6F },
523+
new byte[] { 0x73, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x4F, 0x4B, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20 },
524+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3A, 0x20 },
525+
new byte[] { 0x32, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6D },
526+
new byte[] { 0x6F, 0x74, 0x65, 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x43, 0x6F, 0x64, 0x65, 0x22, 0x3A, 0x20, 0x31 },
527+
new byte[] { 0x30, 0x30, 0x30, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72 },
528+
new byte[] { 0x65, 0x70, 0x6F, 0x72, 0x74, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x61, 0x75, 0x74 },
529+
new byte[] { 0x6F, 0x62, 0x61, 0x68, 0x6E, 0x70, 0x79, 0x74, 0x68, 0x6F, 0x6E, 0x5F, 0x30, 0x5F, 0x36, 0x5F },
530+
new byte[] { 0x30, 0x5F, 0x63, 0x61, 0x73, 0x65, 0x5F, 0x31, 0x5F, 0x31, 0x5F, 0x31, 0x2E, 0x6A, 0x73, 0x6F },
531+
new byte[] { 0x6E, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20 },
532+
new byte[] { 0x20, 0x20, 0x22, 0x31, 0x2E, 0x31, 0x2E, 0x32, 0x22, 0x3A, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20 },
533+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x22 },
534+
new byte[] { 0x3A, 0x20, 0x22, 0x4F, 0x4B, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
535+
new byte[] { 0x20, 0x22, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x22 },
536+
new byte[] { 0x3A, 0x20, 0x22, 0x4F, 0x4B, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
537+
new byte[] { 0x20, 0x22, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3A, 0x20, 0x32, 0x2C, 0x0A },
538+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6D, 0x6F, 0x74, 0x65 },
539+
new byte[] { 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x43, 0x6F, 0x64, 0x65, 0x22, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x30 },
540+
new byte[] { 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6F },
541+
new byte[] { 0x72, 0x74, 0x66, 0x69, 0x6C, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x61, 0x75, 0x74, 0x6F, 0x62, 0x61 },
542+
new byte[] { 0x68, 0x6E, 0x70, 0x79, 0x74, 0x68, 0x6F, 0x6E, 0x5F, 0x30, 0x5F, 0x36, 0x5F, 0x30, 0x5F, 0x63 },
543+
new byte[] { 0x61, 0x73, 0x65, 0x5F, 0x31, 0x5F, 0x31, 0x5F, 0x32, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x22, 0x0A },
544+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22 },
545+
new byte[] { 0x31, 0x2E, 0x31, 0x2E, 0x33, 0x22, 0x3A, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
546+
new byte[] { 0x20, 0x20, 0x20, 0x22, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x22, 0x3A, 0x20, 0x22 },
547+
new byte[] { 0x4F, 0x4B, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62 },
548+
new byte[] { 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x22, 0x3A, 0x20, 0x22 },
549+
new byte[] { 0x4F, 0x4B, 0x22, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64 },
550+
new byte[] { 0x75, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3A, 0x20, 0x32, 0x2C, 0x0A, 0x20, 0x20, 0x20 },
551+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x6D, 0x6F, 0x74, 0x65, 0x43, 0x6C, 0x6F },
552+
new byte[] { 0x73, 0x65, 0x43, 0x6F, 0x64, 0x65, 0x22, 0x3A, 0x20, 0x31, 0x30, 0x30, 0x30, 0x2C, 0x0A, 0x20 },
553+
new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x66 },
554+
new byte[] { 0x69, 0x6C, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x61, 0x75, 0x74, 0x6F, 0x62, 0x61, 0x68, 0x6E, 0x70 },
555+
new byte[] { 0x79, 0x74, 0x68, 0x6F, 0x6E, 0x5F, 0x30, 0x5F, 0x36, 0x5F, 0x30, 0x5F, 0x63, 0x61, 0x73, 0x65 },
556+
new byte[] { 0x5F, 0x31, 0x5F, 0x31, 0x5F, 0x33, 0x2E, 0x6A, 0x73, 0x6F, 0x6E, 0x22, 0x0A, 0x20, 0x20, 0x20 },
557+
new byte[] { 0x20, 0x20, 0x20, 0x7D, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x31, 0x2E, 0x31 },
558+
new byte[] { 0x2E, 0x34, 0x22, 0x3A, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
559+
new byte[] { 0x22, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6F, 0x72, 0x22, 0x3A, 0x20, 0x22, 0x4F, 0x4B, 0x22 },
560+
new byte[] { 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x65, 0x68, 0x61 },
561+
new byte[] { 0x76, 0x69, 0x6F, 0x72, 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x22, 0x3A, 0x20, 0x22, 0x4F, 0x4B, 0x22 },
562+
new byte[] { 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x75, 0x72, 0x61 },
563+
new byte[] { 0x74, 0x69, 0x6F, 0x6E, 0x22, 0x3A, 0x20, 0x32, 0x2C, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }
564+
};
565+
566+
WebSocketTestStream stream = new();
567+
using WebSocket server = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions
568+
{
569+
IsServer = true,
570+
KeepAliveInterval = TimeSpan.Zero,
571+
DangerousDeflateOptions = new()
572+
{
573+
ClientMaxWindowBits = 9,
574+
ServerMaxWindowBits = 9
575+
}
576+
});
577+
using WebSocket client = WebSocket.CreateFromStream(stream.Remote, new WebSocketCreationOptions
578+
{
579+
KeepAliveInterval = TimeSpan.Zero,
580+
DangerousDeflateOptions = new()
581+
{
582+
ClientMaxWindowBits = 9,
583+
ServerMaxWindowBits = 9
584+
}
585+
});
586+
587+
foreach (var message in messages)
588+
{
589+
await server.SendAsync(message, WebSocketMessageType.Text, true, CancellationToken);
590+
}
591+
592+
Memory<byte> buffer = new byte[32];
593+
594+
for (int i = 0; i < messages.Length; ++i)
595+
{
596+
ValueWebSocketReceiveResult result = await client.ReceiveAsync(buffer, CancellationToken);
597+
598+
Assert.True(result.EndOfMessage);
599+
Assert.Equal(messages[i].Length, result.Count);
600+
Assert.True(buffer.Span.Slice(0, result.Count).SequenceEqual(messages[i]));
601+
}
602+
}
603+
586604
private ValueTask SendTextAsync(string text, WebSocket websocket, bool disableCompression = false)
587605
{
588606
WebSocketMessageFlags flags = WebSocketMessageFlags.EndOfMessage;

0 commit comments

Comments
 (0)