From 57031224e7a52eb0ca31cc82d5c7369d121aa336 Mon Sep 17 00:00:00 2001 From: Guerrieri Date: Wed, 20 Dec 2017 11:43:50 +0100 Subject: [PATCH 1/4] Fix continuation frame When a continuation frame is received it checks if there is something to continue. --- websocket-sharp/WebSocket.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 7effc8852..d8a8f683d 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -1065,6 +1065,11 @@ private bool checkReceivedFrame (WebSocketFrame frame, out string message) return false; } + if (frame.Opcode == 0x0 && !_inContinuation) { + message = "A continuation frame has been received but there is nothing to continue."; + return false; + } + if (frame.Rsv2 == Rsv.On) { message = "The RSV2 of a frame is non-zero without any negotiation for it."; return false; From 1eda7e3621c2c874370bd0b212e96a3fc8f6e2fe Mon Sep 17 00:00:00 2001 From: Guerrieri Date: Wed, 20 Dec 2017 11:48:22 +0100 Subject: [PATCH 2/4] Fix close code Update the list of invalid close code, that have not to receives any close message. --- websocket-sharp/Ext.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index cb6565fc1..da4f71bc0 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -496,18 +496,14 @@ internal static bool IsPortNumber (this int value) internal static bool IsReserved (this ushort code) { - return code == 1004 - || code == 1005 - || code == 1006 - || code == 1015; + return !( (code > 999 && code < 1004) + || (code > 1006 && code < 1012) + || (code > 2999 && code < 5000) ); } internal static bool IsReserved (this CloseStatusCode code) { - return code == CloseStatusCode.Undefined - || code == CloseStatusCode.NoStatus - || code == CloseStatusCode.Abnormal - || code == CloseStatusCode.TlsHandshakeFailure; + return IsReserved ((ushort)code); } internal static bool IsSupported (this byte opcode) From b3ab3914c9ef03123910baf715b7370ea7e23802 Mon Sep 17 00:00:00 2001 From: Guerrieri Date: Wed, 20 Dec 2017 12:03:13 +0100 Subject: [PATCH 3/4] Fix Invalid UTF8 message Changing from 'Encoding.UTF8' to 'UTF8Encoding' in order to throw an exception if the UTF8 dedoded message is invalid. The setData() function is moved to the constructors so that the exceptions that can be throw by the decoder are managed by the already implemented try-catch --- websocket-sharp/Ext.cs | 16 ++++++---------- websocket-sharp/MessageEventArgs.cs | 4 ++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index da4f71bc0..d0d560c0d 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -69,6 +69,7 @@ public static class Ext private static readonly byte[] _last = new byte[] { 0x00 }; private static readonly int _retry = 5; private const string _tspecials = "()<>@,;:\\\"/[]?={} \t"; + private static UTF8Encoding _utf8 = new UTF8Encoding (false, true); #endregion @@ -156,7 +157,7 @@ internal static byte[] Append (this ushort code, string reason) var ret = code.InternalToByteArray (ByteOrder.Big); if (reason != null && reason.Length > 0) { var buff = new List (ret); - buff.AddRange (Encoding.UTF8.GetBytes (reason)); + buff.AddRange (_utf8.GetBytes (reason)); ret = buff.ToArray (); } @@ -957,7 +958,7 @@ internal static bool TryGetUTF8DecodedString (this byte[] bytes, out string s) s = null; try { - s = Encoding.UTF8.GetString (bytes); + s = _utf8.GetString (bytes); } catch { return false; @@ -971,7 +972,7 @@ internal static bool TryGetUTF8EncodedBytes (this string s, out byte[] bytes) bytes = null; try { - bytes = Encoding.UTF8.GetBytes (s); + bytes = _utf8.GetBytes (s); } catch { return false; @@ -1014,17 +1015,12 @@ internal static string Unquote (this string value) internal static string UTF8Decode (this byte[] bytes) { - try { - return Encoding.UTF8.GetString (bytes); - } - catch { - return null; - } + return _utf8.GetString (bytes); } internal static byte[] UTF8Encode (this string s) { - return Encoding.UTF8.GetBytes (s); + return _utf8.GetBytes (s); } internal static void WriteBytes (this Stream stream, byte[] bytes, int bufferLength) diff --git a/websocket-sharp/MessageEventArgs.cs b/websocket-sharp/MessageEventArgs.cs index adf7391aa..445283425 100644 --- a/websocket-sharp/MessageEventArgs.cs +++ b/websocket-sharp/MessageEventArgs.cs @@ -61,6 +61,7 @@ internal MessageEventArgs (WebSocketFrame frame) { _opcode = frame.Opcode; _rawData = frame.PayloadData.ApplicationData; + setData (); } internal MessageEventArgs (Opcode opcode, byte[] rawData) @@ -70,6 +71,7 @@ internal MessageEventArgs (Opcode opcode, byte[] rawData) _opcode = opcode; _rawData = rawData; + setData (); } #endregion @@ -103,7 +105,6 @@ internal Opcode Opcode { /// public string Data { get { - setData (); return _data; } } @@ -152,7 +153,6 @@ public bool IsText { /// public byte[] RawData { get { - setData (); return _rawData; } } From e20eca4c7434bffa67a7689d9811a24bc42f43a8 Mon Sep 17 00:00:00 2001 From: Guerrieri Date: Wed, 20 Dec 2017 12:28:29 +0100 Subject: [PATCH 4/4] Fix invalid utf8 close payload Handle close frame in cases where utf8 payload is invalid --- websocket-sharp/WebSocket.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index d8a8f683d..5cca863bb 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -1580,8 +1580,19 @@ private bool ping (byte[] data) private bool processCloseFrame (WebSocketFrame frame) { - var payload = frame.PayloadData; - close (payload, !payload.HasReservedCode, false, true); + try { + PayloadData payload; + + if (frame.PayloadData.Length > 1) + payload = new PayloadData (frame.PayloadData.Code, frame.PayloadData.Reason); + else + payload = frame.PayloadData; + + close (payload, !payload.HasReservedCode, false, true); + } + catch { + close (1002, String.Empty); + } return false; }