|
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