2011-03-28 Maciej Stachowiak <mjs@apple.com>
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Mar 2011 07:37:30 +0000 (07:37 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Mar 2011 07:37:30 +0000 (07:37 +0000)
        Reviewed by Dan Bernstein.

        WKPageGetSourceForFrame and WKPageGetContentsAsString should throw an error in case of a race with page loading
        https://bugs.webkit.org/show_bug.cgi?id=57305
        <rdar://problem/8738060>, <rdar://problem/8780168>

        * UIProcess/WebPageProxy.cpp:
        (WebKit::WebPageProxy::close): Clear m_loadDependentStringCallbackIDs
        (WebKit::WebPageProxy::getSourceForFrame): track the callback as load dependent
        (WebKit::WebPageProxy::getContentsAsString): ditto
        (WebKit::WebPageProxy::clearLoadDependentCallbacks): Invalidate all load dependent callbacks
        (WebKit::WebPageProxy::didCommitLoadForFrame): Call clearLoadDependentCallbacks
        (WebKit::WebPageProxy::didFailLoadForFrame): ditto
        (WebKit::WebPageProxy::stringCallback): Remove callback from load dependent set if appropriate
        (WebKit::WebPageProxy::processDidCrash): Clear m_loadDependentStringCallbackIDs
        * UIProcess/WebPageProxy.h: Add m_loadDependentStringCallbackIDs hash set.

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

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h

index 4a8bb3a..76a0d33 100644 (file)
@@ -1,3 +1,22 @@
+2011-03-28  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        WKPageGetSourceForFrame and WKPageGetContentsAsString should throw an error in case of a race with page loading
+        https://bugs.webkit.org/show_bug.cgi?id=57305
+        <rdar://problem/8738060>, <rdar://problem/8780168>
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::close): Clear m_loadDependentStringCallbackIDs
+        (WebKit::WebPageProxy::getSourceForFrame): track the callback as load dependent
+        (WebKit::WebPageProxy::getContentsAsString): ditto
+        (WebKit::WebPageProxy::clearLoadDependentCallbacks): Invalidate all load dependent callbacks
+        (WebKit::WebPageProxy::didCommitLoadForFrame): Call clearLoadDependentCallbacks
+        (WebKit::WebPageProxy::didFailLoadForFrame): ditto
+        (WebKit::WebPageProxy::stringCallback): Remove callback from load dependent set if appropriate
+        (WebKit::WebPageProxy::processDidCrash): Clear m_loadDependentStringCallbackIDs
+        * UIProcess/WebPageProxy.h: Add m_loadDependentStringCallbackIDs hash set.
+
 2011-03-28  Patrick Gansterer  <paroga@webkit.org>
 
         Reviewed by Darin Adler.
index 2cb5c48..ce5cbc2 100644 (file)
@@ -323,6 +323,7 @@ void WebPageProxy::close()
     invalidateCallbackMap(m_voidCallbacks);
     invalidateCallbackMap(m_dataCallbacks);
     invalidateCallbackMap(m_stringCallbacks);
+    m_loadDependentStringCallbackIDs.clear();
     invalidateCallbackMap(m_scriptValueCallbacks);
     invalidateCallbackMap(m_computedPagesCallbacks);
 
@@ -1115,6 +1116,7 @@ void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCall
 {
     RefPtr<StringCallback> callback = prpCallback;
     uint64_t callbackID = callback->callbackID();
+    m_loadDependentStringCallbackIDs.add(callbackID);
     m_stringCallbacks.set(callbackID, callback.get());
     process()->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
 }
@@ -1123,6 +1125,7 @@ void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
 {
     RefPtr<StringCallback> callback = prpCallback;
     uint64_t callbackID = callback->callbackID();
+    m_loadDependentStringCallbackIDs.add(callbackID);
     m_stringCallbacks.set(callbackID, callback.get());
     process()->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
 }
@@ -1395,6 +1398,19 @@ void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const Resour
     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get());
 }
 
+void WebPageProxy::clearLoadDependentCallbacks()
+{
+    Vector<uint64_t> callbackIDsCopy;
+    copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
+    m_loadDependentStringCallbackIDs.clear();
+
+    for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
+        RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]);
+        if (callback)
+            callback->invalidate();
+    }
+}
+
 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, bool frameHasCustomRepresentation, const PlatformCertificateInfo& certificateInfo, CoreIPC::ArgumentDecoder* arguments)
 {
     RefPtr<APIObject> userData;
@@ -1409,6 +1425,8 @@ void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeTyp
     WebFrameProxy* frame = process()->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
+    clearLoadDependentCallbacks();
+
     frame->didCommitLoad(mimeType, certificateInfo);
 
     if (frame->isMainFrame()) {
@@ -1457,6 +1475,8 @@ void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& er
     WebFrameProxy* frame = process()->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
+    clearLoadDependentCallbacks();
+
     frame->didFailLoad();
 
     m_loaderClient.didFailLoadWithErrorForFrame(this, frame, error, userData.get());
@@ -2431,9 +2451,12 @@ void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackI
     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
     if (!callback) {
         // FIXME: Log error or assert.
+        // this can validly happen if a load invalidated the callback, though
         return;
     }
 
+    m_loadDependentStringCallbackIDs.remove(callbackID);
+
     callback->performCallbackWithReturnValue(resultString.impl());
 }
 
@@ -2555,6 +2578,7 @@ void WebPageProxy::processDidCrash()
     invalidateCallbackMap(m_voidCallbacks);
     invalidateCallbackMap(m_dataCallbacks);
     invalidateCallbackMap(m_stringCallbacks);
+    m_loadDependentStringCallbackIDs.clear();
     invalidateCallbackMap(m_scriptValueCallbacks);
     invalidateCallbackMap(m_computedPagesCallbacks);
     invalidateCallbackMap(m_validateCommandCallbacks);
index 7abda16..b37ed1b 100644 (file)
@@ -656,6 +656,8 @@ private:
     void recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString);
 #endif
 
+    void clearLoadDependentCallbacks();
+
     PageClient* m_pageClient;
     WebLoaderClient m_loaderClient;
     WebPolicyClient m_policyClient;
@@ -688,6 +690,7 @@ private:
     HashMap<uint64_t, RefPtr<VoidCallback> > m_voidCallbacks;
     HashMap<uint64_t, RefPtr<DataCallback> > m_dataCallbacks;
     HashMap<uint64_t, RefPtr<StringCallback> > m_stringCallbacks;
+    HashSet<uint64_t> m_loadDependentStringCallbackIDs;
     HashMap<uint64_t, RefPtr<ScriptValueCallback> > m_scriptValueCallbacks;
     HashMap<uint64_t, RefPtr<ComputedPagesCallback> > m_computedPagesCallbacks;
     HashMap<uint64_t, RefPtr<ValidateCommandCallback> > m_validateCommandCallbacks;