Modified: branches/safari-536.30-branch/Source/WebCore/ChangeLog (148514 => 148515)
--- branches/safari-536.30-branch/Source/WebCore/ChangeLog 2013-04-16 15:34:18 UTC (rev 148514)
+++ branches/safari-536.30-branch/Source/WebCore/ChangeLog 2013-04-16 16:07:50 UTC (rev 148515)
@@ -1,3 +1,31 @@
+2013-04-16 Lucas Forschler <[email protected]>
+
+ Merge r147938
+
+ 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-16 Andy Estes <[email protected]>
Merged r142631.
Modified: branches/safari-536.30-branch/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (148514 => 148515)
--- branches/safari-536.30-branch/Source/WebCore/Modules/websockets/WebSocketChannel.cpp 2013-04-16 15:34:18 UTC (rev 148514)
+++ branches/safari-536.30-branch/Source/WebCore/Modules/websockets/WebSocketChannel.cpp 2013-04-16 16:07:50 UTC (rev 148515)
@@ -156,6 +156,7 @@
return sendFrameHixie76(utf8.data(), utf8.length()) ? ThreadableWebSocketChannel::SendSuccess : ThreadableWebSocketChannel::SendFail;
}
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).
@@ -170,6 +171,7 @@
LOG(Network, "WebSocketChannel %p send arraybuffer %p", this, &binaryData);
ASSERT(!m_useHixie76Protocol);
enqueueRawFrame(WebSocketFrame::OpCodeBinary, static_cast<const char*>(binaryData.data()), binaryData.byteLength());
+ processOutgoingFrameQueue();
return ThreadableWebSocketChannel::SendSuccess;
}
@@ -178,6 +180,7 @@
LOG(Network, "WebSocketChannel %p send blob %s", this, binaryData.url().string().utf8().data());
ASSERT(!m_useHixie76Protocol);
enqueueBlobFrame(WebSocketFrame::OpCodeBinary, binaryData);
+ processOutgoingFrameQueue();
return ThreadableWebSocketChannel::SendSuccess;
}
@@ -186,6 +189,7 @@
LOG(Network, "WebSocketChannel %p send binary %p (%dB)", this, data, length);
ASSERT(!m_useHixie76Protocol);
enqueueRawFrame(WebSocketFrame::OpCodeBinary, data, length);
+ processOutgoingFrameQueue();
return true;
}
@@ -525,6 +529,7 @@
buf.append(reason.utf8().data(), reason.utf8().length());
}
enqueueRawFrame(WebSocketFrame::OpCodeClose, buf.data(), buf.size());
+ processOutgoingFrameQueue();
}
m_closing = true;
if (m_client)
@@ -694,6 +699,7 @@
case WebSocketFrame::OpCodePing:
enqueueRawFrame(WebSocketFrame::OpCodePong, frame.payload, frame.payloadLength);
skipBuffer(frameEnd - m_buffer);
+ processOutgoingFrameQueue();
break;
case WebSocketFrame::OpCodePong:
@@ -809,7 +815,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)
@@ -823,7 +828,6 @@
if (dataLength)
memcpy(frame->vectorData.data(), data, dataLength);
m_outgoingFrameQueue.append(frame.release());
- processOutgoingFrameQueue();
}
void WebSocketChannel::enqueueBlobFrame(WebSocketFrame::OpCode opCode, const Blob& blob)
@@ -835,7 +839,6 @@
frame->frameType = QueuedFrameTypeBlob;
frame->blobData = Blob::create(blob.url(), blob.type(), blob.size());
m_outgoingFrameQueue.append(frame.release());
- processOutgoingFrameQueue();
}
void WebSocketChannel::processOutgoingFrameQueue()