Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Crash in 3rd party WebKit apps that disable cache at a wrong time

https://bugs.webkit.org/show_bug.cgi?id=86027
<rdar://problem/10615880>

Reviewed by Antti Koivisto.

Source/WebCore:

Added an API test.

The fix is to use CachedResourceHandle throughout MemoryCache, which will certainly
keep the resource alive. Also removed earlier fixes.

* css/CSSImageSetValue.cpp: (WebCore::CSSImageSetValue::cachedImageSet):
* css/CSSImageValue.cpp: (WebCore::CSSImageValue::cachedImage):
* css/WebKitCSSShaderValue.cpp: (WebCore::WebKitCSSShaderValue::cachedShader):
* history/PageCache.cpp: (WebCore::PageCache::releaseAutoreleasedPagesNow):
* loader/ImageLoader.cpp: (WebCore::ImageLoader::updateFromElement):
* loader/TextTrackLoader.cpp: (WebCore::TextTrackLoader::load):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestImage):
(WebCore::CachedResourceLoader::requestFont):
(WebCore::CachedResourceLoader::requestTextTrack):
(WebCore::CachedResourceLoader::requestShader):
(WebCore::CachedResourceLoader::requestCSSStyleSheet):
(WebCore::CachedResourceLoader::requestUserCSSStyleSheet):
(WebCore::CachedResourceLoader::requestScript):
(WebCore::CachedResourceLoader::requestXSLStyleSheet):
(WebCore::CachedResourceLoader::requestSVGDocument):
(WebCore::CachedResourceLoader::requestLinkResource):
(WebCore::CachedResourceLoader::requestRawResource):
(WebCore::CachedResourceLoader::requestResource):
(WebCore::CachedResourceLoader::revalidateResource):
(WebCore::CachedResourceLoader::loadResource):
(WebCore::CachedResourceLoader::requestPreload):
* loader/cache/CachedResourceLoader.h: (CachedResourceLoader):
* loader/cache/MemoryCache.h: (WebCore::MemoryCache::setPruneEnabled):

* loader/cache/CachedResourceHandle.h:
(WebCore::CachedResourceHandle::CachedResourceHandle):
(WebCore::CachedResourceHandle::operator=):
Teach CachedResourceHandle how to make CachedResourceHandle<CachedResource> from
a handle to subclass.

Tools:

Added a test that's very similar to MemoryCachePruneWithinResourceLoadDelegate,
but for disabling the cache instead of triggering a prune.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.html: Added.
* TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.mm: Added.
(-[MemoryCacheDisableTestResourceLoadDelegate webView:identifierForInitialRequest:fromDataSource:]):
(-[MemoryCacheDisableTestResourceLoadDelegate webView:resource:willSendRequest:redirectResponse:fromDataSource:]):
(-[MemoryCacheDisableTestResourceLoadDelegate webView:resource:didFinishLoadingFromDataSource:]):
(-[MemoryCacheDisableTestResourceLoadDelegate webView:resource:didFailLoadingWithError:fromDataSource:]):
(TestWebKitAPI::TEST):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@116719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information...
commit 6edc42b47be2a920302bcbfc6a4fcfcd227b63c3 1 parent 6f2377d
authored
44  Source/WebCore/ChangeLog
... ...
@@ -1,3 +1,47 @@
  1
+2012-05-10  Alexey Proskuryakov  <ap@apple.com>
  2
+
  3
+        Crash in 3rd party WebKit apps that disable cache at a wrong time
  4
+        https://bugs.webkit.org/show_bug.cgi?id=86027
  5
+        <rdar://problem/10615880>
  6
+
  7
+        Reviewed by Antti Koivisto.
  8
+
  9
+        Added an API test.
  10
+
  11
+        The fix is to use CachedResourceHandle throughout MemoryCache, which will certainly
  12
+        keep the resource alive. Also removed earlier fixes.
  13
+
  14
+        * css/CSSImageSetValue.cpp: (WebCore::CSSImageSetValue::cachedImageSet):
  15
+        * css/CSSImageValue.cpp: (WebCore::CSSImageValue::cachedImage):
  16
+        * css/WebKitCSSShaderValue.cpp: (WebCore::WebKitCSSShaderValue::cachedShader):
  17
+        * history/PageCache.cpp: (WebCore::PageCache::releaseAutoreleasedPagesNow):
  18
+        * loader/ImageLoader.cpp: (WebCore::ImageLoader::updateFromElement):
  19
+        * loader/TextTrackLoader.cpp: (WebCore::TextTrackLoader::load):
  20
+        * loader/cache/CachedResourceLoader.cpp:
  21
+        (WebCore::CachedResourceLoader::requestImage):
  22
+        (WebCore::CachedResourceLoader::requestFont):
  23
+        (WebCore::CachedResourceLoader::requestTextTrack):
  24
+        (WebCore::CachedResourceLoader::requestShader):
  25
