[WebSocket]The minimal number of bytes MUST be used to encode the length
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Mar 2012 06:04:00 +0000 (06:04 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Mar 2012 06:04:00 +0000 (06:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=81443

Patch by Li Yin <li.yin@intel.com> on 2012-03-22
Reviewed by Kent Tamura.

Source/WebCore:

From RFC 6455 http://tools.ietf.org/html/rfc6455#section-5.2
the minimal number of bytes MUST be used to encode the length

New test case : http/tests/websocket/tests/hybi/invalid-encode-length.html

* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::parseFrame):

LayoutTests:

* http/tests/websocket/tests/hybi/invalid-encode-length-expected.txt: Added.
* http/tests/websocket/tests/hybi/invalid-encode-length.html: Added.
* http/tests/websocket/tests/hybi/invalid-encode-length_wsh.py: Added.
(web_socket_do_extra_handshake):
(web_socket_transfer_data):

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

LayoutTests/ChangeLog
LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length_wsh.py [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/websockets/WebSocketChannel.cpp

index b0df402..512cf5b 100644 (file)
@@ -1,3 +1,16 @@
+2012-03-22  Li Yin  <li.yin@intel.com>
+
+        [WebSocket]The minimal number of bytes MUST be used to encode the length
+        https://bugs.webkit.org/show_bug.cgi?id=81443
+
+        Reviewed by Kent Tamura.
+
+        * http/tests/websocket/tests/hybi/invalid-encode-length-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/invalid-encode-length.html: Added.
+        * http/tests/websocket/tests/hybi/invalid-encode-length_wsh.py: Added.
+        (web_socket_do_extra_handshake):
+        (web_socket_transfer_data):
+
 2012-03-22  Mao Yujie  <yujie.mao@intel.com>
 
         Implement strict testing criterion for callback function definition
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length-expected.txt
new file mode 100644 (file)
index 0000000..ca2a9ca
--- /dev/null
@@ -0,0 +1,28 @@
+CONSOLE MESSAGE: The minimal number of bytes MUST be used to encode the length
+CONSOLE MESSAGE: The minimal number of bytes MUST be used to encode the length
+CONSOLE MESSAGE: The minimal number of bytes MUST be used to encode the length
+CONSOLE MESSAGE: The minimal number of bytes MUST be used to encode the length
+Test whether WebSocket aborts the connection when it receives an unexpected encoding length frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Case 126_125: Test started.
+onopen() was called.
+onclose() was called.
+PASS closeEvent.wasClean is false
+Case 126_0: Test started.
+onopen() was called.
+onclose() was called.
+PASS closeEvent.wasClean is false
+Case 127_65535: Test started.
+onopen() was called.
+onclose() was called.
+PASS closeEvent.wasClean is false
+Case 127_0: Test started.
+onopen() was called.
+onclose() was called.
+PASS closeEvent.wasClean is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length.html b/LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length.html
new file mode 100644 (file)
index 0000000..7c49427
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src="../../../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Test whether WebSocket aborts the connection when it receives an unexpected encoding length frame.");
+
+window.jsTestIsAsync = true;
+if (window.layoutTestController)
+    layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
+
+var closeEvent;
+var payload_extended = ["126_125", "126_0", "127_65535", "127_0"];
+var totalTestSize = 4;
+
+function doTest(curTest)
+{
+    var url = "ws://127.0.0.1:8880/websocket/tests/hybi/invalid-encode-length?case=" + payload_extended[curTest];
+    var ws = new WebSocket(url);
+
+    debug("Case " + payload_extended[curTest] + ": Test started.");
+
+    ws.onopen = function()
+    {
+        debug("onopen() was called.");
+    };
+
+    ws.onmessage = function(event)
+    {
+        var message = event.data;
+        testFailed("onmessage() was called. (message = \"" + message + "\")");
+    };
+
+    ws.onclose = function(event)
+    {
+        debug("onclose() was called.");
+        closeEvent = event;
+        shouldBeFalse("closeEvent.wasClean");
+        if (curTest == totalTestSize - 1)
+            finishJSTest();
+        else
+            doTest(curTest + 1);
+    };
+}
+
+doTest(0);
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length_wsh.py b/LayoutTests/http/tests/websocket/tests/hybi/invalid-encode-length_wsh.py
new file mode 100644 (file)
index 0000000..92bdea4
--- /dev/null
@@ -0,0 +1,32 @@
+import re
+import struct
+from mod_pywebsocket import common
+
+
+def web_socket_do_extra_handshake(request):
+    pass
+
+
+def web_socket_transfer_data(request):
+    match = re.search(r'\?case=(\d+_\d+)$', request.ws_resource)
+    if match is None:
+        msgutil.send_message(request, 'FAIL: Query value is incorrect or missing')
+        return
+
+    payload_length, extended_length = (match.group(1)).split('_', 1)
+    payload_length = int(payload_length)
+    extended_length = int(extended_length)
+
+    # pywebsocket refuses to create a frame with error encode length.
+    # Thus, we need to build a frame manually.
+    header = chr(0x80 | common.OPCODE_TEXT) # 0x80 is for "fin" bit.
+    header += chr(payload_length) # No Mask and two bytes extended payload length.
+    if payload_length == 126:
+        header += struct.pack('!H', extended_length)
+    elif payload_length == 127:
+        header += struct.pack('!Q', extended_length)
+    else:
+        msgutil.send_message(request, 'FAIL: Query value is incorrect or missing')
+        return
+    request.connection.write(header)
+    request.connection.write('X' * extended_length)
index fcf8743..ea9b323 100644 (file)
@@ -1,3 +1,18 @@
+2012-03-22  Li Yin  <li.yin@intel.com>
+
+        [WebSocket]The minimal number of bytes MUST be used to encode the length
+        https://bugs.webkit.org/show_bug.cgi?id=81443
+
+        Reviewed by Kent Tamura.
+
+        From RFC 6455 http://tools.ietf.org/html/rfc6455#section-5.2
+        the minimal number of bytes MUST be used to encode the length
+        
+        New test case : http/tests/websocket/tests/hybi/invalid-encode-length.html
+
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::parseFrame):
+
 2012-03-22  Adam Barth  <abarth@webkit.org>
 
         Unreviewed.  Sort xcodeproj file.
index 7611862..124e6bd 100644 (file)
@@ -585,6 +585,14 @@ WebSocketChannel::ParseFrameResult WebSocketChannel::parseFrame(WebSocketFrame&
             payloadLength64 <<= 8;
             payloadLength64 |= static_cast<unsigned char>(*p++);
         }
+        if (extendedPayloadLengthSize == 2 && payloadLength64 <= maxPayloadLengthWithoutExtendedLengthField) {
+            fail("The minimal number of bytes MUST be used to encode the length");
+            return FrameError;
+        }
+        if (extendedPayloadLengthSize == 8 && payloadLength64 <= 0xFFFF) {
+            fail("The minimal number of bytes MUST be used to encode the length");
+            return FrameError;
+        }
     }
 
     // FIXME: UINT64_C(0x7FFFFFFFFFFFFFFF) should be used but it did not compile on Qt bots.