Title: [188976] trunk/Source/_javascript_Core
Revision
188976
Author
bb...@apple.com
Date
2015-08-26 11:53:36 -0700 (Wed, 26 Aug 2015)

Log Message

Web Inspector: REGRESSION(r188965): BackendDispatcher loses request ids when called re-entrantly
https://bugs.webkit.org/show_bug.cgi?id=148480

Reviewed by Joseph Pecoraro.

I added an assertion that m_currentRequestId is Nullopt when dispatch() is called, but this should
not hold if dispatching a backend command while debugger is paused. I will remove the assertion
and add proper scoping for all dispatch() branches.

No new tests, this wrong assert caused inspector/dom-debugger/node-removed.html to crash reliably.

* inspector/InspectorBackendDispatcher.cpp:
(Inspector::BackendDispatcher::dispatch): Cover each exit with an appropriate TemporaryChange scope.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (188975 => 188976)


--- trunk/Source/_javascript_Core/ChangeLog	2015-08-26 18:52:44 UTC (rev 188975)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-08-26 18:53:36 UTC (rev 188976)
@@ -1,3 +1,19 @@
+2015-08-26  Brian Burg  <bb...@apple.com>
+
+        Web Inspector: REGRESSION(r188965): BackendDispatcher loses request ids when called re-entrantly
+        https://bugs.webkit.org/show_bug.cgi?id=148480
+
+        Reviewed by Joseph Pecoraro.
+
+        I added an assertion that m_currentRequestId is Nullopt when dispatch() is called, but this should
+        not hold if dispatching a backend command while debugger is paused. I will remove the assertion
+        and add proper scoping for all dispatch() branches.
+
+        No new tests, this wrong assert caused inspector/dom-debugger/node-removed.html to crash reliably.
+
+        * inspector/InspectorBackendDispatcher.cpp:
+        (Inspector::BackendDispatcher::dispatch): Cover each exit with an appropriate TemporaryChange scope.
+
 2015-08-26  Sukolsak Sakshuwong  <sukol...@gmail.com>
 
         Remove the unused *Executable::unlinkCalls() and CodeBlock::unlinkCalls()

Modified: trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.cpp (188975 => 188976)


--- trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.cpp	2015-08-26 18:52:44 UTC (rev 188975)
+++ trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.cpp	2015-08-26 18:53:36 UTC (rev 188976)
@@ -86,72 +86,81 @@
 
     ASSERT(!m_protocolErrors.size());
 
-    RefPtr<InspectorValue> parsedMessage;
-    if (!InspectorValue::parseJSON(message, parsedMessage)) {
-        reportProtocolError(ParseError, ASCIILiteral("Message must be in JSON format"));
-        sendPendingErrors();
-        return;
-    }
-
+    long requestId = 0;
     RefPtr<InspectorObject> messageObject;
-    if (!parsedMessage->asObject(messageObject)) {
-        reportProtocolError(InvalidRequest, ASCIILiteral("Message must be a JSONified object"));
-        sendPendingErrors();
-        return;
-    }
 