+        (WebCore::CachedResourceLoader::requestCSSStyleSheet):
  26
+        (WebCore::CachedResourceLoader::requestUserCSSStyleSheet):
  27
+        (WebCore::CachedResourceLoader::requestScript):
  28
+        (WebCore::CachedResourceLoader::requestXSLStyleSheet):
  29
+        (WebCore::CachedResourceLoader::requestSVGDocument):
  30
+        (WebCore::CachedResourceLoader::requestLinkResource):
  31
+        (WebCore::CachedResourceLoader::requestRawResource):
  32
+        (WebCore::CachedResourceLoader::requestResource):
  33
+        (WebCore::CachedResourceLoader::revalidateResource):
  34
+        (WebCore::CachedResourceLoader::loadResource):
  35
+        (WebCore::CachedResourceLoader::requestPreload):
  36
+        * loader/cache/CachedResourceLoader.h: (CachedResourceLoader):
  37
+        * loader/cache/MemoryCache.h: (WebCore::MemoryCache::setPruneEnabled):
  38
+
  39
+        * loader/cache/CachedResourceHandle.h:
  40
+        (WebCore::CachedResourceHandle::CachedResourceHandle):
  41
+        (WebCore::CachedResourceHandle::operator=):
  42
+        Teach CachedResourceHandle how to make CachedResourceHandle<CachedResource> from
  43
+        a handle to subclass.
  44
+
1 45
 2012-05-10  Tien-Ren Chen  <trchen@chromium.org>
2 46
 
3 47
         Eliminate duplicated code for culled line box in RenderInline
4  Source/WebCore/css/CSSImageSetValue.cpp
@@ -106,8 +106,8 @@ StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* load
106 106
         // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698
107 107
         ImageWithScale image = bestImageForScaleFactor();
108 108
         ResourceRequest request(loader->document()->completeURL(image.imageURL));
109  
-        if (CachedImage* cachedImage = loader->requestImage(request)) {
110  
-            m_imageSet = StyleCachedImageSet::create(cachedImage, image.scaleFactor, this);
  109
+        if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) {
  110
+            m_imageSet = StyleCachedImageSet::create(cachedImage.get(), image.scaleFactor, this);
111 111
             m_accessedBestFitImage = true;
112 112
         }
113 113
     }
4  Source/WebCore/css/CSSImageValue.cpp
@@ -82,8 +82,8 @@ StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const
82 82
         m_accessedImage = true;
83 83
 
84 84
         ResourceRequest request(loader->document()->completeURL(url));
85  
-        if (CachedImage* cachedImage = loader->requestImage(request))
86  
-            m_image = StyleCachedImage::create(cachedImage);
  85
+        if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request))
  86
+            m_image = StyleCachedImage::create(cachedImage.get());
87 87
     }
88 88
 
89 89
     return (m_image && m_image->isCachedImage()) ? static_cast<StyleCachedImage*>(m_image.get()) : 0;
4  Source/WebCore/css/WebKitCSSShaderValue.cpp
@@ -59,8 +59,8 @@ StyleCachedShader* WebKitCSSShaderValue::cachedShader(CachedResourceLoader* load
59 59
         m_accessedShader = true;
60 60
 
61 61
         ResourceRequest request(loader->document()->completeURL(m_url));
62  
-        if (CachedShader* cachedShader = loader->requestShader(request))
63  
-            m_shader = StyleCachedShader::create(cachedShader);
  62
+        if (CachedResourceHandle<CachedShader> cachedShader = loader->requestShader(request))
  63
+            m_shader = StyleCachedShader::create(cachedShader.get());
64 64
     }
65 65
 
66 66
     return (m_shader && m_shader->isCachedShader()) ? static_cast<StyleCachedShader*>(m_shader.get()) : 0;
7  Source/WebCore/history/PageCache.cpp
@@ -535,7 +535,6 @@ void PageCache::releaseAutoreleasedPagesNow()
535 535
     m_autoreleaseTimer.stop();
536 536
 
537 537
     // Postpone dead pruning until all our resources have gone dead.
538  
-    bool pruneWasEnabled = memoryCache()->pruneEnabled();
539 538
     memoryCache()->setPruneEnabled(false);
540 539
 
541 540
     CachedPageSet tmp;
@@ -546,10 +545,8 @@ void PageCache::releaseAutoreleasedPagesNow()
546 545
         (*it)->destroy();
547 546
 
548 547
     // Now do the prune.
549  
-    if (pruneWasEnabled) {
550  
-        memoryCache()->setPruneEnabled(true);
551  
-        memoryCache()->prune();
552  
-    }
  548
+    memoryCache()->setPruneEnabled(true);
  549
+    memoryCache()->prune();
553 550
 }
554 551
 
555 552
 void PageCache::autorelease(PassRefPtr<CachedPage> page)
