From 0d5d6d2b4c518211306f296909006b6650a612e9 Mon Sep 17 00:00:00 2001 From: sta Date: Wed, 17 Sep 2014 14:50:22 +0900 Subject: [PATCH] Modified to check if valid frame was received --- websocket-sharp/Ext.cs | 2 +- websocket-sharp/WebSocket.cs | 81 ++++++++++++++----------------- websocket-sharp/WebSocketFrame.cs | 32 ++++++------ 3 files changed, 52 insertions(+), 63 deletions(-) diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index 3be026e6..6052484b 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -249,7 +249,7 @@ namespace WebSocketSharp internal static string CheckIfValidControlData (this byte[] data, string paramName) { return data.Length > 125 - ? String.Format ("'{0}' is greater than the allowable size.", paramName) + ? String.Format ("'{0}' is greater than the allowable max size.", paramName) : null; } diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 0d359821..10ef696c 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -571,6 +571,18 @@ namespace WebSocketSharp : null; } + private string checkIfValidReceivedFrame (WebSocketFrame frame) + { + var masked = frame.IsMasked; + return _client && masked + ? "A frame from the server is masked." + : !_client && !masked + ? "A frame from a client isn't masked." + : frame.IsCompressed && _compression == CompressionMethod.None + ? "A compressed frame is without the available decompression method." + : null; + } + private void close (CloseStatusCode code, string reason, bool wait) { close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait); @@ -649,18 +661,11 @@ namespace WebSocketSharp { while (true) { var frame = WebSocketFrame.Read (_stream, false); - var masked = frame.IsMasked; - if (_client && masked) - return processUnsupportedFrame ( - frame, CloseStatusCode.ProtocolError, "A frame from the server is masked."); - - if (!_client && !masked) - return processUnsupportedFrame ( - frame, CloseStatusCode.ProtocolError, "A frame from a client isn't masked."); - - if (masked) - frame.Unmask (); + var msg = checkIfValidReceivedFrame (frame); + if (msg != null) + return processUnsupportedFrame (frame, CloseStatusCode.ProtocolError, msg); + frame.Unmask (); if (frame.IsFinal) { /* FINAL */ @@ -977,6 +982,26 @@ namespace WebSocketSharp return true; } + private bool processReceivedFrame (WebSocketFrame frame) + { + var msg = checkIfValidReceivedFrame (frame); + if (msg != null) + return processUnsupportedFrame (frame, CloseStatusCode.ProtocolError, msg); + + frame.Unmask (); + return frame.IsFragmented + ? processFragmentedFrame (frame) + : frame.IsData + ? processDataFrame (frame) + : frame.IsPing + ? processPingFrame (frame) + : frame.IsPong + ? processPongFrame (frame) + : frame.IsClose + ? processCloseFrame (frame) + : processUnsupportedFrame (frame, CloseStatusCode.IncorrectData, null); + } + // As server private void processSecWebSocketExtensionsHeader (string value) { @@ -1012,38 +1037,6 @@ namespace WebSocketSharp return false; } - private bool processWebSocketFrame (WebSocketFrame frame) - { - var masked = frame.IsMasked; - if (_client && masked) - return processUnsupportedFrame ( - frame, CloseStatusCode.ProtocolError, "A frame from the server is masked."); - - if (!_client && !masked) - return processUnsupportedFrame ( - frame, CloseStatusCode.ProtocolError, "A frame from a client isn't masked."); - - if (masked) - frame.Unmask (); - - return frame.IsCompressed && _compression == CompressionMethod.None - ? processUnsupportedFrame ( - frame, - CloseStatusCode.IncorrectData, - "A compressed data has been received without available decompression method.") - : frame.IsFragmented - ? processFragmentedFrame (frame) - : frame.IsData - ? processDataFrame (frame) - : frame.IsPing - ? processPingFrame (frame) - : frame.IsPong - ? processPongFrame (frame) - : frame.IsClose - ? processCloseFrame (frame) - : processUnsupportedFrame (frame, CloseStatusCode.PolicyViolation, null); - } - // As client private void releaseClientResources () { @@ -1311,7 +1304,7 @@ namespace WebSocketSharp _stream, false, frame => { - if (processWebSocketFrame (frame) && _readyState != WebSocketState.Closed) { + if (processReceivedFrame (frame) && _readyState != WebSocketState.Closed) { receive (); if (!frame.IsData) diff --git a/websocket-sharp/WebSocketFrame.cs b/websocket-sharp/WebSocketFrame.cs index 839f97ea..3388fb5d 100644 --- a/websocket-sharp/WebSocketFrame.cs +++ b/websocket-sharp/WebSocketFrame.cs @@ -389,7 +389,7 @@ namespace WebSocketSharp ? String.Empty : payloadLen > 125 ? String.Format ("A {0} frame.", opcode.ToLower ()) - : !masked && !frame.IsFragmented && frame.IsText + : !masked && !frame.IsFragmented && !frame.IsCompressed && frame.IsText ? Encoding.UTF8.GetString (frame._payloadData.ApplicationData) : frame._payloadData.ToString (); @@ -438,21 +438,17 @@ Extended Payload Length: {7} // Payload Length var payloadLen = (byte) (header[1] & 0x7f); - // Check if correct frame. - var incorrect = isControl (opcode) && fin == Fin.More - ? "A control frame is fragmented." - : !isData (opcode) && rsv1 == Rsv.On - ? "A non data frame is compressed." - : null; + // Check if valid header + var err = isControl (opcode) && payloadLen > 125 + ? "A control frame has a payload data which is greater than the allowable max size." + : isControl (opcode) && fin == Fin.More + ? "A control frame is fragmented." + : !isData (opcode) && rsv1 == Rsv.On + ? "A non data frame is compressed." + : null; - if (incorrect != null) - throw new WebSocketException (CloseStatusCode.IncorrectData, incorrect); - - // Check if consistent frame. - if (isControl (opcode) && payloadLen > 125) - throw new WebSocketException ( - CloseStatusCode.InconsistentData, - "The length of payload data of a control frame is greater than the allowable length."); + if (err != null) + throw new WebSocketException (CloseStatusCode.ProtocolError, err); var frame = new WebSocketFrame (); frame._fin = fin; @@ -498,11 +494,11 @@ Extended Payload Length: {7} byte[] data = null; if (len > 0) { - // Check if allowable payload data length. + // Check if allowable max length. if (payloadLen > 126 && len > PayloadData.MaxLength) throw new WebSocketException ( CloseStatusCode.TooBig, - "The length of 'Payload Data' of a frame is greater than the allowable length."); + "The length of 'Payload Data' of a frame is greater than the allowable max length."); data = payloadLen > 126 ? stream.ReadBytes ((long) len, 1024) @@ -607,9 +603,9 @@ Extended Payload Length: {7} if (_mask == Mask.Unmask) return; + _mask = Mask.Unmask; _payloadData.Mask (_maskingKey); _maskingKey = new byte[0]; - _mask = Mask.Unmask; } #endregion