[WebSocket] Should raise SYNTAX_ERR when message contains unpaired surrogates
authorbashi@chromium.org <bashi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2012 09:39:56 +0000 (09:39 +0000)
committerbashi@chromium.org <bashi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2012 09:39:56 +0000 (09:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80103

Reviewed by Kent Tamura.

Source/WebCore:

Add UTF8 validation checks for WebSocket message and close reason.

Tests: http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html
       http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html

* Modules/websockets/WebSocket.cpp:
(WebCore::WebSocket::send): Raise SYNTAX_ERR if the message is invalid.
(WebCore::WebSocket::close):Raise SYNTAX_ERR if the reason is invalid.
* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::send): Check whether message is a valid UTF8 string.

LayoutTests:

Added tests for unpaired surrogates check for WebSocket message and close reason.
Updated two expectations for close() tests because further error message is added.

* http/tests/websocket/tests/hybi/close-expected.txt: Updated.
* http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason-expected.txt: Added.
* http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html: Added.
* http/tests/websocket/tests/hybi/unpaired-surrogates-in-message-expected.txt: Added.
* http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html: Added.
* http/tests/websocket/tests/hybi/workers/close-expected.txt: Updated.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@110037 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/websocket/tests/hybi/close-expected.txt
LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-message-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/workers/close-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/websockets/WebSocket.cpp
Source/WebCore/Modules/websockets/WebSocketChannel.cpp

index baec58a..26f6998 100644 (file)
@@ -1,3 +1,20 @@
+2012-03-07  Kenichi Ishibashi  <bashi@chromium.org>
+
+        [WebSocket] Should raise SYNTAX_ERR when message contains unpaired surrogates
+        https://bugs.webkit.org/show_bug.cgi?id=80103
+
+        Reviewed by Kent Tamura.
+
+        Added tests for unpaired surrogates check for WebSocket message and close reason.
+        Updated two expectations for close() tests because further error message is added.
+
+        * http/tests/websocket/tests/hybi/close-expected.txt: Updated.
+        * http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html: Added.
+        * http/tests/websocket/tests/hybi/unpaired-surrogates-in-message-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html: Added.
+        * http/tests/websocket/tests/hybi/workers/close-expected.txt: Updated.
+
 2012-03-07  Fumitoshi Ukai  <ukai@chromium.org>
 
         Unreviewed, update chromium test expectations
 2012-03-07  Fumitoshi Ukai  <ukai@chromium.org>
 
         Unreviewed, update chromium test expectations
index cfc1861..db929b0 100644 (file)
@@ -1,4 +1,6 @@
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
+CONSOLE MESSAGE: WebSocket close message is too long.
+CONSOLE MESSAGE: WebSocket close message is too long.
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
 Verify WebSocket::close behaviors.
 
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
 Verify WebSocket::close behaviors.
 
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason-expected.txt
new file mode 100644 (file)
index 0000000..eebb5c2
--- /dev/null
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: WebSocket close message contains invalid character(s).
+Checks whether SYNTAX_ERR is thrown when attemping to close the connection with unpaired surrogates.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Connected.
+PASS SYNTAX_ERR was thrown.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html b/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html
new file mode 100644 (file)
index 0000000..696494a
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script type="text/javascript">
+description("Checks whether SYNTAX_ERR is thrown when attemping to close the connection with unpaired surrogates.");
+
+window.jsTestIsAsync = true;
+if (window.layoutTestController)
+    layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
+
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/echo");
+
+ws.onopen = function()
+{
+    debug("Connected.");
+    try {
+        ws.close(1000, '\uD807');
+        testFailed('SYNTAX_ERR should be thrown.');
+    } catch(e) {
+        if (e.name == 'SYNTAX_ERR')
+            testPassed('SYNTAX_ERR was thrown.');
+        else
+            testFailed('Unexpected exception: ' + e);
+    }
+    ws.close();
+};
+
+ws.onmessage = function (event)
+{
+    var message = event.data;
+    testFailed("onmessage() was called. (message = \"" + message + "\")");
+};
+
+ws.onclose = function()
+{
+    finishJSTest();
+};
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-message-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-message-expected.txt
new file mode 100644 (file)
index 0000000..a181060
--- /dev/null
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: Websocket message contains invalid character(s).
+Checks whether SYNTAX_ERR is thrown when attemping to send unpaired surrogates.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Connected.
+PASS SYNTAX_ERR was thrown.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html b/LayoutTests/http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html
new file mode 100644 (file)
index 0000000..202f9ef
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script type="text/javascript">
+description("Checks whether SYNTAX_ERR is thrown when attemping to send unpaired surrogates.");
+
+window.jsTestIsAsync = true;
+if (window.layoutTestController)
+    layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
+
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/echo");
+
+ws.onopen = function()
+{
+    debug("Connected.");
+    try {
+        ws.send('\uD807');
+        testFailed('SYNTAX_ERR should be thrown.');
+    } catch(e) {
+        if (e.name == 'SYNTAX_ERR')
+            testPassed('SYNTAX_ERR was thrown.');
+        else
+            testFailed('Unexpected exception: ' + e);
+    }
+    ws.close();
+};
+
+ws.onmessage = function (event)
+{
+    var message = event.data;
+    testFailed("onmessage() was called. (message = \"" + message + "\")");
+    ws.close();
+};
+
+ws.onclose = function()
+{
+    finishJSTest();
+};
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
index 97e840b..bddc6de 100644 (file)
@@ -1,4 +1,6 @@
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
+CONSOLE MESSAGE: WebSocket close message is too long.
+CONSOLE MESSAGE: WebSocket close message is too long.
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
 Verify WebSocket::close behaviors in Worker.
 
 CONSOLE MESSAGE: WebSocket is closed before the connection is established.
 Verify WebSocket::close behaviors in Worker.
 