4  Source/WebCore/loader/ImageLoader.cpp
@@ -154,7 +154,7 @@ void ImageLoader::updateFromElement()
154 154
 
155 155
     // Do not load any image if the 'src' attribute is missing or if it is
156 156
     // an empty string.
157  
-    CachedImage* newImage = 0;
  157
+    CachedResourceHandle<CachedImage> newImage = 0;
158 158
     if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) {
159 159
         ResourceRequest request = ResourceRequest(document->completeURL(sourceURI(attr)));
160 160
 
@@ -170,7 +170,7 @@ void ImageLoader::updateFromElement()
170 170
             newImage = new CachedImage(request);
171 171
             newImage->setLoading(true);
172 172
             newImage->setOwningCachedResourceLoader(document->cachedResourceLoader());
173  
-            document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage);
  173
+            document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage.get());
174 174
             document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages);
175 175
         } else
176 176
             newImage = document->cachedResourceLoader()->requestImage(request);
2  Source/WebCore/loader/TextTrackLoader.cpp
@@ -167,7 +167,7 @@ bool TextTrackLoader::load(const KURL& url, const String& crossOriginMode)
167 167
     }
168 168
 
169 169
     CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
170  
-    m_cachedCueData = static_cast<CachedTextTrack*>(cachedResourceLoader->requestTextTrack(cueRequest));
  170
+    m_cachedCueData = cachedResourceLoader->requestTextTrack(cueRequest);
171 171
     if (m_cachedCueData)
172 172
         m_cachedCueData->addClient(this);
173 173
     
3  Source/WebCore/loader/cache/CachedResourceHandle.h
@@ -61,12 +61,15 @@ namespace WebCore {
61 61
         CachedResourceHandle() { }
62 62
         CachedResourceHandle(R* res) : CachedResourceHandleBase(res) { }
63 63
         CachedResourceHandle(const CachedResourceHandle<R>& o) : CachedResourceHandleBase(o) { }
  64
+        template<typename U> CachedResourceHandle(const CachedResourceHandle<U>& o) : CachedResourceHandleBase(o.get()) { }
64 65
 
65 66
         R* get() const { return reinterpret_cast<R*>(CachedResourceHandleBase::get()); }
66 67
         R* operator->() const { return get(); }
67 68
                
68 69
         CachedResourceHandle& operator=(R* res) { setResource(res); return *this; } 
69 70
         CachedResourceHandle& operator=(const CachedResourceHandle& o) { setResource(o.get()); return *this; }
  71
+        template<typename U> CachedResourceHandle& operator=(const CachedResourceHandle<U>& o) { setResource(o.get()); return *this; }
  72
+
70 73
         bool operator==(const CachedResourceHandleBase& o) const { return get() == o.get(); }
71 74
         bool operator!=(const CachedResourceHandleBase& o) const { return get() != o.get(); }
72 75
     };
105  Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -151,7 +151,7 @@ Frame* CachedResourceLoader::frame() const
151 151
     return m_document ? m_document->frame() : 0;
152 152
 }
153 153
 
154  
-CachedImage* CachedResourceLoader::requestImage(ResourceRequest& request)
  154
+CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(ResourceRequest& request)
155 155
 {
156 156
     if (Frame* f = frame()) {
157 157
         if (f->loader()->pageDismissalEventBeingDispatched() != FrameLoader::NoDismissal) {
@@ -161,37 +161,37 @@ CachedImage* CachedResourceLoader::requestImage(ResourceRequest& request)
161 161
             return 0;
162 162
         }
163 163
     }
164  
-    CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String(), defaultCachedResourceOptions()));
  164
+    CachedResourceHandle<CachedImage> resource(static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String(), defaultCachedResourceOptions()).get()));
165 165
     if (autoLoadImages() && resource && resource->stillNeedsLoad())
166 166
         resource->load(this, defaultCachedResourceOptions());
167 167
     return resource;
168 168
 }
169 169
 
170  
-CachedFont* CachedResourceLoader::requestFont(ResourceRequest& request)
  170
+CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(ResourceRequest& request)
171 171
 {
172  
-    return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, request, String(), defaultCachedResourceOptions()));
  172
+    return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, request, String(), defaultCachedResourceOptions()).get());
173 173
 }
174 174
 
175 175
 #if ENABLE(VIDEO_TRACK)
176  
-CachedTextTrack* CachedResourceLoader::requestTextTrack(ResourceRequest& request)
  176
+CachedResourceHandle<CachedTextTrack> CachedResourceLoader::requestTextTrack(ResourceRequest& request)
177 177
 {
178  
-    return static_cast<CachedTextTrack*>(requestResource(CachedResource::TextTrackResource, request, String(), defaultCachedResourceOptions()));
  178
+    return static_cast<CachedTextTrack*>(requestResource(CachedResource::TextTrackResource, request, String(), defaultCachedResourceOptions()).get());
179 179
 }
180 180
 #endif
181 181
 
