|
4 | 4 | using System;
|
5 | 5 | using System.Diagnostics.Contracts;
|
6 | 6 | using System.IO;
|
| 7 | +using System.Linq; |
7 | 8 | using System.Net.WebSockets;
|
8 | 9 | using System.Text;
|
9 | 10 | using System.Threading;
|
@@ -302,6 +303,11 @@ private async Task ReadNextFrameAsync(CancellationToken cancellationToken)
|
302 | 303 | await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Incorrect masking", cancellationToken);
|
303 | 304 | }
|
304 | 305 |
|
| 306 | + if (!ValidateOpCode(_frameInProgress.OpCode)) |
| 307 | + { |
| 308 | + await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid opcode: " + _frameInProgress.OpCode, cancellationToken); |
| 309 | + } |
| 310 | + |
305 | 311 | if (_frameInProgress.IsControlFrame)
|
306 | 312 | {
|
307 | 313 | if (_frameBytesRemaining > 125)
|
@@ -455,29 +461,6 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
|
455 | 461 | return result;
|
456 | 462 | }
|
457 | 463 |
|
458 |
| - private static bool ValidateCloseStatus(WebSocketCloseStatus closeStatus) |
459 |
| - { |
460 |
| - if (closeStatus < (WebSocketCloseStatus)1000 || closeStatus >= (WebSocketCloseStatus)5000) |
461 |
| - { |
462 |
| - return false; |
463 |
| - } |
464 |
| - else if (closeStatus >= (WebSocketCloseStatus)3000) |
465 |
| - { |
466 |
| - // 3000-3999 - Reserved for frameworks |
467 |
| - // 4000-4999 - Reserved for private usage |
468 |
| - return true; |
469 |
| - } |
470 |
| - int[] validCodes = new[] { 1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011 }; |
471 |
| - foreach (var validCode in validCodes) |
472 |
| - { |
473 |
| - if (closeStatus == (WebSocketCloseStatus)validCode) |
474 |
| - { |
475 |
| - return true; |
476 |
| - } |
477 |
| - } |
478 |
| - return false; |
479 |
| - } |
480 |
| - |
481 | 464 | public async override Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
|
482 | 465 | {
|
483 | 466 | ThrowIfDisposed();
|
@@ -617,6 +600,34 @@ private void ValidateSegment(ArraySegment<byte> buffer)
|
617 | 600 | }
|
618 | 601 | }
|
619 | 602 |
|
| 603 | + private bool ValidateOpCode(int opCode) |
| 604 | + { |
| 605 | + return Constants.OpCodes.ValidOpCodes.Contains(opCode); |
| 606 | + } |
| 607 | + |
| 608 | + private static bool ValidateCloseStatus(WebSocketCloseStatus closeStatus) |
| 609 | + { |
| 610 | + if (closeStatus < (WebSocketCloseStatus)1000 || closeStatus >= (WebSocketCloseStatus)5000) |
| 611 | + { |
| 612 | + return false; |
| 613 | + } |
| 614 | + else if (closeStatus >= (WebSocketCloseStatus)3000) |
| 615 | + { |
| 616 | + // 3000-3999 - Reserved for frameworks |
| 617 | + // 4000-4999 - Reserved for private usage |
| 618 | + return true; |
| 619 | + } |
| 620 | + int[] validCodes = new[] { 1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011 }; |
| 621 | + foreach (var validCode in validCodes) |
| 622 | + { |
| 623 | + if (closeStatus == (WebSocketCloseStatus)validCode) |
| 624 | + { |
| 625 | + return true; |
| 626 | + } |
| 627 | + } |
| 628 | + return false; |
| 629 | + } |
| 630 | + |
620 | 631 | private async Task SendErrorAbortAndThrow(WebSocketCloseStatus error, string message, CancellationToken cancellationToken)
|
621 | 632 | {
|
622 | 633 | if (State == WebSocketState.Open || State == WebSocketState.CloseReceived)
|
|
0 commit comments