Commit 3ce3939f authored by bweinstein@apple.com's avatar bweinstein@apple.com

Source/WebCore: Crashes loading pages when cancelling subresource loads through WebKit

https://bugs.webkit.org/show_bug.cgi?id=53123
<rdar://problem/8914361>
        
Reviewed by Antti Koivisto.

Fix a crash that happened when cancelling subresource loads through WebKit.
        
When a load is cancelled synchronously (via the WebKit client), CachedResourceLoader::requestResource 
can be called recursively on the same function, either leading to infinite recursion, or deleting 
an object when it is not done being used.
        
The fix for this was to call checkForPendingPreloads and servePendingRequests asynchronously when 
CachedResourceLoader::loadDone was called synchronously (due to the load being cancelled synchronously).

Test: fast/loader/willSendRequest-null-for-preload.html

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::setRequest): Only dispatch didReceiveServerRedirectForProvisionalLoadForFrame 
    if our new URL is non-null.
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::CachedResourceLoader): Initialize our timer.
(WebCore::CachedResourceLoader::loadDone): If the CachedResource we were passed in was 0, that means this 
    function was called synchronously
    from CachedResourceRequest::load, and we don't want to call into checkForPendingPreloads synchronously, 
    so put it on a 0-delay timer to make the calls to checkForPendingPreloads and servePendingRequests asynchronous.
(WebCore::CachedResourceLoader::loadDonePendingActionTimerFired): Call checkForPendingPreloads and servePendingRequests.
(WebCore::CachedResourceLoader::checkForPendingPreloads): m_pendingPreloads is now a Deque instead of a Vector, 
    so use Deque methods.
* loader/cache/CachedResourceLoader.h: Add the timer, the timer callback function, and make m_pendingPreloads a Deque.

Source/WebKit2: Crashes loading pages when cancelling subresource loads through WebKit
https://bugs.webkit.org/show_bug.cgi?id=53123
<rdar://problem/8914361>

Reviewed by Antti Koivisto.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForMIMEType): If our URL is null, return early instead of dispatching
    a message.

LayoutTests: Reviewed byAntti Koivisto.

Crashes loading pages when cancelling subresource loads through WebKit
https://bugs.webkit.org/show_bug.cgi?id=53123
<rdar://problem/8914361>
        
Add tests for crashing when cancelling subresource loads through WebKit via setWillSendRequestReturnsNull.