182 182
 #if ENABLE(CSS_SHADERS)
183  
-CachedShader* CachedResourceLoader::requestShader(ResourceRequest& request)
  183
+CachedResourceHandle<CachedShader> CachedResourceLoader::requestShader(ResourceRequest& request)
184 184
 {
185  
-    return static_cast<CachedShader*>(requestResource(CachedResource::ShaderResource, request, String(), defaultCachedResourceOptions()));
  185
+    return static_cast<CachedShader*>(requestResource(CachedResource::ShaderResource, request, String(), defaultCachedResourceOptions()).get());
186 186
 }
187 187
 #endif
188 188
 
189  
-CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
  189
+CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestCSSStyleSheet(ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
190 190
 {
191  
-    return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, request, charset, defaultCachedResourceOptions(), priority));
  191
+    return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, request, charset, defaultCachedResourceOptions(), priority).get());
192 192
 }
193 193
 
194  
-CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequest& request, const String& charset)
  194
+CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequest& request, const String& charset)
195 195
 {
196 196
     KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.url());
197 197
 
@@ -203,41 +203,37 @@ CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequ
203 203
     if (url.string() != request.url())
204 204
         request.setURL(url);
205 205
 
206  
-    CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(request, charset);
207  
-    
208  
-    bool inCache = memoryCache()->add(userSheet);
209  
-    if (!inCache)
210  
-        userSheet->setInCache(true);
  206
+    CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleSheet(request, charset);
211 207
 
212  
-    userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
  208
+    memoryCache()->add(userSheet.get());
  209
+    // FIXME: loadResource calls setOwningCachedResourceLoader() if the resource couldn't be added to cache. Does this function need to call it, too?
213 210
 
214  
-    if (!inCache)
215  
-        userSheet->setInCache(false);
  211
+    userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
216 212
     
217 213
     return userSheet;
218 214
 }
219 215
 
220  
-CachedScript* CachedResourceLoader::requestScript(ResourceRequest& request, const String& charset)
  216
+CachedResourceHandle<CachedScript> CachedResourceLoader::requestScript(ResourceRequest& request, const String& charset)
221 217
 {
222  
-    return static_cast<CachedScript*>(requestResource(CachedResource::Script, request, charset, defaultCachedResourceOptions()));
  218
+    return static_cast<CachedScript*>(requestResource(CachedResource::Script, request, charset, defaultCachedResourceOptions()).get());
223 219
 }
224 220
 
225 221
 #if ENABLE(XSLT)
226  
-CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(ResourceRequest& request)
  222
+CachedResourceHandle<CachedXSLStyleSheet> CachedResourceLoader::requestXSLStyleSheet(ResourceRequest& request)
227 223
 {
228  
-    return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, request, String(), defaultCachedResourceOptions()));
  224
+    return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, request, String(), defaultCachedResourceOptions()).get());
229 225
 }
230 226
 #endif
231 227
 
232 228
 #if ENABLE(SVG)
233  
-CachedSVGDocument* CachedResourceLoader::requestSVGDocument(ResourceRequest& request)
  229
+CachedResourceHandle<CachedSVGDocument> CachedResourceLoader::requestSVGDocument(ResourceRequest& request)
234 230
 {
235  
-    return static_cast<CachedSVGDocument*>(requestResource(CachedResource::SVGDocumentResource, request, request.url(), defaultCachedResourceOptions()));
  231
+    return static_cast<CachedSVGDocument*>(requestResource(CachedResource::SVGDocumentResource, request, request.url(), defaultCachedResourceOptions()).get());
236 232
 }
237 233
 #endif
238 234
 
239 235
 #if ENABLE(LINK_PREFETCH)
240  
-CachedResource* CachedResourceLoader::requestLinkResource(CachedResource::Type type, ResourceRequest& request, ResourceLoadPriority priority)
  236
+CachedResourceHandle<CachedResource> CachedResourceLoader::requestLinkResource(CachedResource::Type type, ResourceRequest& request, ResourceLoadPriority priority)
241 237
 {
242 238
     ASSERT(frame());
243 239
     ASSERT(type == CachedResource::LinkPrefetch || type == CachedResource::LinkPrerender || type == CachedResource::LinkSubresource);
@@ -245,9 +241,9 @@ CachedResource* CachedResourceLoader::requestLinkResource(CachedResource::Type t
245 241
 }
246 242
 #endif
247 243
 
248  
-CachedRawResource* CachedResourceLoader::requestRawResource(ResourceRequest& request, const ResourceLoaderOptions& options)
  244
+CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestRawResource(ResourceRequest& request, const ResourceLoaderOptions& options)
249 245
 {
250  
-    return static_cast<CachedRawResource*>(requestResource(CachedResource::RawResource, request, String(), options, ResourceLoadPriorityUnresolved, false));
  246
+    return static_cast<CachedRawResource*>(requestResource(CachedResource::RawResource, request, String(), options, ResourceLoadPriorityUnresolved, false).get());
251 247
 }
252 248
 
253 249
 bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const KURL& url) const
