REGRESSION (Safari 13): WebSocket payload is truncated when x-webkit-deflate-frame...
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Nov 2019 08:50:13 +0000 (08:50 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Nov 2019 08:50:13 +0000 (08:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202401
<rdar://problem/55922632>

Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/websocket/tests/hybi/deflate-extension.html

* Modules/websockets/WebSocketDeflater.cpp:
(WebCore::WebSocketDeflater::finish):
Make sure to continue calling deflate until all output data is flushed.

LayoutTests:

* http/tests/websocket/tests/hybi/deflate-extension-expected.txt: Added.
* http/tests/websocket/tests/hybi/deflate-extension.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/http/tests/websocket/tests/hybi/deflate-extension-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/deflate-extension.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/websockets/WebSocketDeflater.cpp

index f238480..13fbdf9 100644 (file)
@@ -1,3 +1,14 @@
+2019-11-25  Youenn Fablet  <youenn@apple.com>
+
+        REGRESSION (Safari 13): WebSocket payload is truncated when x-webkit-deflate-frame is used
+        https://bugs.webkit.org/show_bug.cgi?id=202401
+        <rdar://problem/55922632>
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/websocket/tests/hybi/deflate-extension-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/deflate-extension.html: Added.
+
 2019-11-25  youenn fablet  <youenn@apple.com>
 
         Mark imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html as Slow
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/deflate-extension-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/deflate-extension-expected.txt
new file mode 100644 (file)
index 0000000..b939547
--- /dev/null
@@ -0,0 +1,13 @@
+Test WebSocket deflate-frame extension.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS event.data is firstMessage
+PASS event.data is secondMessage
+PASS event.data is thirdMessage
+onclose() was called.
+PASS closeEvent.wasClean is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/deflate-extension.html b/LayoutTests/http/tests/websocket/tests/hybi/deflate-extension.html
new file mode 100644 (file)
index 0000000..3e0e9a8
--- /dev/null
@@ -0,0 +1,73 @@
+<!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 WebSocket deflate-frame extension.");
+
+window.jsTestIsAsync = true;
+
+var closeEvent;
+var ws;
+var messageIndex;
+
+function randomText(len) {
+    const allCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+    var randomText = ''
+    for (var i = 0; i < len; i++) {
+        var k = Math.floor(Math.random() * allCharacters.length)
+        randomText += allCharacters.charAt(k);
+    }
+    return randomText
+}
+
+var firstMessage = randomText(10000);
+var secondMessage = randomText(10000);
+var thirdMessage = randomText(10000);
+
+function doTest(queryIndex)
+{
+    var url = "ws://localhost:8880/websocket/tests/hybi/deflate-frame?max_window_bits=15";
+    ws = new WebSocket(url);
+    messageIndex = 0;
+
+    ws.onopen = function(event)
+    {
+        ws.send(firstMessage);
+    };
+
+    ws.onmessage = function(event)
+    {
+        if (messageIndex === 0) {
+            shouldBe("event.data", "firstMessage");
+            messageIndex += 1
+            ws.send(secondMessage);
+        } else if (messageIndex === 1) {
+            shouldBe("event.data", "secondMessage");
+            messageIndex += 1
+            ws.send(thirdMessage);
+        } else {
+            shouldBe("event.data", "thirdMessage");
+            ws.close();
+        }
+    };
+
+    ws.onclose = function(event)
+    {
+        debug("onclose() was called.");
+        closeEvent = event;
+        shouldBeTrue("closeEvent.wasClean");
+        finishJSTest();
+    };
+}
+
+doTest(0);
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
index 4f15a04..047f7f2 100644 (file)
@@ -1,3 +1,17 @@
+2019-11-25  Youenn Fablet  <youenn@apple.com>
+
+        REGRESSION (Safari 13): WebSocket payload is truncated when x-webkit-deflate-frame is used
+        https://bugs.webkit.org/show_bug.cgi?id=202401
+        <rdar://problem/55922632>
+
+        Reviewed by Alex Christensen.
+
+        Test: http/tests/websocket/tests/hybi/deflate-extension.html
+
+        * Modules/websockets/WebSocketDeflater.cpp:
+        (WebCore::WebSocketDeflater::finish):
+        Make sure to continue calling deflate until all output data is flushed.
+
 2019-11-24  Sunny He  <sunny_he@apple.com>
 
         Ensure SpeechSynthesis::cancel() correctly clears m_currentSpeechUtterance
index 4a4865f..b64de24 100644 (file)
@@ -101,11 +101,13 @@ bool WebSocketDeflater::finish()
         size_t availableCapacity = m_buffer.size() - writePosition;
         setStreamParameter(m_stream.get(), 0, 0, m_buffer.data() + writePosition, availableCapacity);
         int result = deflate(m_stream.get(), Z_SYNC_FLUSH);
-        m_buffer.shrink(writePosition + availableCapacity - m_stream->avail_out);
-        if (result == Z_OK)
-            break;
-        if (result != Z_BUF_ERROR)
-            return false;
+        if (m_stream->avail_out) {
+            m_buffer.shrink(writePosition + availableCapacity - m_stream->avail_out);
+            if (result == Z_OK)
+                break;
+            if (result != Z_BUF_ERROR)
+                return false;
+        }
     }
     // Remove 4 octets from the tail as the specification requires.
     if (m_buffer.size() <= 4)