[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198
commit-queue at webkit.org
commit-queue at webkit.org
Sun Feb 20 22:45:32 UTC 2011
The following commit has been merged in the webkit-1.3 branch:
commit d9cfa0f056d7fd06f3e12c5dd84a2b5b28493a0c
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jan 11 02:26:06 2011 +0000
2011-01-10 Joe Mason <jmason at rim.com>
Reviewed by Alexey Proskuryakov.
WebSockets: unbounded buffer growth when server sends bad data
https://bugs.webkit.org/show_bug.cgi?id=51253
Tests that a websocket handshake should fail after 1024 bytes without a
newline, or if it contains a null byte before the first newline.
* http/tests/websocket/tests/handshake-fail-by-maxlength-expected.txt: Added.
* http/tests/websocket/tests/handshake-fail-by-maxlength.html: Added.
* http/tests/websocket/tests/handshake-fail-by-maxlength_wsh.py: Added.
* http/tests/websocket/tests/handshake-fail-by-prepended-null-expected.txt: Added.
* http/tests/websocket/tests/handshake-fail-by-prepended-null.html: Added.
* http/tests/websocket/tests/handshake-fail-by-prepended-null_wsh.py: Added.
2011-01-10 Joe Mason <jmason at rim.com>
Reviewed by Alexey Proskuryakov.
WebSockets: unbounded buffer growth when server sends bad data
https://bugs.webkit.org/show_bug.cgi?id=51253
Fail a websocket handshake after 1024 bytes without a newline, or if it
contains a null byte before the first newline.
Tests: http/tests/websocket/tests/handshake-fail-by-maxlength.html
http/tests/websocket/tests/handshake-fail-by-prepended-null.html
* websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::readStatusLine):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75461 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 039789a..7820fe2 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,20 @@
+2011-01-10 Joe Mason <jmason at rim.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ WebSockets: unbounded buffer growth when server sends bad data
+ https://bugs.webkit.org/show_bug.cgi?id=51253
+
+ Tests that a websocket handshake should fail after 1024 bytes without a
+ newline, or if it contains a null byte before the first newline.
+
+ * http/tests/websocket/tests/handshake-fail-by-maxlength-expected.txt: Added.
+ * http/tests/websocket/tests/handshake-fail-by-maxlength.html: Added.
+ * http/tests/websocket/tests/handshake-fail-by-maxlength_wsh.py: Added.
+ * http/tests/websocket/tests/handshake-fail-by-prepended-null-expected.txt: Added.
+ * http/tests/websocket/tests/handshake-fail-by-prepended-null.html: Added.
+ * http/tests/websocket/tests/handshake-fail-by-prepended-null_wsh.py: Added.
+
2011-01-10 Jer Noble <jer.noble at apple.com>
Reviewed by Simon Fraser.
diff --git a/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength-expected.txt b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength-expected.txt
new file mode 100644
index 0000000..61ee73b
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength-expected.txt
@@ -0,0 +1,12 @@
+CONSOLE MESSAGE: line 0: Status line is too long
+Connection should fail immediately, rather than succeeding or staying in limbo until timeout, if handshake is longer than 1024 bytes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS timedOut is false
+PASS connected is false
+PASS origin is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength.html b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength.html
new file mode 100644
index 0000000..66cbfd0
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../js-test-resources/js-test-style.css">
+<script src="../../../js-test-resources/js-test-pre.js"></script>
+<script src="../../../js-test-resources/js-test-post-function.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description('Connection should fail immediately, rather than succeeding or staying in limbo until timeout, if handshake is longer than 1024 bytes.');
+
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone()
+
+var timedOut = false;
+var connected = false;
+var origin;
+
+function endTest() {
+ shouldBeFalse('timedOut');
+ shouldBeFalse('connected');
+ shouldBeUndefined('origin');
+ clearTimeout(timeoutID);
+ isSuccessfullyParsed();
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+
+var url = 'ws://localhost:8880/websocket/tests/handshake-fail-by-maxlength';
+var ws = new WebSocket(url);
+
+ws.onopen = function()
+{
+ debug('Connected');
+ connected = true;
+}
+
+ws.onmessage = function(messageEvent)
+{
+ origin = messageEvent.data;
+ debug('origin = ' + origin);
+ ws.close();
+}
+
+ws.onclose = function()
+{
+ endTest();
+}
+
+function timeoutCallback()
+{
+ debug('Timed out (state = ' + ws.readyState + ')');
+ timedOut = true;
+ endTest();
+}
+
+var timeoutID = setTimeout(timeoutCallback, 3000);
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength_wsh.py b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength_wsh.py
new file mode 100644
index 0000000..fc7ffb5
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-maxlength_wsh.py
@@ -0,0 +1,44 @@
+# Copyright (C) Research In Motion Limited 2011. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+# disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
+# following disclaimer in the documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import time
+
+def web_socket_do_extra_handshake(request):
+ # This will cause the handshake to fail because it pushes the length of the
+ # status line past 1024 characters
+ msg = ""
+ for i in range(0, 1024):
+ msg += "."
+ msg += 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n'
+ msg += 'Upgrade: WebSocket\r\n'
+ msg += 'Connection: Upgrade\r\n'
+ msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n'
+ msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n'
+ msg += '\r\n'
+ msg += request.ws_challenge_md5
+ request.connection.write(msg)
+ # continue writing data until the client disconnects
+ while True:
+ time.sleep(1)
+ request.connection.write('keepalive\n')
+
+def web_socket_transfer_data(request):
+ pass
diff --git a/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null-expected.txt b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null-expected.txt
new file mode 100644
index 0000000..5db17c8
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null-expected.txt
@@ -0,0 +1,12 @@
+CONSOLE MESSAGE: line 0: Status line contains embedded null
+Connection should fail immediately, rather than succeeding or staying in limbo until timeout, if a null byte is received before the handshake.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS timedOut is false
+PASS connected is false
+PASS origin is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null.html b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null.html
new file mode 100644
index 0000000..f728ede
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../js-test-resources/js-test-style.css">
+<script src="../../../js-test-resources/js-test-pre.js"></script>
+<script src="../../../js-test-resources/js-test-post-function.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description('Connection should fail immediately, rather than succeeding or staying in limbo until timeout, if a null byte is received before the handshake.');
+
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone()
+
+var timedOut = false;
+var connected = false;
+var origin;
+
+function endTest() {
+ shouldBeFalse('timedOut');
+ shouldBeFalse('connected');
+ shouldBeUndefined('origin');
+ clearTimeout(timeoutID);
+ isSuccessfullyParsed();
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+
+var url = 'ws://localhost:8880/websocket/tests/handshake-fail-by-prepended-null';
+var ws = new WebSocket(url);
+
+ws.onopen = function()
+{
+ debug('Connected');
+ connected = true;
+}
+
+ws.onmessage = function(messageEvent)
+{
+ origin = messageEvent.data;
+ debug('origin = ' + origin);
+ ws.close();
+}
+
+ws.onclose = function()
+{
+ endTest();
+}
+
+function timeoutCallback()
+{
+ debug('Timed out (state = ' + ws.readyState + ')');
+ timedOut = true;
+ endTest();
+}
+
+var timeoutID = setTimeout(timeoutCallback, 3000);
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null_wsh.py b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null_wsh.py
new file mode 100644
index 0000000..84c2b97
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/tests/handshake-fail-by-prepended-null_wsh.py
@@ -0,0 +1,49 @@
+# Copyright (C) Research In Motion Limited 2011. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
+# following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+# disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
+# following disclaimer in the documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import time
+
+def web_socket_do_extra_handshake(request):
+ # This simulates a broken server that sends a WebSocket frame before the
+ # handshake, and more frames afterwards. It is important that if this
+ # happens the client does not buffer all the frames as the server continues
+ # to send more data - it should abort after reading a reasonable number of
+ # bytes (set arbitrarily to 1024).
+ frame = '\0Frame-contains-thirty-two-bytes'
+
+ msg = frame
+ msg += 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n'
+ msg += 'Upgrade: WebSocket\r\n'
+ msg += 'Connection: Upgrade\r\n'
+ msg += 'Sec-WebSocket-Location: ' + request.ws_location + '\r\n'
+ msg += 'Sec-WebSocket-Origin: ' + request.ws_origin + '\r\n'
+ msg += '\r\n'
+ msg += request.ws_challenge_md5
+ request.connection.write(msg)
+ # continue writing data until the client disconnects
+ while True:
+ time.sleep(1)
+ numFrames = 1024 / len(frame) # write over 1024 bytes including the above handshake
+ for i in range(0, numFrames):
+ request.connection.write(frame)
+
+def web_socket_transfer_data(request):
+ pass
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index e450f66..0e9a4f6 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2011-01-10 Joe Mason <jmason at rim.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ WebSockets: unbounded buffer growth when server sends bad data
+ https://bugs.webkit.org/show_bug.cgi?id=51253
+
+ Fail a websocket handshake after 1024 bytes without a newline, or if it
+ contains a null byte before the first newline.
+
+ Tests: http/tests/websocket/tests/handshake-fail-by-maxlength.html
+ http/tests/websocket/tests/handshake-fail-by-prepended-null.html
+
+ * websockets/WebSocketHandshake.cpp:
+ (WebCore::WebSocketHandshake::readStatusLine):
+
2011-01-10 Adam Barth <abarth at webkit.org>
Reviewed by Darin Adler.
diff --git a/Source/WebCore/websockets/WebSocketHandshake.cpp b/Source/WebCore/websockets/WebSocketHandshake.cpp
index 5049098..9506ad4 100644
--- a/Source/WebCore/websockets/WebSocketHandshake.cpp
+++ b/Source/WebCore/websockets/WebSocketHandshake.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -427,6 +428,10 @@ KURL WebSocketHandshake::httpURLForAuthenticationAndCookies() const
// statusCode and statusText will be set to -1 and a null string, respectively.
int WebSocketHandshake::readStatusLine(const char* header, size_t headerLength, int& statusCode, String& statusText)
{
+ // Arbitrary size limit to prevent the server from sending an unbounded
+ // amount of data with no newlines and forcing us to buffer it all.
+ static const int maximumLength = 1024;
+
statusCode = -1;
statusText = String();
@@ -441,6 +446,12 @@ int WebSocketHandshake::readStatusLine(const char* header, size_t headerLength,
space1 = p;
else if (!space2)
space2 = p;
+ } else if (*p == '\0') {
+ // The caller isn't prepared to deal with null bytes in status
+ // line. WebSockets specification doesn't prohibit this, but HTTP
+ // does, so we'll just treat this as an error.
+ m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line contains embedded null", 0, clientOrigin());
+ return p + 1 - header;
} else if (*p == '\n')
break;
}
@@ -448,9 +459,9 @@ int WebSocketHandshake::readStatusLine(const char* header, size_t headerLength,
return -1; // We have not received '\n' yet.
const char* end = p + 1;
- if (end - header > INT_MAX) {
- m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line is too long: " + trimConsoleMessage(header, maxConsoleMessageSize + 1), 0, clientOrigin());
- return INT_MAX;
+ if (end - header > maximumLength) {
+ m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Status line is too long", 0, clientOrigin());
+ return maximumLength;
}
int lineLength = end - header;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list