@@ -410,7 +406,7 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
410 406
     return true;
411 407
 }
412 408
 
413  
-CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, const ResourceLoaderOptions& options, ResourceLoadPriority priority, bool forPreload)
  409
+CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, const ResourceLoaderOptions& options, ResourceLoadPriority priority, bool forPreload)
414 410
 {
415 411
     KURL url = request.url();
416 412
     
@@ -434,25 +430,25 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
434 430
     }
435 431
 
436 432
     // See if we can use an existing resource from the cache.
437  
-    CachedResource* resource = memoryCache()->resourceForURL(url);
  433
+    CachedResourceHandle<CachedResource> resource = memoryCache()->resourceForURL(url);
438 434
 
439 435
     if (request.url() != url)
440 436
         request.setURL(url);
441 437
 
442  
-    switch (determineRevalidationPolicy(type, request, forPreload, resource)) {
  438
+    switch (determineRevalidationPolicy(type, request, forPreload, resource.get())) {
443 439
     case Load:
444 440
         resource = loadResource(type, request, charset, priority, options);
445 441
         break;
446 442
     case Reload:
447  
-        memoryCache()->remove(resource);
  443
+        memoryCache()->remove(resource.get());
448 444
         resource = loadResource(type, request, charset, priority, options);
449 445
         break;
450 446
     case Revalidate:
451  
-        resource = revalidateResource(resource, priority, options);
  447
+        resource = revalidateResource(resource.get(), priority, options);
452 448
         break;
453 449
     case Use:
454  
-        memoryCache()->resourceAccessed(resource);
455  
-        notifyLoadedFromMemoryCache(resource);
  450
+        memoryCache()->resourceAccessed(resource.get());
  451
+        notifyLoadedFromMemoryCache(resource.get());
456 452
         break;
457 453
     }
458 454
 
@@ -463,8 +459,8 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
463 459
     m_documentResources.set(resource->url(), resource);
464 460
     return resource;
465 461
 }
466  
-    
467  
-CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority, const ResourceLoaderOptions& options)
  462
+
  463
+CachedResourceHandle<CachedResource> CachedResourceLoader::revalidateResource(CachedResource* resource, ResourceLoadPriority priority, const ResourceLoaderOptions& options)
468 464
 {
469 465
     ASSERT(resource);
470 466
     ASSERT(resource->inCache());
@@ -475,13 +471,13 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
475 471
     // Copy the URL out of the resource to be revalidated in case it gets deleted by the remove() call below.
476 472
     String url = resource->url();
477 473
     bool urlProtocolIsData = resource->url().protocolIsData();
478  
-    CachedResource* newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding());
  474
+    CachedResourceHandle<CachedResource> newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding());
479 475
     
480  
-    LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
  476
+    LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource.get(), resource);
481 477
     newResource->setResourceToRevalidate(resource);
482 478
     
483 479
     memoryCache()->remove(resource);
484  
-    memoryCache()->add(newResource);
  480
+    memoryCache()->add(newResource.get());
485 481
     
486 482
     newResource->setLoadPriority(priority);
487 483
     newResource->load(this, options);
@@ -491,39 +487,26 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
491 487
     return newResource;
492 488
 }
493 489
 
494  
-CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority, const ResourceLoaderOptions& options)
  490
+CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority, const ResourceLoaderOptions& options)
495 491
 {
496 492
     ASSERT(!memoryCache()->resourceForURL(request.url()));
497 493
     
498 494
     LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.url().string().latin1().data());
499 495
     
500  
-    CachedResource* resource = createResource(type, request, charset);
501  
-    
502  
-    bool inCache = memoryCache()->add(resource);
  496
+    CachedResourceHandle<CachedResource> resource = createResource(type, request, charset);
503 497
     
504  
-    // Pretend the resource is in the cache, to prevent it from being deleted during the load() call.
505  
-    // FIXME: CachedResource should just use normal refcounting instead.
506  
-    if (!inCache)
507  
-        resource->setInCache(true);
  498
+    bool inCache = memoryCache()->add(resource.get());
508 499
     
509 500
     resource->setLoadPriority(priority);
510  
-    
511  
-    bool wasPruneEnabled = memoryCache()->pruneEnabled();
512  
-    memoryCache()->setPruneEnabled(false);
513 501
     resource->load(this, options);
514  
-    memoryCache()->setPruneEnabled(wasPruneEnabled);
515 502
     
516  
-    if (!inCache) {
  503
+    if (!inCache)
517 504
         resource->setOwningCachedResourceLoader(this);
518  
-        resource->setInCache(false);
519  
-    }
520 505
 
521 506
     // We don't support immediate loads, but we do support immediate failure.