* fast/loader/willSendRequest-null-for-preload-expected.txt: Added.
* fast/loader/willSendRequest-null-for-preload.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76701 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent db205667
2011-01-25 Brian Weinstein <bweinstein@apple.com>
Reviewed byAntti Koivisto.
Crashes loading pages when cancelling subresource loads through WebKit
https://bugs.webkit.org/show_bug.cgi?id=53123
<rdar://problem/8914361>
Add tests for crashing when cancelling subresource loads through WebKit via setWillSendRequestReturnsNull.
* fast/loader/willSendRequest-null-for-preload-expected.txt: Added.
* fast/loader/willSendRequest-null-for-preload.html: Added.
2011-01-26 Ryosuke Niwa <rniwa@webkit.org>
Unreviewed Chromium Linux rebaselines for r76688.
......
Blocked access to external URL http://www.example.com/
Test for Bug 53123: Crashes loading pages when cancelling subresource loads through WebKit. If the test doesn't crash, then it has passed. It must be run in DRT.
<!DOCTYPE html>
<html>
<head>
<title>Bug 53123: Crashes loading pages when cancelling subresource loads through WebKit</title>
<script type="text/javascript" src="http://www.example.com"></script>
<script>
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.setWillSendRequestReturnsNull(true);
}
</script>
</head>
<body>
<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=53123">Bug 53123: Crashes loading pages when cancelling subresource loads through WebKit</a>.
If the test doesn't crash, then it has passed. It must be run in DRT.</p>
<script src="http://www.example.org" type="text/javascript"></script>
</body>
</html>
CONSOLE MESSAGE: line 1: SyntaxError: Parse error
Test for Bug 53123: Crashes loading pages when cancelling subresource loads through WebKit. If the test doesn't crash, then it has passed. It must be run in DRT.
2011-01-25 Brian Weinstein <bweinstein@apple.com>
Reviewed by Antti Koivisto.
Crashes loading pages when cancelling subresource loads through WebKit
https://bugs.webkit.org/show_bug.cgi?id=53123
<rdar://problem/8914361>
Fix a crash that happened when cancelling subresource loads through WebKit.
When a load is cancelled synchronously (via the WebKit client), CachedResourceLoader::requestResource
can be called recursively on the same function, either leading to infinite recursion, or deleting
an object when it is not done being used.
The fix for this was to call checkForPendingPreloads and servePendingRequests asynchronously when
CachedResourceLoader::loadDone was called synchronously (due to the load being cancelled synchronously).
Test: fast/loader/willSendRequest-null-for-preload.html
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::setRequest): Only dispatch didReceiveServerRedirectForProvisionalLoadForFrame
if our new URL is non-null.
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::CachedResourceLoader): Initialize our timer.
(WebCore::CachedResourceLoader::loadDone): If the CachedResource we were passed in was 0, that means this
function was called synchronously
from CachedResourceRequest::load, and we don't want to call into checkForPendingPreloads synchronously,
so put it on a 0-delay timer to make the calls to checkForPendingPreloads and servePendingRequests asynchronous.
(WebCore::CachedResourceLoader::loadDonePendingActionTimerFired): Call checkForPendingPreloads and servePendingRequests.
(WebCore::CachedResourceLoader::checkForPendingPreloads): m_pendingPreloads is now a Deque instead of a Vector,
so use Deque methods.
* loader/cache/CachedResourceLoader.h: Add the timer, the timer callback function, and make m_pendingPreloads a Deque.
2011-01-25 Pavel Podivilov <podivilov@chromium.org>
Reviewed by Pavel Feldman.
......@@ -168,9 +168,9 @@ void DocumentLoader::setRequest(const ResourceRequest& req)
KURL oldURL = m_request.url();
m_request = req;
// Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed.
// Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed (and is non-null).
// Also, don't send it when replacing unreachable URLs with alternate content.
if (!handlingUnreachableURL && oldURL != req.url())
if (!handlingUnreachableURL && !req.url().isNull() && oldURL != req.url())
frameLoader()->didReceiveServerRedirectForProvisionalLoadForFrame();
}
......
......@@ -80,6 +80,7 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url
CachedResourceLoader::CachedResourceLoader(Document* document)
: m_document(document)
, m_requestCount(0)
, m_loadDoneActionTimer(this, &CachedResourceLoader::loadDoneActionTimerFired)
, m_autoLoadImages(true)
, m_loadFinishing(false)
, m_allowStaleResources(false)
......@@ -519,6 +520,25 @@ void CachedResourceLoader::loadDone(CachedResourceRequest* request)
m_requests.remove(request);
if (frame())
frame()->loader()->loadDone();
if (!request) {
// If the request passed to this function is null, loadDone finished synchronously from when
// the load was started, so we want to kick off our next set of loads (via checkForPendingPreloads
// and servePendingRequests) asynchronously.
m_loadDoneActionTimer.startOneShot(0);
return;
}
performPostLoadActions();
}
void CachedResourceLoader::loadDoneActionTimerFired(Timer<CachedResourceLoader>*)
{
performPostLoadActions();
}
void CachedResourceLoader::performPostLoadActions()
{
checkForPendingPreloads();
resourceLoadScheduler()->servePendingRequests();
}
......@@ -583,11 +603,10 @@ void CachedResourceLoader::preload(CachedResource::Type type, const String& url,
void CachedResourceLoader::checkForPendingPreloads()
{
unsigned count = m_pendingPreloads.size();
if (!count || !m_document->body() || !m_document->body()->renderer())
if (m_pendingPreloads.isEmpty() || !m_document->body() || !m_document->body()->renderer())
return;
for (unsigned i = 0; i < count; ++i) {
PendingPreload& preload = m_pendingPreloads[i];
while (!m_pendingPreloads.isEmpty()) {
PendingPreload preload = m_pendingPreloads.takeFirst();
// Don't request preload if the resource already loaded normally (this will result in double load if the page is being reloaded with cached results ignored).
if (!cachedResource(m_document->completeURL(preload.m_url)))
requestPreload(preload.m_type, preload.m_url, preload.m_charset);
......
......@@ -30,6 +30,8 @@
#include "CachedResourceHandle.h"
#include "CachePolicy.h"
#include "ResourceLoadPriority.h"
#include "Timer.h"
#include <wtf/Deque.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/ListHashSet.h>
......@@ -117,6 +119,10 @@ private:
void notifyLoadedFromMemoryCache(CachedResource*);
bool canRequest(CachedResource::Type, const KURL&);
void loadDoneActionTimerFired(Timer<CachedResourceLoader>*);
void performPostLoadActions();
HashSet<String> m_validatedURLs;
mutable DocumentResourceMap m_documentResources;
......@@ -133,7 +139,9 @@ private:
String m_url;
String m_charset;
};
Vector<PendingPreload> m_pendingPreloads;
Deque<PendingPreload> m_pendingPreloads;
Timer<CachedResourceLoader> m_loadDoneActionTimer;
//29 bits left
bool m_autoLoadImages : 1;
......
2011-01-25 Brian Weinstein <bweinstein@apple.com>
Reviewed by Antti Koivisto.
Crashes loading pages when cancelling subresource loads through WebKit
https://bugs.webkit.org/show_bug.cgi?id=53123
<rdar://problem/8914361>
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForMIMEType): If our URL is null, return early instead of dispatching
a message.
2011-01-25 Chris Fleizach <cfleizach@apple.com>
Reviewed by Darin Adler.
......@@ -617,6 +617,8 @@ void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction f
uint64_t listenerID = m_frame->setUpPolicyListener(function);
const String& url = request.url().string(); // FIXME: Pass entire request.
if (!url)
return;
bool receivedPolicyAction;
uint64_t policyAction;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment