Diff
Modified: trunk/LayoutTests/ChangeLog (118722 => 118723)
--- trunk/LayoutTests/ChangeLog 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/LayoutTests/ChangeLog 2012-05-29 05:15:23 UTC (rev 118723)
@@ -1,3 +1,18 @@
+2012-05-28 Takashi Toyoshima <[email protected]>
+
+ [WebSocket] Receiving reserved close codes, 1005, 1006, and 1015 must appear as code=1006 and wasClean=false
+ https://bugs.webkit.org/show_bug.cgi?id=87084
+
+ Reviewed by Kent Tamura.
+
+ Add test cases where server initiates a closing handshake with forbidden status codes.
+
+ * http/tests/websocket/tests/hybi/close-code-and-reason-expected.txt:
+ * http/tests/websocket/tests/hybi/close-code-and-reason.html:
+ * http/tests/websocket/tests/hybi/workers/close-code-and-reason-expected.txt:
+ * http/tests/websocket/tests/hybi/workers/resources/close-code-and-reason.js:
+ (WebSocketTest.prototype.onclose):
+
2012-05-28 Kent Tamura <[email protected]>
Form controls in <fieldset disabled> should not be validated.
Modified: trunk/LayoutTests/http/tests/websocket/tests/hybi/close-code-and-reason-expected.txt (118722 => 118723)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/close-code-and-reason-expected.txt 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/close-code-and-reason-expected.txt 2012-05-29 05:15:23 UTC (rev 118723)
@@ -1,4 +1,8 @@
CONSOLE MESSAGE: WebSocket is closed before the connection is established.
+CONSOLE MESSAGE: Received a broken close frame containing an invalid size body.
+CONSOLE MESSAGE: Received a broken close frame containing a reserved status code.
+CONSOLE MESSAGE: Received a broken close frame containing a reserved status code.
+CONSOLE MESSAGE: Received a broken close frame containing a reserved status code.
Test CloseEvent code and reason property.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -9,25 +13,74 @@
PASS closeEvent.reason is emptyString
WebSocketTest.onopen() was called with testId = 0.
WebSocketTest.onclose() was called with testId = 0.
+PASS typeof closeEvent.wasClean is 'boolean'
PASS closeEvent.wasClean is true
-PASS closeEvent.code is expectedCode[testId]
-PASS closeEvent.reason is expectedReason[testId]
-PASS closeEvent.code is expectedCode[testId]
-PASS closeEvent.reason is expectedReason[testId]
+PASS closeEvent.code is 1005
+PASS closeEvent.reason is ''
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is true
+PASS closeEvent.code is 1005
+PASS closeEvent.reason is ''
WebSocketTest.onopen() was called with testId = 1.
WebSocketTest.onclose() was called with testId = 1.
-PASS closeEvent.wasClean is true
-PASS closeEvent.code is expectedCode[testId]
-PASS closeEvent.reason is expectedReason[testId]
-PASS closeEvent.code is expectedCode[testId]
-PASS closeEvent.reason is expectedReason[testId]
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
WebSocketTest.onopen() was called with testId = 2.
WebSocketTest.onclose() was called with testId = 2.
+PASS typeof closeEvent.wasClean is 'boolean'
PASS closeEvent.wasClean is true
-PASS closeEvent.code is expectedCode[testId]
-PASS closeEvent.reason is expectedReason[testId]
-PASS closeEvent.code is expectedCode[testId]
-PASS closeEvent.reason is expectedReason[testId]
+PASS closeEvent.code is 1000
+PASS closeEvent.reason is 'ok'
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is true
+PASS closeEvent.code is 1000
+PASS closeEvent.reason is 'ok'
+WebSocketTest.onopen() was called with testId = 3.
+WebSocketTest.onclose() was called with testId = 3.
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+WebSocketTest.onopen() was called with testId = 4.
+WebSocketTest.onclose() was called with testId = 4.
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+WebSocketTest.onopen() was called with testId = 5.
+WebSocketTest.onclose() was called with testId = 5.
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is false
+PASS closeEvent.code is 1006
+PASS closeEvent.reason is ''
+WebSocketTest.onopen() was called with testId = 6.
+WebSocketTest.onclose() was called with testId = 6.
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is true
+PASS closeEvent.code is 65535
+PASS closeEvent.reason is 'good bye'
+PASS typeof closeEvent.wasClean is 'boolean'
+PASS closeEvent.wasClean is true
+PASS closeEvent.code is 65535
+PASS closeEvent.reason is 'good bye'
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/http/tests/websocket/tests/hybi/close-code-and-reason.html (118722 => 118723)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/close-code-and-reason.html 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/close-code-and-reason.html 2012-05-29 05:15:23 UTC (rev 118723)
@@ -14,6 +14,7 @@
layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
var closeEvent;
+var codeNormalClosure = 1000;
var codeNoStatusRcvd = 1005;
var codeAbnormalClosure = 1006;
var emptyString = "";
@@ -37,22 +38,43 @@
ws.close();
var testId = 0;
-var testNum = 3;
+var testNum = 7;
var sendData = [
"-", // request close frame without code and reason
"--", // request close frame with invalid body which size is 1
+ "1000 ok", // request close frame with code 1000 and reason
+ "1005 foo", // request close frame with forbidden code 1005 and reason
+ "1006 bar", // request close frame with forbidden code 1006 and reason
+ "1015 baz", // request clode frame with forbidden code 1015 and reason
"65535 good bye", // request close frame with specified code and reason
];
var expectedCode = [
codeNoStatusRcvd,
- codeNoStatusRcvd,
+ codeAbnormalClosure,
+ codeNormalClosure,
+ codeAbnormalClosure,
+ codeAbnormalClosure,
+ codeAbnormalClosure,
65535,
];
var expectedReason = [
- "",
- "",
- "good bye",
+ "''",
+ "''",
+ "'ok'",
+ "''",
+ "''",
+ "''",
+ "'good bye'",
];
+var expectedWasClean = [
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+];
WebSocketTest = function() {
this.ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/close-code-and-reason");
@@ -76,13 +98,15 @@
{
closeEvent = event;
debug("WebSocketTest.onclose() was called with testId = " + testId + ".");
- shouldBeTrue("closeEvent.wasClean");
- shouldBe("closeEvent.code", "expectedCode[testId]");
- shouldBe("closeEvent.reason", "expectedReason[testId]");
+ shouldEvaluateTo("closeEvent.wasClean", expectedWasClean[testId]);
+ shouldEvaluateTo("closeEvent.code", expectedCode[testId]);
+ shouldEvaluateTo("closeEvent.reason", expectedReason[testId]);
closeEvent.code = 0;
closeEvent.reason = "readonly";
- shouldBe("closeEvent.code", "expectedCode[testId]");
- shouldBe("closeEvent.reason", "expectedReason[testId]");
+ closeEvent.wasClean = !closeEvent.wasClean;
+ shouldEvaluateTo("closeEvent.wasClean", expectedWasClean[testId]);
+ shouldEvaluateTo("closeEvent.code", expectedCode[testId]);
+ shouldEvaluateTo("closeEvent.reason", expectedReason[testId]);
testId++;
if (testId < testNum)
test = new WebSocketTest();
Modified: trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/close-code-and-reason-expected.txt (118722 => 118723)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/close-code-and-reason-expected.txt 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/close-code-and-reason-expected.txt 2012-05-29 05:15:23 UTC (rev 118723)
@@ -1,4 +1,8 @@
CONSOLE MESSAGE: WebSocket is closed before the connection is established.
+CONSOLE MESSAGE: Received a broken close frame containing an invalid size body.
+CONSOLE MESSAGE: Received a broken close frame containing a reserved status code.
+CONSOLE MESSAGE: Received a broken close frame containing a reserved status code.
+CONSOLE MESSAGE: Received a broken close frame containing a reserved status code.
Test CloseEvent code and reason property in Worker.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -12,20 +16,55 @@
PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 1005
PASS PASS: worker: event.reason is
+PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 1005
PASS PASS: worker: event.reason is
WebSocketTest.onopen() was called with testId = 1.
WebSocketTest.onclose() was called with testId = 1.
-PASS PASS: worker: event.wasClean is true
-PASS PASS: worker: event.code is 1005
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
PASS PASS: worker: event.reason is
-PASS PASS: worker: event.code is 1005
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
PASS PASS: worker: event.reason is
WebSocketTest.onopen() was called with testId = 2.
WebSocketTest.onclose() was called with testId = 2.
PASS PASS: worker: event.wasClean is true
+PASS PASS: worker: event.code is 1000
+PASS PASS: worker: event.reason is ok
+PASS PASS: worker: event.wasClean is true
+PASS PASS: worker: event.code is 1000
+PASS PASS: worker: event.reason is ok
+WebSocketTest.onopen() was called with testId = 3.
+WebSocketTest.onclose() was called with testId = 3.
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
+PASS PASS: worker: event.reason is
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
+PASS PASS: worker: event.reason is
+WebSocketTest.onopen() was called with testId = 4.
+WebSocketTest.onclose() was called with testId = 4.
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
+PASS PASS: worker: event.reason is
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
+PASS PASS: worker: event.reason is
+WebSocketTest.onopen() was called with testId = 5.
+WebSocketTest.onclose() was called with testId = 5.
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
+PASS PASS: worker: event.reason is
+PASS PASS: worker: event.wasClean is false
+PASS PASS: worker: event.code is 1006
+PASS PASS: worker: event.reason is
+WebSocketTest.onopen() was called with testId = 6.
+WebSocketTest.onclose() was called with testId = 6.
+PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 65535
PASS PASS: worker: event.reason is good bye
+PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 65535
PASS PASS: worker: event.reason is good bye
DONE
Modified: trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/close-code-and-reason.js (118722 => 118723)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/close-code-and-reason.js 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/close-code-and-reason.js 2012-05-29 05:15:23 UTC (rev 118723)
@@ -1,3 +1,4 @@
+var codeNormalClosure = 1000;
var codeNoStatusRcvd = 1005;
var codeAbnormalClosure = 1006;
var emptyString = "";
@@ -30,22 +31,43 @@
ws.close();
var testId = 0;
-var testNum = 3;
+var testNum = 7;
var sendData = [
"-", // request close frame without code and reason
"--", // request close frame with invalid body which size is 1
+ "1000 ok", // request close frame with code 1000 and reason
+ "1005 foo", // request close frame with forbidden code 1005 and reason
+ "1006 bar", // request close frame with forbidden code 1006 and reason
+ "1015 baz", // request close frame with forbidden code 1015 and reason
"65535 good bye", // request close frame with specified code and reason
];
var expectedCode = [
codeNoStatusRcvd,
- codeNoStatusRcvd,
+ codeAbnormalClosure,
+ codeNormalClosure,
+ codeAbnormalClosure,
+ codeAbnormalClosure,
+ codeAbnormalClosure,
65535,
];
var expectedReason = [
"",
"",
+ "ok",
+ "",
+ "",
+ "",
"good bye",
];
+var expectedWasClean = [
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ true,
+];
WebSocketTest = function() {
this.ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/close-code-and-reason");
@@ -68,11 +90,13 @@
WebSocketTest.prototype._onclose_ = function(event)
{
postMessage("WebSocketTest.onclose() was called with testId = " + testId + ".");
- postResult(event.wasClean, "event.wasClean", "true");
+ postResult(event.wasClean == expectedWasClean[testId], "event.wasClean", expectedWasClean[testId]);
postResult(event.code == expectedCode[testId], "event.code", expectedCode[testId]);
postResult(event.reason == expectedReason[testId], "event.reason", expectedReason[testId]);
event.code = 0;
event.reason = "readonly";
+ event.wasClean = !event.wasClean;
+ postResult(event.wasClean == expectedWasClean[testId], "event.wasClean", expectedWasClean[testId]);
postResult(event.code == expectedCode[testId], "event.code", expectedCode[testId]);
postResult(event.reason == expectedReason[testId], "event.reason", expectedReason[testId]);
testId++;
Modified: trunk/Source/WebCore/ChangeLog (118722 => 118723)
--- trunk/Source/WebCore/ChangeLog 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/Source/WebCore/ChangeLog 2012-05-29 05:15:23 UTC (rev 118723)
@@ -1,3 +1,21 @@
+2012-05-28 Takashi Toyoshima <[email protected]>
+
+ [WebSocket] Receiving reserved close codes, 1005, 1006, and 1015 must appear as code=1006 and wasClean=false
+ https://bugs.webkit.org/show_bug.cgi?id=87084
+
+ Reviewed by Kent Tamura.
+
+ Status codes 1005, 1006, and 1015 are forbidden to be sent in actual close frames.
+ If a client received these frames, the client should handle them as broken.
+ Close frames containing invalid body size are the same as these forbidden cases.
+ Update close-code-and-reason tests to verify this patch.
+
+ * Modules/websockets/WebSocket.cpp: Handle AbnormalClosure as wasClean == false
+ (WebCore::WebSocket::didClose):
+ * Modules/websockets/WebSocketChannel.cpp: Handle close frames' status code carefully
+ (WebCore::WebSocketChannel::processFrame):
+ * Modules/websockets/WebSocketChannel.h: Update on newly defined close event codes
+
2012-05-28 Kentaro Hara <[email protected]>
[V8] Avoid passing NULL to an 'isolate' parameter
Modified: trunk/Source/WebCore/Modules/websockets/WebSocket.cpp (118722 => 118723)
--- trunk/Source/WebCore/Modules/websockets/WebSocket.cpp 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/Source/WebCore/Modules/websockets/WebSocket.cpp 2012-05-29 05:15:23 UTC (rev 118723)
@@ -557,6 +557,8 @@
if (!m_channel)
return;
bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && closingHandshakeCompletion == ClosingHandshakeComplete;
+ if (!m_useHixie76Protocol)
+ wasClean = wasClean && code != WebSocketChannel::CloseEventCodeAbnormalClosure;
m_state = CLOSED;
m_bufferedAmount = unhandledBufferedAmount;
ASSERT(scriptExecutionContext());
Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (118722 => 118723)
--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp 2012-05-29 05:15:23 UTC (rev 118723)
@@ -674,12 +674,22 @@
break;
case WebSocketFrame::OpCodeClose:
- if (frame.payloadLength >= 2) {
+ if (!frame.payloadLength)
+ m_closeEventCode = CloseEventCodeNoStatusRcvd;
+ else if (frame.payloadLength == 1) {
+ m_closeEventCode = CloseEventCodeAbnormalClosure;
+ fail("Received a broken close frame containing an invalid size body.");
+ return false;
+ } else {
unsigned char highByte = static_cast<unsigned char>(frame.payload[0]);
unsigned char lowByte = static_cast<unsigned char>(frame.payload[1]);
m_closeEventCode = highByte << 8 | lowByte;
- } else
- m_closeEventCode = CloseEventCodeNoStatusRcvd;
+ if (m_closeEventCode == CloseEventCodeNoStatusRcvd || m_closeEventCode == CloseEventCodeAbnormalClosure || m_closeEventCode == CloseEventCodeTLSHandshake) {
+ m_closeEventCode = CloseEventCodeAbnormalClosure;
+ fail("Received a broken close frame containing a reserved status code.");
+ return false;
+ }
+ }
if (frame.payloadLength >= 3)
m_closeEventReason = String::fromUTF8(&frame.payload[2], frame.payloadLength - 2);
else
Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.h (118722 => 118723)
--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.h 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.h 2012-05-29 05:15:23 UTC (rev 118723)
@@ -102,7 +102,12 @@
CloseEventCodeFrameTooLarge = 1004,
CloseEventCodeNoStatusRcvd = 1005,
CloseEventCodeAbnormalClosure = 1006,
- CloseEventCodeInvalidUTF8 = 1007,
+ CloseEventCodeInvalidFramePayloadData = 1007,
+ CloseEventCodePolicyViolation = 1008,
+ CloseEventCodeMessageTooBig = 1009,
+ CloseEventCodeMandatoryExt = 1010,
+ CloseEventCodeInternalError = 1011,
+ CloseEventCodeTLSHandshake = 1015,
CloseEventCodeMinimumUserDefined = 3000,
CloseEventCodeMaximumUserDefined = 4999
};
Modified: trunk/Source/WebKit/chromium/ChangeLog (118722 => 118723)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-05-29 05:15:23 UTC (rev 118723)
@@ -1,3 +1,14 @@
+2012-05-28 Takashi Toyoshima <[email protected]>
+
+ [WebSocket] Receiving reserved close codes, 1005, 1006, and 1015 must appear as code=1006 and wasClean=false
+ https://bugs.webkit.org/show_bug.cgi?id=87084
+
+ Reviewed by Kent Tamura.
+
+ Update close event codes corresponding to WebSocketChannel::CloseEventCode.
+
+ * public/WebSocket.h: Update on newly defined close event codes
+
2012-05-28 MORITA Hajime <[email protected]>
Rename FrameLoaderClient::shadowDOMAllowed() to allowShadowDOM()
Modified: trunk/Source/WebKit/chromium/public/WebSocket.h (118722 => 118723)
--- trunk/Source/WebKit/chromium/public/WebSocket.h 2012-05-29 04:11:05 UTC (rev 118722)
+++ trunk/Source/WebKit/chromium/public/WebSocket.h 2012-05-29 05:15:23 UTC (rev 118723)
@@ -55,7 +55,12 @@
CloseEventCodeFrameTooLarge = 1004,
CloseEventCodeNoStatusRcvd = 1005,
CloseEventCodeAbnormalClosure = 1006,
- CloseEventCodeInvalidUTF8 = 1007,
+ CloseEventCodeInvalidFramePayloadData = 1007,
+ CloseEventCodePolicyViolation = 1008,
+ CloseEventCodeMessageTooBig = 1009,
+ CloseEventCodeMandatoryExt = 1010,
+ CloseEventCodeInternalError = 1011,
+ CloseEventCodeTLSHandshake = 1015,
CloseEventCodeMinimumUserDefined = 3000,
CloseEventCodeMaximumUserDefined = 4999
};