522 507
     if (resource->errorOccurred()) {
523 508
         if (inCache)
524  
-            memoryCache()->remove(resource);
525  
-        else
526  
-            delete resource;
  509
+            memoryCache()->remove(resource.get());
527 510
         return 0;
528 511
     }
529 512
 
@@ -781,14 +764,14 @@ void CachedResourceLoader::requestPreload(CachedResource::Type type, ResourceReq
781 764
     if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
782 765
         encoding = charset.isEmpty() ? m_document->charset() : charset;
783 766
 
784  
-    CachedResource* resource = requestResource(type, request, encoding, defaultCachedResourceOptions(), ResourceLoadPriorityUnresolved, true);
785  
-    if (!resource || (m_preloads && m_preloads->contains(resource)))
  767
+    CachedResourceHandle<CachedResource> resource = requestResource(type, request, encoding, defaultCachedResourceOptions(), ResourceLoadPriorityUnresolved, true);
  768
+    if (!resource || (m_preloads && m_preloads->contains(resource.get())))
786 769
         return;
787 770
     resource->increasePreloadCount();
788 771
 
789 772
     if (!m_preloads)
790 773
         m_preloads = adoptPtr(new ListHashSet<CachedResource*>);
791  
-    m_preloads->add(resource);
  774
+    m_preloads->add(resource.get());
792 775
 
793 776
 #if PRELOAD_DEBUG
794 777
     printf("PRELOADING %s\n",  resource->url().latin1().data());
28  Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -63,27 +63,27 @@ friend class ResourceCacheValidationSuppressor;
63 63
     CachedResourceLoader(Document*);
64 64
     ~CachedResourceLoader();
65 65
 
66  
-    CachedImage* requestImage(ResourceRequest&);
67  
-    CachedCSSStyleSheet* requestCSSStyleSheet(ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
68  
-    CachedCSSStyleSheet* requestUserCSSStyleSheet(ResourceRequest&, const String& charset);
69  
-    CachedScript* requestScript(ResourceRequest&, const String& charset);
70  
-    CachedFont* requestFont(ResourceRequest&);
71  
-    CachedRawResource* requestRawResource(ResourceRequest&, const ResourceLoaderOptions&);
  66
+    CachedResourceHandle<CachedImage> requestImage(ResourceRequest&);
  67
+    CachedResourceHandle<CachedCSSStyleSheet> requestCSSStyleSheet(ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
  68
+    CachedResourceHandle<CachedCSSStyleSheet> requestUserCSSStyleSheet(ResourceRequest&, const String& charset);
  69
+    CachedResourceHandle<CachedScript> requestScript(ResourceRequest&, const String& charset);
  70
+    CachedResourceHandle<CachedFont> requestFont(ResourceRequest&);
  71
+    CachedResourceHandle<CachedRawResource> requestRawResource(ResourceRequest&, const ResourceLoaderOptions&);
72 72
 
73 73
 #if ENABLE(SVG)
74  
-    CachedSVGDocument* requestSVGDocument(ResourceRequest&);
  74
+    CachedResourceHandle<CachedSVGDocument> requestSVGDocument(ResourceRequest&);
75 75
 #endif
76 76
 #if ENABLE(XSLT)
77  
-    CachedXSLStyleSheet* requestXSLStyleSheet(ResourceRequest&);
  77
+    CachedResourceHandle<CachedXSLStyleSheet> requestXSLStyleSheet(ResourceRequest&);
78 78
 #endif
79 79
 #if ENABLE(LINK_PREFETCH)
80  
-    CachedResource* requestLinkResource(CachedResource::Type, ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
  80
+    CachedResourceHandle<CachedResource> requestLinkResource(CachedResource::Type, ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
81 81
 #endif
82 82
 #if ENABLE(VIDEO_TRACK)
83  
-    CachedTextTrack* requestTextTrack(ResourceRequest&);
  83
+    CachedResourceHandle<CachedTextTrack> requestTextTrack(ResourceRequest&);
84 84
 #endif
85 85
 #if ENABLE(CSS_SHADERS)
86  
-    CachedShader* requestShader(ResourceRequest&);
  86
+    CachedResourceHandle<CachedShader> requestShader(ResourceRequest&);
87 87
 #endif
88 88
 
89 89
     // Logs an access denied message to the console for the specified URL.
@@ -119,9 +119,9 @@ friend class ResourceCacheValidationSuppressor;
119 119
     bool canRequest(CachedResource::Type, const KURL&, bool forPreload = false);
120 120
     
121 121
 private:
122  
-    CachedResource* requestResource(CachedResource::Type, ResourceRequest&, const String& charset, const ResourceLoaderOptions&, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false);
123  
-    CachedResource* revalidateResource(CachedResource*, ResourceLoadPriority, const ResourceLoaderOptions&);
124  
-    CachedResource* loadResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority, const ResourceLoaderOptions&);
  122
+    CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, ResourceRequest&, const String& charset, const ResourceLoaderOptions&, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false);
  123
+    CachedResourceHandle<CachedResource> revalidateResource(CachedResource*, ResourceLoadPriority, const ResourceLoaderOptions&);
  124
+    CachedResourceHandle<CachedResource> loadResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority, const ResourceLoaderOptions&);
125 125
     void requestPreload(CachedResource::Type, ResourceRequest&, const String& charset);
126 126
 
127 127
     enum RevalidationPolicy { Use, Revalidate, Reload, Load };
1  Source/WebCore/loader/cache/MemoryCache.h
@@ -129,7 +129,6 @@ class MemoryCache {
129 129
     void evictResources();
130 130
     
131 131
     void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
132  
-    bool pruneEnabled() const { return m_pruneEnabled; }
133 132
     void prune();
134 133
     void pruneToPercentage(float targetPercentLive);
135 134
 
20  Tools/ChangeLog
... ...
@@ -1,3 +1,23 @@
  1
+2012-05-10  Alexey Proskuryakov  <ap@apple.com>
  2
+
  3
+        Crash in 3rd party WebKit apps that disable cache at a wrong time
  4
+        https://bugs.webkit.org/show_bug.cgi?id=86027
  5
+        <rdar://problem/10615880>
  6
+
  7
+        Reviewed by Antti Koivisto.
  8
+
  9
+        Added a test that's very similar to MemoryCachePruneWithinResourceLoadDelegate,
  10
+        but for disabling the cache instead of triggering a prune.
  11
+
  12
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  13
+        * TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.html: Added.
  14
+        * TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.mm: Added.
  15
+        (-[MemoryCacheDisableTestResourceLoadDelegate webView:identifierForInitialRequest:fromDataSource:]):
  16
+        (-[MemoryCacheDisableTestResourceLoadDelegate webView:resource:willSendRequest:redirectResponse:fromDataSource:]):
  17
+        (-[MemoryCacheDisableTestResourceLoadDelegate webView:resource:didFinishLoadingFromDataSource:]):
  18
+        (-[MemoryCacheDisableTestResourceLoadDelegate webView:resource:didFailLoadingWithError:fromDataSource:]):
  19
+        (TestWebKitAPI::TEST):
  20
+
1 21
 2012-05-10  Anders Carlsson  <andersca@apple.com>
2 22
 
3 23
         WebKit2: Add a way to blacklist specific plug-ins/plug-in versions
10  Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
@@ -141,6 +141,8 @@
141 141
 		C507E8A714C6545B005D6B3B /* InspectorBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = C507E8A614C6545B005D6B3B /* InspectorBar.mm */; };
142 142
 		C540F776152E4DA000A40C8C /* SimplifyMarkup.mm in Sources */ = {isa = PBXBuildFile; fileRef = C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */; };
143 143
 		C540F784152E5A9A00A40C8C /* verboseMarkup.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C540F783152E5A7800A40C8C /* verboseMarkup.html */; };
  144
+		E1220DA0155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */; };
  145
