Title: [173917] releases/WebKitGTK/webkit-2.6/Source/WebCore
Revision
173917
Author
[email protected]
Date
2014-09-24 06:37:41 -0700 (Wed, 24 Sep 2014)

Log Message

Merge r173848 - WebSocket crash when a connection is closed from server side
https://bugs.webkit.org/show_bug.cgi?id=137009
rdar://problem/18333977
rdar://problem/12708225

Reviewed by Brady Eidson.

I don't think that this can be tested with our test server.

* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::WebSocketChannel): Added logging.
(WebCore::WebSocketChannel::~WebSocketChannel): Ditto.
(WebCore::WebSocketChannel::close): Protect self, because startClosingHandshake
can release the last reference.
(WebCore::WebSocketChannel::fail): Added an assertion that the channel is always
closed after this function.
(WebCore::WebSocketChannel::startClosingHandshake): Protect self, and don't change
the stack from closed back to closing if after failing to send closing handshake.
(WebCore::WebSocketChannel::processOutgoingFrameQueue): Protect self.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog (173916 => 173917)


--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog	2014-09-24 13:36:19 UTC (rev 173916)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog	2014-09-24 13:37:41 UTC (rev 173917)
@@ -1,3 +1,25 @@
+2014-09-22  Alexey Proskuryakov  <[email protected]>
+
+        WebSocket crash when a connection is closed from server side
+        https://bugs.webkit.org/show_bug.cgi?id=137009
+        rdar://problem/18333977
+        rdar://problem/12708225
+
+        Reviewed by Brady Eidson.
+
+        I don't think that this can be tested with our test server.
+
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::WebSocketChannel): Added logging.
+        (WebCore::WebSocketChannel::~WebSocketChannel): Ditto.
+        (WebCore::WebSocketChannel::close): Protect self, because startClosingHandshake
+        can release the last reference.
+        (WebCore::WebSocketChannel::fail): Added an assertion that the channel is always
+        closed after this function.
+        (WebCore::WebSocketChannel::startClosingHandshake): Protect self, and don't change
+        the stack from closed back to closing if after failing to send closing handshake.
+        (WebCore::WebSocketChannel::processOutgoingFrameQueue): Protect self.
+
 2014-09-22  David Hyatt  <[email protected]>
 
         Bad cast in isValidColumnSpanner.

Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (173916 => 173917)


--- releases/WebKitGTK/webkit-2.6/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2014-09-24 13:36:19 UTC (rev 173916)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2014-09-24 13:37:41 UTC (rev 173917)
@@ -85,10 +85,13 @@
 {
     if (Page* page = m_document->page())
         m_identifier = page->progress().createUniqueIdentifier();
+
+    LOG(Network, "WebSocketChannel %p ctor, identifier %lu", this, m_identifier);
 }
 
 WebSocketChannel::~WebSocketChannel()
 {
+    LOG(Network, "WebSocketChannel %p dtor", this);
 }
 
 void WebSocketChannel::connect(const URL& url, const String& protocol)
@@ -181,6 +184,7 @@
     ASSERT(!m_suspended);
     if (!m_handle)
         return;
+    Ref<WebSocketChannel> protect(*this); // An attempt to send closing handshake may fail, which will get the channel closed and dereferenced.
     startClosingHandshake(code, reason);
     if (m_closing && !m_closingTimer.isActive())
         m_closingTimer.startOneShot(2 * TCPMaximumSegmentLifetime);
@@ -208,6 +212,8 @@
 
     if (m_handle && !m_closed)
         m_handle->disconnect(); // Will call didClose().
+
+    ASSERT(m_closed);
 }
 
 void WebSocketChannel::disconnect()
@@ -458,6 +464,7 @@
 void WebSocketChannel::startClosingHandshake(int code, const String& reason)
 {
     LOG(Network, "WebSocketChannel %p startClosingHandshake() code=%d m_receivedClosingHandshake=%d", this, m_closing, m_receivedClosingHandshake);
+    ASSERT(!m_closed);
     if (m_closing)
         return;
     ASSERT(m_handle);
@@ -471,8 +478,14 @@
         buf.append(reason.utf8().data(), reason.utf8().length());
     }
     enqueueRawFrame(WebSocketFrame::OpCodeClose, buf.data(), buf.size());
+    Ref<WebSocketChannel> protect(*this); // An attempt to send closing handshake may fail, which will get the channel closed and dereferenced.
     processOutgoingFrameQueue();
 
+    if (m_closed) {
+        // The channel got closed because processOutgoingFrameQueue() failed.
+        return;
+    }
+
     m_closing = true;
     if (m_client)
         m_client->didStartClosingHandshake();
@@ -706,6 +719,8 @@
     if (m_outgoingFrameQueueStatus == OutgoingFrameQueueClosed)
         return;
 
+    Ref<WebSocketChannel> protect(*this); // Any call to fail() will get the channel closed and dereferenced.
+
     while (!m_outgoingFrameQueue.isEmpty()) {
         OwnPtr<QueuedFrame> frame = m_outgoingFrameQueue.takeFirst();
         switch (frame->frameType) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to