index e89c25f..1b9f10e 100644 (file)
@@ -1,3 +1,21 @@
+2012-03-07  Kenichi Ishibashi  <bashi@chromium.org>
+
+        [WebSocket] Should raise SYNTAX_ERR when message contains unpaired surrogates
+        https://bugs.webkit.org/show_bug.cgi?id=80103
+
+        Reviewed by Kent Tamura.
+
+        Add UTF8 validation checks for WebSocket message and close reason.
+
+        Tests: http/tests/websocket/tests/hybi/unpaired-surrogates-in-close-reason.html
+               http/tests/websocket/tests/hybi/unpaired-surrogates-in-message.html
+
+        * Modules/websockets/WebSocket.cpp:
+        (WebCore::WebSocket::send): Raise SYNTAX_ERR if the message is invalid.
+        (WebCore::WebSocket::close):Raise SYNTAX_ERR if the reason is invalid.
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::send): Check whether message is a valid UTF8 string.
+
 2012-03-07  Byungwoo Lee  <bw80.lee@samsung.com>
 
         [EFL] Build warning: Fix warn_unused_result warnings.
 2012-03-07  Byungwoo Lee  <bw80.lee@samsung.com>
 
         [EFL] Build warning: Fix warn_unused_result warnings.
index e9d9ce6..78183f1 100644 (file)
@@ -288,9 +288,14 @@ bool WebSocket::send(const String& message, ExceptionCode& ec)
         m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize));
         return false;
     }
         m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize));
         return false;
     }
-    // FIXME: check message is valid utf8.
     ASSERT(m_channel);
     ASSERT(m_channel);
-    return m_channel->send(message) == ThreadableWebSocketChannel::SendSuccess;
+    ThreadableWebSocketChannel::SendResult result = m_channel->send(message);
+    if (result == ThreadableWebSocketChannel::InvalidMessage) {
+        scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Websocket message contains invalid character(s).");
+        ec = SYNTAX_ERR;
+        return false;
+    }
+    return result == ThreadableWebSocketChannel::SendSuccess;
 }
 
 bool WebSocket::send(ArrayBuffer* binaryData, ExceptionCode& ec)
 }
 
 bool WebSocket::send(ArrayBuffer* binaryData, ExceptionCode& ec)
@@ -343,8 +348,15 @@ void WebSocket::close(int code, const String& reason, ExceptionCode& ec)
             ec = INVALID_ACCESS_ERR;
             return;
         }
             ec = INVALID_ACCESS_ERR;
             return;
         }
-        // FIXME: if reason contains any unpaired surrogates, raise SYNTAX_ERR.
-        if (reason.utf8().length() > maxReasonSizeInBytes) {
+        CString utf8 = reason.utf8(true);
+        if (utf8.length() > maxReasonSizeInBytes) {
+            scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "WebSocket close message is too long.");
+            ec = SYNTAX_ERR;
+            return;
+        }
+        // Checks whether reason is valid utf8.
+        if (utf8.isNull() && reason.length()) {
+            scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "WebSocket close message contains invalid character(s).");
             ec = SYNTAX_ERR;
             return;
         }
             ec = SYNTAX_ERR;
             return;
         }
index fb87d38..6c976aa 100644 (file)
@@ -160,7 +160,9 @@ String WebSocketChannel::extensions()
 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const String& message)
 {
     LOG(Network, "WebSocketChannel %p send %s", this, message.utf8().data());
 ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const String& message)
 {
     LOG(Network, "WebSocketChannel %p send %s", this, message.utf8().data());
-    CString utf8 = message.utf8();
+    CString utf8 = message.utf8(true);
+    if (utf8.isNull() && message.length())
+        return InvalidMessage;
     if (m_useHixie76Protocol) {
         return sendFrameHixie76(utf8.data(), utf8.length()) ? ThreadableWebSocketChannel::SendSuccess : ThreadableWebSocketChannel::SendFail;
     }
     if (m_useHixie76Protocol) {
         return sendFrameHixie76(utf8.data(), utf8.length()) ? ThreadableWebSocketChannel::SendSuccess : ThreadableWebSocketChannel::SendFail;
     }