+		E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */; };
144 146
 		E490296814E2E3A4002BEDD1 /* TypingStyleCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */; };
145 147
 		F3FC3EE313678B7300126A65 /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3FC3EE213678B7300126A65 /* libgtest.a */; };
146 148
 		F6A6BFBB1558AC4800926107 /* simple-unload.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F6A6BFB91558ABF800926107 /* simple-unload.html */; };
@@ -182,6 +184,7 @@
182 184
 				B55F11B71517D03300915916 /* attributedStringCustomFont.html in Copy Resources */,
183 185
 				76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */,
184 186
 				5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */,
  187
+				E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */,
185 188
 				517E7E04151119C100D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html in Copy Resources */,
186 189
 				379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */,
187 190
 				33DC8912141955FE00747EF7 /* simple-iframe.html in Copy Resources */,
@@ -360,6 +363,8 @@
360 363
 		C507E8A614C6545B005D6B3B /* InspectorBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorBar.mm; sourceTree = "<group>"; };
361 364
 		C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SimplifyMarkup.mm; sourceTree = "<group>"; };
362 365
 		C540F783152E5A7800A40C8C /* verboseMarkup.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = verboseMarkup.html; sourceTree = "<group>"; };
  366
+		E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheDisableWithinResourceLoadDelegate.mm; sourceTree = "<group>"; };
  367
+		E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = MemoryCacheDisableWithinResourceLoadDelegate.html; sourceTree = "<group>"; };
363 368
 		E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TypingStyleCrash.mm; sourceTree = "<group>"; };
364 369
 		F3FC3EE213678B7300126A65 /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; };
365 370
 		F6A6BFB81558ABF800926107 /* simple-iframe-unload.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-iframe-unload.html"; sourceTree = "<group>"; };
@@ -654,6 +659,7 @@
654 659
 				3776BC62150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm */,
655 660
 				939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */,
