Modified to check if valid frame was received

This commit is contained in:
sta 2014-09-17 14:50:22 +09:00
parent 130b0a08d0
commit 0d5d6d2b4c
3 changed files with 52 additions and 63 deletions

View File

@ -249,7 +249,7 @@ namespace WebSocketSharp
internal static string CheckIfValidControlData (this byte[] data, string paramName) internal static string CheckIfValidControlData (this byte[] data, string paramName)
{ {
return data.Length > 125 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; : null;
} }

View File

@ -571,6 +571,18 @@ namespace WebSocketSharp
: null; : 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) private void close (CloseStatusCode code, string reason, bool wait)
{ {
close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait); close (new PayloadData (((ushort) code).Append (reason)), !code.IsReserved (), wait);
@ -649,18 +661,11 @@ namespace WebSocketSharp
{ {
while (true) { while (true) {
var frame = WebSocketFrame.Read (_stream, false); var frame = WebSocketFrame.Read (_stream, false);
var masked = frame.IsMasked; var msg = checkIfValidReceivedFrame (frame);
if (_client && masked) if (msg != null)
return processUnsupportedFrame ( return processUnsupportedFrame (frame, CloseStatusCode.ProtocolError, msg);
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 (); frame.Unmask ();
if (frame.IsFinal) { if (frame.IsFinal) {
/* FINAL */ /* FINAL */
@ -977,6 +982,26 @@ namespace WebSocketSharp
return true; 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 // As server
private void processSecWebSocketExtensionsHeader (string value) private void processSecWebSocketExtensionsHeader (string value)
{ {
@ -1012,38 +1037,6 @@ namespace WebSocketSharp
return false; 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 // As client
private void releaseClientResources () private void releaseClientResources ()
{ {
@ -1311,7 +1304,7 @@ namespace WebSocketSharp
_stream, _stream,
false, false,
frame => { frame => {
if (processWebSocketFrame (frame) && _readyState != WebSocketState.Closed) { if (processReceivedFrame (frame) && _readyState != WebSocketState.Closed) {
receive (); receive ();
if (!frame.IsData) if (!frame.IsData)

View File

@ -389,7 +389,7 @@ namespace WebSocketSharp
? String.Empty ? String.Empty
: payloadLen > 125 : payloadLen > 125
? String.Format ("A {0} frame.", opcode.ToLower ()) ? 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) ? Encoding.UTF8.GetString (frame._payloadData.ApplicationData)
: frame._payloadData.ToString (); : frame._payloadData.ToString ();
@ -438,21 +438,17 @@ Extended Payload Length: {7}
// Payload Length // Payload Length
var payloadLen = (byte) (header[1] & 0x7f); var payloadLen = (byte) (header[1] & 0x7f);
// Check if correct frame. // Check if valid header
var incorrect = isControl (opcode) && fin == Fin.More 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." ? "A control frame is fragmented."
: !isData (opcode) && rsv1 == Rsv.On : !isData (opcode) && rsv1 == Rsv.On
? "A non data frame is compressed." ? "A non data frame is compressed."
: null; : null;
if (incorrect != null) if (err != null)
throw new WebSocketException (CloseStatusCode.IncorrectData, incorrect); throw new WebSocketException (CloseStatusCode.ProtocolError, err);
// 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.");
var frame = new WebSocketFrame (); var frame = new WebSocketFrame ();
frame._fin = fin; frame._fin = fin;
@ -498,11 +494,11 @@ Extended Payload Length: {7}
byte[] data = null; byte[] data = null;
if (len > 0) { if (len > 0) {
// Check if allowable payload data length. // Check if allowable max length.
if (payloadLen > 126 && len > PayloadData.MaxLength) if (payloadLen > 126 && len > PayloadData.MaxLength)
throw new WebSocketException ( throw new WebSocketException (
CloseStatusCode.TooBig, 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 data = payloadLen > 126
? stream.ReadBytes ((long) len, 1024) ? stream.ReadBytes ((long) len, 1024)
@ -607,9 +603,9 @@ Extended Payload Length: {7}
if (_mask == Mask.Unmask) if (_mask == Mask.Unmask)
return; return;
_mask = Mask.Unmask;
_payloadData.Mask (_maskingKey); _payloadData.Mask (_maskingKey);
_maskingKey = new byte[0]; _maskingKey = new byte[0];
_mask = Mask.Unmask;
} }
#endregion #endregion