Changeset 76701 in webkit


Ignore:
Timestamp:
Jan 26, 2011 11:07:15 AM (13 years ago)
Author:
bweinstein@apple.com
Message:

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.
Location:
trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r76700 r76701  
     12011-01-25  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed byAntti Koivisto.
     4
     5        Crashes loading pages when cancelling subresource loads through WebKit
     6        https://bugs.webkit.org/show_bug.cgi?id=53123
     7        <rdar://problem/8914361>
     8       
     9        Add tests for crashing when cancelling subresource loads through WebKit via setWillSendRequestReturnsNull.
     10
     11        * fast/loader/willSendRequest-null-for-preload-expected.txt: Added.
     12        * fast/loader/willSendRequest-null-for-preload.html: Added.
     13
    1142011-01-26  Ryosuke Niwa  <rniwa@webkit.org>
    215
  • trunk/Source/WebCore/ChangeLog

    r76699 r76701  
     12011-01-25  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by Antti Koivisto.
     4
     5        Crashes loading pages when cancelling subresource loads through WebKit
     6        https://bugs.webkit.org/show_bug.cgi?id=53123
     7        <rdar://problem/8914361>
     8       
     9        Fix a crash that happened when cancelling subresource loads through WebKit.
     10       
     11        When a load is cancelled synchronously (via the WebKit client), CachedResourceLoader::requestResource
     12        can be called recursively on the same function, either leading to infinite recursion, or deleting
     13        an object when it is not done being used.
     14       
     15        The fix for this was to call checkForPendingPreloads and servePendingRequests asynchronously when
     16        CachedResourceLoader::loadDone was called synchronously (due to the load being cancelled synchronously).
     17
     18        Test: fast/loader/willSendRequest-null-for-preload.html
     19
     20        * loader/DocumentLoader.cpp:
     21        (WebCore::DocumentLoader::setRequest): Only dispatch didReceiveServerRedirectForProvisionalLoadForFrame
     22            if our new URL is non-null.
     23        * loader/cache/CachedResourceLoader.cpp:
     24        (WebCore::CachedResourceLoader::CachedResourceLoader): Initialize our timer.
     25        (WebCore::CachedResourceLoader::loadDone): If the CachedResource we were passed in was 0, that means this
     26            function was called synchronously
     27            from CachedResourceRequest::load, and we don't want to call into checkForPendingPreloads synchronously,
     28            so put it on a 0-delay timer to make the calls to checkForPendingPreloads and servePendingRequests asynchronous.
     29        (WebCore::CachedResourceLoader::loadDonePendingActionTimerFired): Call checkForPendingPreloads and servePendingRequests.
     30        (WebCore::CachedResourceLoader::checkForPendingPreloads): m_pendingPreloads is now a Deque instead of a Vector,
     31            so use Deque methods.
     32        * loader/cache/CachedResourceLoader.h: Add the timer, the timer callback function, and make m_pendingPreloads a Deque.
     33
    1342011-01-25  Pavel Podivilov  <podivilov@chromium.org>
    235
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r73436 r76701  
    169169    m_request = req;
    170170
    171     // Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed.
     171    // Only send webView:didReceiveServerRedirectForProvisionalLoadForFrame: if URL changed (and is non-null).
    172172    // Also, don't send it when replacing unreachable URLs with alternate content.
    173     if (!handlingUnreachableURL && oldURL != req.url())
     173    if (!handlingUnreachableURL && !req.url().isNull() && oldURL != req.url())
    174174        frameLoader()->didReceiveServerRedirectForProvisionalLoadForFrame();
    175175}
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r75912 r76701  
    8181    : m_document(document)
    8282    , m_requestCount(0)
     83    , m_loadDoneActionTimer(this, &CachedResourceLoader::loadDoneActionTimerFired)
    8384    , m_autoLoadImages(true)
    8485    , m_loadFinishing(false)
     
    520521    if (frame())
    521522        frame()->loader()->loadDone();
     523
     524    if (!request) {
     525        // If the request passed to this function is null, loadDone finished synchronously from when
     526        // the load was started, so we want to kick off our next set of loads (via checkForPendingPreloads
     527        // and servePendingRequests) asynchronously.
     528        m_loadDoneActionTimer.startOneShot(0);
     529        return;
     530    }
     531
     532    performPostLoadActions();
     533}
     534
     535void CachedResourceLoader::loadDoneActionTimerFired(Timer<CachedResourceLoader>*)
     536{
     537    performPostLoadActions();
     538}
     539
     540void CachedResourceLoader::performPostLoadActions()
     541{
    522542    checkForPendingPreloads();
    523543    resourceLoadScheduler()->servePendingRequests();
     
    584604void CachedResourceLoader::checkForPendingPreloads()
    585605{
    586     unsigned count = m_pendingPreloads.size();
    587     if (!count || !m_document->body() || !m_document->body()->renderer())
    588         return;
    589     for (unsigned i = 0; i < count; ++i) {
    590         PendingPreload& preload = m_pendingPreloads[i];
     606    if (m_pendingPreloads.isEmpty() || !m_document->body() || !m_document->body()->renderer())
     607        return;
     608    while (!m_pendingPreloads.isEmpty()) {
     609        PendingPreload preload = m_pendingPreloads.takeFirst();
    591610        // 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).
    592611        if (!cachedResource(m_document->completeURL(preload.m_url)))
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.h

    r76248 r76701  
    3131#include "CachePolicy.h"
    3232#include "ResourceLoadPriority.h"
     33#include "Timer.h"
     34#include <wtf/Deque.h>
    3335#include <wtf/HashMap.h>
    3436#include <wtf/HashSet.h>
     
    118120    void notifyLoadedFromMemoryCache(CachedResource*);
    119121    bool canRequest(CachedResource::Type, const KURL&);
     122
     123    void loadDoneActionTimerFired(Timer<CachedResourceLoader>*);
     124
     125    void performPostLoadActions();
    120126   
    121127    HashSet<String> m_validatedURLs;
     
    134140        String m_charset;
    135141    };
    136     Vector<PendingPreload> m_pendingPreloads;
     142    Deque<PendingPreload> m_pendingPreloads;
     143
     144    Timer<CachedResourceLoader> m_loadDoneActionTimer;
    137145   
    138146    //29 bits left
  • trunk/Source/WebKit2/ChangeLog

    r76657 r76701  
     12011-01-25  Brian Weinstein  <bweinstein@apple.com>
     2
     3        Reviewed by Antti Koivisto.
     4
     5        Crashes loading pages when cancelling subresource loads through WebKit
     6        https://bugs.webkit.org/show_bug.cgi?id=53123
     7        <rdar://problem/8914361>
     8
     9        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     10        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForMIMEType): If our URL is null, return early instead of dispatching
     11            a message.
     12
    1132011-01-25  Chris Fleizach  <cfleizach@apple.com>
    214
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r76608 r76701  
    618618    uint64_t listenerID = m_frame->setUpPolicyListener(function);
    619619    const String& url = request.url().string(); // FIXME: Pass entire request.
     620    if (!url)
     621        return;
    620622
    621623    bool receivedPolicyAction;
Note: See TracChangeset for help on using the changeset viewer.