Title: [147938] trunk/Source/WebCore
Revision
147938
Author
[email protected]
Date
2013-04-08 11:17:19 -0700 (Mon, 08 Apr 2013)

Log Message

        <rdar://problem/12834449> Crashes in WebSocketChannel::processFrame when processing a ping
        https://bugs.webkit.org/show_bug.cgi?id=114178

        Reviewed by Brady Eidson.

        No test, I could never reproduce even manually.

        Calling enqueueRawFrame() could change incoming buffer, so a subsequent skipBuffer()
        would operate on wrong assumptions. This happened because enqueueRawFrame() actually
        tried to process the queue, and send failure sometimed clears m_buffer.

        Fixing this by decoupling enqueuing from sending, and making sure that skipBuffer()
        in ping frame processing case is performed at a safe time.

        * Modules/websockets/WebSocketChannel.cpp:
        (WebCore::WebSocketChannel::send):
        (WebCore::WebSocketChannel::startClosingHandshake):
        (WebCore::WebSocketChannel::processFrame):
        (WebCore::WebSocketChannel::enqueueTextFrame):
        (WebCore::WebSocketChannel::enqueueRawFrame):
        (WebCore::WebSocketChannel::enqueueBlobFrame):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (147937 => 147938)


--- trunk/Source/WebCore/ChangeLog	2013-04-08 18:09:01 UTC (rev 147937)
+++ trunk/Source/WebCore/ChangeLog	2013-04-08 18:17:19 UTC (rev 147938)
@@ -1,3 +1,27 @@
+2013-04-08  Alexey Proskuryakov  <[email protected]>
+
+        <rdar://problem/12834449> Crashes in WebSocketChannel::processFrame when processing a ping
+        https://bugs.webkit.org/show_bug.cgi?id=114178
+
+        Reviewed by Brady Eidson.
+
+        No test, I could never reproduce even manually.
+
+        Calling enqueueRawFrame() could change incoming buffer, so a subsequent skipBuffer()
+        would operate on wrong assumptions. This happened because enqueueRawFrame() actually
+        tried to process the queue, and send failure sometimed clears m_buffer.
+
+        Fixing this by decoupling enqueuing from sending, and making sure that skipBuffer()
+        in ping frame processing case is performed at a safe time.
+
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::send):
+        (WebCore::WebSocketChannel::startClosingHandshake):
+        (WebCore::WebSocketChannel::processFrame):
+        (WebCore::WebSocketChannel::enqueueTextFrame):
+        (WebCore::WebSocketChannel::enqueueRawFrame):
+        (WebCore::WebSocketChannel::enqueueBlobFrame):
+
 2013-04-08  Max Vujovic  <[email protected]>
 
         REGRESSION (r147502): Animations of CA filters broken

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (147937 => 147938)


--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2013-04-08 18:09:01 UTC (rev 147937)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2013-04-08 18:17:19 UTC (rev 147938)
@@ -140,6 +140,7 @@
     LOG(Network, "WebSocketChannel %p send() Sending String '%s'", this, message.utf8().data());
     CString utf8 = message.utf8(String::StrictConversionReplacingUnpairedSurrogatesWithFFFD);
     enqueueTextFrame(utf8);
+    processOutgoingFrameQueue();
     // According to WebSocket API specification, WebSocket.send() should return void instead
     // of boolean. However, our implementation still returns boolean due to compatibility
     // concern (see bug 65850).
@@ -153,6 +154,7 @@
 {
     LOG(Network, "WebSocketChannel %p send() Sending ArrayBuffer %p byteOffset=%u byteLength=%u", this, &binaryData, byteOffset, byteLength);
     enqueueRawFrame(WebSocketFrame::OpCodeBinary, static_cast<const char*>(binaryData.data()) + byteOffset, byteLength);
+    processOutgoingFrameQueue();
     return ThreadableWebSocketChannel::SendSuccess;
 }
 
@@ -160,6 +162,7 @@
 {
     LOG(Network, "WebSocketChannel %p send() Sending Blob '%s'", this, binaryData.url().elidedString().utf8().data());
     enqueueBlobFrame(WebSocketFrame::OpCodeBinary, binaryData);
+    processOutgoingFrameQueue();
     return ThreadableWebSocketChannel::SendSuccess;
 }
 
@@ -167,6 +170,7 @@
 {
     LOG(Network, "WebSocketChannel %p send() Sending char* data="" length=%d", this, data, length);
     enqueueRawFrame(WebSocketFrame::OpCodeBinary, data, length);
+    processOutgoingFrameQueue();
     return true;
 }
 
@@ -479,6 +483,7 @@
         buf.append(reason.utf8().data(), reason.utf8().length());
     }
     enqueueRawFrame(WebSocketFrame::OpCodeClose, buf.data(), buf.size());
+    processOutgoingFrameQueue();
 
     m_closing = true;
     if (m_client)
@@ -658,6 +663,7 @@
     case WebSocketFrame::OpCodePing:
         enqueueRawFrame(WebSocketFrame::OpCodePong, frame.payload, frame.payloadLength);
         skipBuffer(frameEnd - m_buffer.data());
+        processOutgoingFrameQueue();
         break;
 
     case WebSocketFrame::OpCodePong:
@@ -683,7 +689,6 @@
     frame->frameType = QueuedFrameTypeString;
     frame->stringData = string;
     m_outgoingFrameQueue.append(frame.release());
-    processOutgoingFrameQueue();
 }
 
 void WebSocketChannel::enqueueRawFrame(WebSocketFrame::OpCode opCode, const char* data, size_t dataLength)
@@ -696,7 +701,6 @@
     if (dataLength)
         memcpy(frame->vectorData.data(), data, dataLength);
     m_outgoingFrameQueue.append(frame.release());
-    processOutgoingFrameQueue();
 }
 
 void WebSocketChannel::enqueueBlobFrame(WebSocketFrame::OpCode opCode, const Blob& blob)
@@ -707,7 +711,6 @@
     frame->frameType = QueuedFrameTypeBlob;
     frame->blobData = Blob::create(blob.url(), blob.type(), blob.size());
     m_outgoingFrameQueue.append(frame.release());
-    processOutgoingFrameQueue();
 }
 
 void WebSocketChannel::processOutgoingFrameQueue()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to