656 661
 				C507E8A614C6545B005D6B3B /* InspectorBar.mm */,
  662
+				E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */,
657 663
 				517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */,
658 664
 				3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */,
659 665
 				C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */,
@@ -673,8 +679,9 @@
673 679
 				379028B814FABE49007E6B43 /* acceptsFirstMouse.html */,
674 680
 				5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */,
675 681
 				37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */,
676  
-				C07E6CB113FD738A0038B22B /* devicePixelRatio.html */,
  682
+				E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */,
677 683
 				517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */,
  684
+				C07E6CB113FD738A0038B22B /* devicePixelRatio.html */,
678 685
 				C540F783152E5A7800A40C8C /* verboseMarkup.html */,
679 686
 			);
680 687
 			name = Resources;
@@ -878,6 +885,7 @@
878 885
 				51FCF79A1534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp in Sources */,
879 886
 				51393E201523944A005F39C5 /* DOMWindowExtensionBasic.cpp in Sources */,
880 887
 				76E182DA1547550100F1FADD /* WillSendSubmitEvent.cpp in Sources */,
  888
+				E1220DA0155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm in Sources */,
881 889
 				F6F49C6915545C8E0007F39D /* DOMWindowExtensionNoCache.cpp in Sources */,
882 890
 			);
883 891
 			runOnlyForDeploymentPostprocessing = 0;
14  Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.html
... ...
@@ -0,0 +1,14 @@
  1
+<script>
  2
+
  3
+function loaded()
  4
+{
  5
+    var request = new XMLHttpRequest();
  6
+    request.open('GET', 'http://www.iana.org/domains/example/', true);
  7
+    request.send(null);
  8
+}
  9
+
  10
+</script>
  11
+
  12
+<body onload="loaded();">
  13
+We will do some XHR'ing now!
  14
+</body>
90  Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.mm
... ...
@@ -0,0 +1,90 @@
  1
+/*
  2
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
  3
+ *
  4
+ * Redistribution and use in source and binary forms, with or without
  5
+ * modification, are permitted provided that the following conditions
  6
+ * are met:
  7
+ * 1. Redistributions of source code must retain the above copyright
  8
+ *    notice, this list of conditions and the following disclaimer.
  9
+ * 2. Redistributions in binary form must reproduce the above copyright
  10
+ *    notice, this list of conditions and the following disclaimer in the
  11
+ *    documentation and/or other materials provided with the distribution.
  12
+ *
  13
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23
+ * THE POSSIBILITY OF SUCH DAMAGE.
  24
+ */
  25
+
  26
+#import "config.h"
  27
+#import "PlatformUtilities.h"
  28
+#import <WebKit/WebCache.h>
  29
+#import <wtf/RetainPtr.h>
  30
+
  31
+@interface MemoryCacheDisableTestResourceLoadDelegate : NSObject {
  32
+}
  33
+@end
  34
+
  35
+static bool didFinishLoad;
  36
+
  37
+@implementation MemoryCacheDisableTestResourceLoadDelegate
  38
+
  39
+- (id)webView:(WebView *)sender identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource
  40
+{
  41
+    [WebCache setDisabled:YES];
  42
+    [WebCache setDisabled:NO];
  43
+
  44
+    return self;
  45
+}
  46
+
  47
+- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
  48
+{
  49
+    [WebCache setDisabled:YES];
  50
+    [WebCache setDisabled:NO];
  51
+
  52
+    return request;
  53
+}
  54
+
  55
+- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
  56
+{
  57
+    [WebCache setDisabled:YES];
  58
+    [WebCache setDisabled:NO];
  59
+
  60
+    didFinishLoad = YES;
  61
+}
  62
+
  63
+- (void)webView:(WebView *)sender resource:(id)identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
  64
+{
  65
+    [WebCache setDisabled:YES];
  66
+    [WebCache setDisabled:NO];
  67
+}
  68
+
  69
+@end
  70
+
  71
+namespace TestWebKitAPI {
  72
+
  73
+TEST(WebKit1, MemoryCacheDisableWithinResourceLoadDelegate)
  74
+{
  75
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  76
+
  77
+    RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
  78
+
  79
+    RetainPtr<MemoryCacheDisableTestResourceLoadDelegate> resourceLoadDelegate(AdoptNS, [[MemoryCacheDisableTestResourceLoadDelegate alloc] init]);
  80
+    webView.get().resourceLoadDelegate = resourceLoadDelegate.get();
  81
+
  82
+    [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"MemoryCacheDisableWithinResourceLoadDelegate" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
  83
+
  84
+    Util::run(&didFinishLoad);
  85
+    
  86
+    [pool drain];
  87
+    // If we finished without crashing, the test passed.
  88
+}
  89
+
  90
+} // namespace TestWebKitAPI

0 notes on commit 6edc42b

Please sign in to comment.
Something went wrong with that request. Please try again.