-    RefPtr<InspectorValue> requestIdValue;
-    if (!messageObject->getValue(ASCIILiteral("id"), requestIdValue)) {
-        reportProtocolError(InvalidRequest, ASCIILiteral("'id' property was not found"));
-        sendPendingErrors();
-        return;
-    }
+    {
+        // In case this is a re-entrant call from a nested run loop, we don't want to lose
+        // the outer request's id just because the inner request is bogus.
+        TemporaryChange<Optional<long>> scopedRequestId(m_currentRequestId, Nullopt);
 
-    long requestId = 0;
-    if (!requestIdValue->asInteger(requestId)) {
-        reportProtocolError(InvalidRequest, ASCIILiteral("The type of 'id' property must be integer"));
-        sendPendingErrors();
-        return;
-    }
+        RefPtr<InspectorValue> parsedMessage;
+        if (!InspectorValue::parseJSON(message, parsedMessage)) {
+            reportProtocolError(ParseError, ASCIILiteral("Message must be in JSON format"));
+            sendPendingErrors();
+            return;
+        }
 
-    ASSERT(!m_currentRequestId);
-    TemporaryChange<Optional<long>> scopedRequestId(m_currentRequestId, requestId);
+        if (!parsedMessage->asObject(messageObject)) {
+            reportProtocolError(InvalidRequest, ASCIILiteral("Message must be a JSONified object"));
+            sendPendingErrors();
+            return;
+        }
 
-    RefPtr<InspectorValue> methodValue;
-    if (!messageObject->getValue(ASCIILiteral("method"), methodValue)) {
-        reportProtocolError(InvalidRequest, ASCIILiteral("'method' property wasn't found"));
-        sendPendingErrors();
-        return;
-    }
+        RefPtr<InspectorValue> requestIdValue;
+        if (!messageObject->getValue(ASCIILiteral("id"), requestIdValue)) {
+            reportProtocolError(InvalidRequest, ASCIILiteral("'id' property was not found"));
+            sendPendingErrors();
+            return;
+        }
 
-    String methodString;
-    if (!methodValue->asString(methodString)) {
-        reportProtocolError(InvalidRequest, ASCIILiteral("The type of 'method' property must be string"));
-        sendPendingErrors();
-        return;
+        if (!requestIdValue->asInteger(requestId)) {
+            reportProtocolError(InvalidRequest, ASCIILiteral("The type of 'id' property must be integer"));
+            sendPendingErrors();
+            return;
+        }
     }
 
-    Vector<String> domainAndMethod;
-    methodString.split('.', true, domainAndMethod);
-    if (domainAndMethod.size() != 2 || !domainAndMethod[0].length() || !domainAndMethod[1].length()) {
-        reportProtocolError(InvalidRequest, ASCIILiteral("The 'method' property was formatted incorrectly. It should be 'Domain.method'"));
-        sendPendingErrors();
-        return;
-    }
+    {
+        // We could be called re-entrantly from a nested run loop, so restore the previous id.
+        TemporaryChange<Optional<long>> scopedRequestId(m_currentRequestId, requestId);
 
-    String domain = domainAndMethod[0];
-    SupplementalBackendDispatcher* domainDispatcher = m_dispatchers.get(domain);
-    if (!domainDispatcher) {
-        reportProtocolError(MethodNotFound, "'" + domain + "' domain was not found");
-        sendPendingErrors();
-        return;
-    }
+        RefPtr<InspectorValue> methodValue;
+        if (!messageObject->getValue(ASCIILiteral("method"), methodValue)) {
+            reportProtocolError(InvalidRequest, ASCIILiteral("'method' property wasn't found"));
+            sendPendingErrors();
+            return;
+        }
 
-    String method = domainAndMethod[1];
-    domainDispatcher->dispatch(requestId, method, messageObject.releaseNonNull());
+        String methodString;
+        if (!methodValue->asString(methodString)) {
+            reportProtocolError(InvalidRequest, ASCIILiteral("The type of 'method' property must be string"));
+            sendPendingErrors();
+            return;
+        }
 
-    if (m_protocolErrors.size())
-        sendPendingErrors();
+        Vector<String> domainAndMethod;
+        methodString.split('.', true, domainAndMethod);
+        if (domainAndMethod.size() != 2 || !domainAndMethod[0].length() || !domainAndMethod[1].length()) {
+            reportProtocolError(InvalidRequest, ASCIILiteral("The 'method' property was formatted incorrectly. It should be 'Domain.method'"));
+            sendPendingErrors();
+            return;
+        }
+
+        String domain = domainAndMethod[0];
+        SupplementalBackendDispatcher* domainDispatcher = m_dispatchers.get(domain);
+        if (!domainDispatcher) {
+            reportProtocolError(MethodNotFound, "'" + domain + "' domain was not found");
+            sendPendingErrors();
+            return;
+        }
+
+        String method = domainAndMethod[1];
+        domainDispatcher->dispatch(requestId, method, messageObject.releaseNonNull());
+
+        if (m_protocolErrors.size())
+            sendPendingErrors();
+    }
 }
 
 void BackendDispatcher::sendResponse(long requestId, RefPtr<InspectorObject>&& result)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to