diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/loader/cache/CachedImage.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/loader/cache/CachedImage.cpp')
-rw-r--r-- | Source/WebCore/loader/cache/CachedImage.cpp | 432 |
1 files changed, 174 insertions, 258 deletions
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp index 5525fb1f3..65f0bf79c 100644 --- a/Source/WebCore/loader/cache/CachedImage.cpp +++ b/Source/WebCore/loader/cache/CachedImage.cpp @@ -35,15 +35,15 @@ #include "FrameLoaderTypes.h" #include "FrameView.h" #include "MemoryCache.h" -#include "Page.h" #include "RenderElement.h" -#include "ResourceBuffer.h" +#include "SVGImage.h" #include "SecurityOrigin.h" #include "Settings.h" +#include "SharedBuffer.h" #include "SubresourceLoader.h" #include <wtf/CurrentTime.h> +#include <wtf/NeverDestroyed.h> #include <wtf/StdLibExtras.h> -#include <wtf/Vector.h> #if PLATFORM(IOS) #include "SystemMemory.h" @@ -53,40 +53,28 @@ #include "PDFDocumentImage.h" #endif -#if ENABLE(SVG) -#include "SVGImage.h" -#endif - -#if ENABLE(DISK_IMAGE_CACHE) -#include "DiskImageCacheIOS.h" -#endif - namespace WebCore { -CachedImage::CachedImage(const ResourceRequest& resourceRequest) - : CachedResource(resourceRequest, ImageResource) - , m_image(0) - , m_shouldPaintBrokenImage(true) +CachedImage::CachedImage(CachedResourceRequest&& request, SessionID sessionID) + : CachedResource(WTFMove(request), ImageResource, sessionID) { setStatus(Unknown); } -CachedImage::CachedImage(Image* image) - : CachedResource(ResourceRequest(), ImageResource) +CachedImage::CachedImage(Image* image, SessionID sessionID) + : CachedResource(URL(), ImageResource, sessionID) , m_image(image) - , m_shouldPaintBrokenImage(true) { - setStatus(Cached); - setLoading(false); } -CachedImage::CachedImage(const URL& url, Image* image) - : CachedResource(ResourceRequest(url), ImageResource) +CachedImage::CachedImage(const URL& url, Image* image, SessionID sessionID) + : CachedResource(url, ImageResource, sessionID) , m_image(image) - , m_shouldPaintBrokenImage(true) + , m_isManuallyCached(true) { - setStatus(Cached); - setLoading(false); + // Use the incoming URL in the response field. This ensures that code using the response directly, + // such as origin checks for security, actually see something. + m_response.setURL(url); } CachedImage::~CachedImage() @@ -94,56 +82,69 @@ CachedImage::~CachedImage() clearImage(); } -void CachedImage::load(CachedResourceLoader* cachedResourceLoader, const ResourceLoaderOptions& options) +void CachedImage::load(CachedResourceLoader& loader) { - if (!cachedResourceLoader || cachedResourceLoader->autoLoadImages()) - CachedResource::load(cachedResourceLoader, options); + if (loader.shouldPerformImageLoad(url())) + CachedResource::load(loader); else setLoading(false); } -void CachedImage::didAddClient(CachedResourceClient* c) +void CachedImage::setBodyDataFrom(const CachedResource& resource) +{ + ASSERT(resource.type() == type()); + const CachedImage& image = static_cast<const CachedImage&>(resource); + + CachedResource::setBodyDataFrom(resource); + + m_image = image.m_image; + m_imageObserver = image.m_imageObserver; + if (m_imageObserver) + m_imageObserver->add(*this); + + if (m_image && is<SVGImage>(*m_image)) + m_svgImageCache = std::make_unique<SVGImageCache>(&downcast<SVGImage>(*m_image)); +} + +void CachedImage::didAddClient(CachedResourceClient& client) { if (m_data && !m_image && !errorOccurred()) { createImage(); - m_image->setData(m_data->sharedBuffer(), true); + m_image->setData(m_data.copyRef(), true); } - - ASSERT(c->resourceClientType() == CachedImageClient::expectedType()); + + ASSERT(client.resourceClientType() == CachedImageClient::expectedType()); if (m_image && !m_image->isNull()) - static_cast<CachedImageClient*>(c)->imageChanged(this); + static_cast<CachedImageClient&>(client).imageChanged(this); - CachedResource::didAddClient(c); + CachedResource::didAddClient(client); } -void CachedImage::didRemoveClient(CachedResourceClient* c) +void CachedImage::didRemoveClient(CachedResourceClient& client) { - ASSERT(c); - ASSERT(c->resourceClientType() == CachedImageClient::expectedType()); + ASSERT(client.resourceClientType() == CachedImageClient::expectedType()); + + m_pendingContainerSizeRequests.remove(&static_cast<CachedImageClient&>(client)); - m_pendingContainerSizeRequests.remove(static_cast<CachedImageClient*>(c)); -#if ENABLE(SVG) if (m_svgImageCache) - m_svgImageCache->removeClientFromCache(static_cast<CachedImageClient*>(c)); -#endif + m_svgImageCache->removeClientFromCache(&static_cast<CachedImageClient&>(client)); - CachedResource::didRemoveClient(c); + CachedResource::didRemoveClient(client); } void CachedImage::switchClientsToRevalidatedResource() { - ASSERT(resourceToRevalidate()); - ASSERT(resourceToRevalidate()->isImage()); + ASSERT(is<CachedImage>(resourceToRevalidate())); // Pending container size requests need to be transferred to the revalidated resource. if (!m_pendingContainerSizeRequests.isEmpty()) { // A copy of pending size requests is needed as they are deleted during CachedResource::switchClientsToRevalidateResouce(). ContainerSizeRequests switchContainerSizeRequests; - for (ContainerSizeRequests::iterator it = m_pendingContainerSizeRequests.begin(); it != m_pendingContainerSizeRequests.end(); ++it) - switchContainerSizeRequests.set(it->key, it->value); + for (auto& request : m_pendingContainerSizeRequests) + switchContainerSizeRequests.set(request.key, request.value); CachedResource::switchClientsToRevalidatedResource(); - CachedImage* revalidatedCachedImage = static_cast<CachedImage*>(resourceToRevalidate()); - for (ContainerSizeRequests::iterator it = switchContainerSizeRequests.begin(); it != switchContainerSizeRequests.end(); ++it) - revalidatedCachedImage->setContainerSizeForRenderer(it->key, it->value.first, it->value.second); + CachedImage& revalidatedCachedImage = downcast<CachedImage>(*resourceToRevalidate()); + for (auto& request : switchContainerSizeRequests) + revalidatedCachedImage.setContainerSizeForRenderer(request.key, request.value.first, request.value.second); return; } @@ -159,12 +160,17 @@ void CachedImage::allClientsRemoved() std::pair<Image*, float> CachedImage::brokenImage(float deviceScaleFactor) const { + if (deviceScaleFactor >= 3) { + static NeverDestroyed<Image*> brokenImageVeryHiRes(Image::loadPlatformResource("missingImage@3x").leakRef()); + return std::make_pair(brokenImageVeryHiRes, 3); + } + if (deviceScaleFactor >= 2) { - DEFINE_STATIC_LOCAL(Image*, brokenImageHiRes, (Image::loadPlatformResource("missingImage@2x").leakRef())); + static NeverDestroyed<Image*> brokenImageHiRes(Image::loadPlatformResource("missingImage@2x").leakRef()); return std::make_pair(brokenImageHiRes, 2); } - DEFINE_STATIC_LOCAL(Image*, brokenImageLoRes, (Image::loadPlatformResource("missingImage").leakRef())); + static NeverDestroyed<Image*> brokenImageLoRes(Image::loadPlatformResource("missingImage").leakRef()); return std::make_pair(brokenImageLoRes, 1); } @@ -175,8 +181,6 @@ bool CachedImage::willPaintBrokenImage() const Image* CachedImage::image() { - ASSERT(!isPurgeable()); - if (errorOccurred() && m_shouldPaintBrokenImage) { // Returning the 1x broken image is non-ideal, but we cannot reliably access the appropriate // deviceScaleFactor from here. It is critical that callers use CachedImage::brokenImage() @@ -192,8 +196,6 @@ Image* CachedImage::image() Image* CachedImage::imageForRenderer(const RenderObject* renderer) { - ASSERT(!isPurgeable()); - if (errorOccurred() && m_shouldPaintBrokenImage) { // Returning the 1x broken image is non-ideal, but we cannot reliably access the appropriate // deviceScaleFactor from here. It is critical that callers use CachedImage::brokenImage() @@ -204,19 +206,15 @@ Image* CachedImage::imageForRenderer(const RenderObject* renderer) if (!m_image) return Image::nullImage(); -#if ENABLE(SVG) if (m_image->isSVGImage()) { Image* image = m_svgImageCache->imageForRenderer(renderer); if (image != Image::nullImage()) return image; } -#else - UNUSED_PARAM(renderer); -#endif return m_image.get(); } -void CachedImage::setContainerSizeForRenderer(const CachedImageClient* renderer, const IntSize& containerSize, float containerZoom) +void CachedImage::setContainerSizeForRenderer(const CachedImageClient* renderer, const LayoutSize& containerSize, float containerZoom) { if (containerSize.isEmpty()) return; @@ -226,17 +224,13 @@ void CachedImage::setContainerSizeForRenderer(const CachedImageClient* renderer, m_pendingContainerSizeRequests.set(renderer, SizeAndZoom(containerSize, containerZoom)); return; } -#if ENABLE(SVG) + if (!m_image->isSVGImage()) { m_image->setContainerSize(containerSize); return; } m_svgImageCache->setContainerSizeForRenderer(renderer, containerSize, containerZoom); -#else - UNUSED_PARAM(containerZoom); - m_image->setContainerSize(containerSize); -#endif } bool CachedImage::usesImageContainerSize() const @@ -263,42 +257,19 @@ bool CachedImage::imageHasRelativeHeight() const return false; } -LayoutSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float multiplier, SizeType sizeType) +LayoutSize CachedImage::imageSizeForRenderer(const RenderElement* renderer, float multiplier, SizeType sizeType) { - ASSERT(!isPurgeable()); - if (!m_image) - return IntSize(); + return LayoutSize(); - LayoutSize imageSize(m_image->size()); + LayoutSize imageSize; -#if ENABLE(CSS_IMAGE_ORIENTATION) - if (renderer && m_image->isBitmapImage()) { - ImageOrientationDescription orientationDescription(renderer->shouldRespectImageOrientation(), renderer->style().imageOrientation()); - if (orientationDescription.respectImageOrientation() == RespectImageOrientation) - imageSize = toBitmapImage(m_image.get())->sizeRespectingOrientation(orientationDescription); - } -#else - if (m_image->isBitmapImage() && (renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation)) -#if !PLATFORM(IOS) - imageSize = toBitmapImage(m_image.get())->sizeRespectingOrientation(); -#else - { - // On iOS, the image may have been subsampled to accommodate our size restrictions. However - // we should tell the renderer what the original size was. - imageSize = toBitmapImage(m_image.get())->originalSizeRespectingOrientation(); - } else if (m_image->isBitmapImage()) - imageSize = toBitmapImage(m_image.get())->originalSize(); -#endif // !PLATFORM(IOS) -#endif // ENABLE(CSS_IMAGE_ORIENTATION) - -#if ENABLE(SVG) - else if (m_image->isSVGImage() && sizeType == UsedSize) { - imageSize = m_svgImageCache->imageSizeForRenderer(renderer); - } -#else - UNUSED_PARAM(sizeType); -#endif + if (is<BitmapImage>(*m_image) && renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation) + imageSize = LayoutSize(downcast<BitmapImage>(*m_image).sizeRespectingOrientation()); + else if (is<SVGImage>(*m_image) && sizeType == UsedSize) + imageSize = LayoutSize(m_svgImageCache->imageSizeForRenderer(renderer)); + else + imageSize = LayoutSize(m_image->size()); if (multiplier == 1.0f) return imageSize; @@ -331,7 +302,7 @@ void CachedImage::checkShouldPaintBrokenImage() if (!m_loader || m_loader->reachedTerminalState()) return; - m_shouldPaintBrokenImage = m_loader->frameLoader()->client().shouldPaintBrokenImage(m_resourceRequest.url()); + m_shouldPaintBrokenImage = m_loader->frameLoader()->client().shouldPaintBrokenImage(url()); } void CachedImage::clear() @@ -347,77 +318,98 @@ inline void CachedImage::createImage() // Create the image if it doesn't yet exist. if (m_image) return; + + m_imageObserver = CachedImageObserver::create(*this); + + if (m_response.mimeType() == "image/svg+xml") { + auto svgImage = SVGImage::create(*m_imageObserver, url()); + m_svgImageCache = std::make_unique<SVGImageCache>(svgImage.ptr()); + m_image = WTFMove(svgImage); #if USE(CG) && !USE(WEBKIT_IMAGE_DECODERS) - else if (m_response.mimeType() == "application/pdf") - m_image = PDFDocumentImage::create(this); + } else if (m_response.mimeType() == "application/pdf") { + m_image = PDFDocumentImage::create(m_imageObserver.get()); #endif -#if ENABLE(SVG) - else if (m_response.mimeType() == "image/svg+xml") { - RefPtr<SVGImage> svgImage = SVGImage::create(this); - m_svgImageCache = std::make_unique<SVGImageCache>(svgImage.get()); - m_image = svgImage.release(); - } -#endif - else - m_image = BitmapImage::create(this); + } else + m_image = BitmapImage::create(m_imageObserver.get()); if (m_image) { // Send queued container size requests. if (m_image->usesContainerSize()) { - for (ContainerSizeRequests::iterator it = m_pendingContainerSizeRequests.begin(); it != m_pendingContainerSizeRequests.end(); ++it) - setContainerSizeForRenderer(it->key, it->value.first, it->value.second); + for (auto& request : m_pendingContainerSizeRequests) + setContainerSizeForRenderer(request.key, request.value.first, request.value.second); } m_pendingContainerSizeRequests.clear(); } } -inline void CachedImage::clearImage() +CachedImage::CachedImageObserver::CachedImageObserver(CachedImage& image) { - // If our Image has an observer, it's always us so we need to clear the back pointer - // before dropping our reference. - if (m_image) - m_image->setImageObserver(0); - m_image.clear(); + m_cachedImages.reserveInitialCapacity(1); + m_cachedImages.append(&image); + if (auto* loader = image.loader()) { + m_allowSubsampling = loader->frameLoader()->frame().settings().imageSubsamplingEnabled(); + m_allowLargeImageAsyncDecoding = loader->frameLoader()->frame().settings().largeImageAsyncDecodingEnabled(); + m_allowAnimatedImageAsyncDecoding = loader->frameLoader()->frame().settings().animatedImageAsyncDecodingEnabled(); + m_showDebugBackground = loader->frameLoader()->frame().settings().showDebugBorders(); + } } -bool CachedImage::canBeDrawn() const +void CachedImage::CachedImageObserver::decodedSizeChanged(const Image* image, long long delta) { - if (!m_image || m_image->isNull()) - return false; + for (auto cachedImage : m_cachedImages) + cachedImage->decodedSizeChanged(image, delta); +} - if (!m_loader || m_loader->reachedTerminalState()) - return true; +void CachedImage::CachedImageObserver::didDraw(const Image* image) +{ + for (auto cachedImage : m_cachedImages) + cachedImage->didDraw(image); +} - size_t estimatedDecodedImageSize = m_image->width() * m_image->height() * 4; // no overflow check - return estimatedDecodedImageSize <= m_loader->frameLoader()->frame().settings().maximumDecodedImageSize(); +void CachedImage::CachedImageObserver::animationAdvanced(const Image* image) +{ + for (auto cachedImage : m_cachedImages) + cachedImage->animationAdvanced(image); } -void CachedImage::addIncrementalDataBuffer(ResourceBuffer* data) +void CachedImage::CachedImageObserver::changedInRect(const Image* image, const IntRect* rect) { - m_data = data; - if (!data) - return; + for (auto cachedImage : m_cachedImages) + cachedImage->changedInRect(image, rect); +} + +inline void CachedImage::clearImage() +{ + if (m_imageObserver) { + m_imageObserver->remove(*this); + m_imageObserver = nullptr; + } + m_image = nullptr; +} + +void CachedImage::addIncrementalDataBuffer(SharedBuffer& data) +{ + m_data = &data; createImage(); // Have the image update its data from its internal buffer. // It will not do anything now, but will delay decoding until // queried for info (like size or specific image frames). - bool sizeAvailable = m_image->setData(m_data->sharedBuffer(), false); + bool sizeAvailable = m_image->setData(&data, false); if (!sizeAvailable) return; - if (!canBeDrawn()) { - // There's no image to draw or its decoded size is bigger than the maximum allowed. + if (m_image->isNull()) { + // Image decoding failed. Either we need more image data or the image data is malformed. error(errorOccurred() ? status() : DecodeError); if (inCache()) - memoryCache()->remove(this); + MemoryCache::singleton().remove(*this); return; } - // Go ahead and tell our observers to try to draw. - // Each chunk from the network causes observers to repaint, which will - // force that chunk to decode. + // Tell our observers to try to draw. + // Each chunk from the network causes observers to repaint, which will force that chunk to decode. // It would be nice to only redraw the decoded band of the image, but with the current design // (decoding delayed until painting) that seems hard. notifyObservers(); @@ -425,32 +417,34 @@ void CachedImage::addIncrementalDataBuffer(ResourceBuffer* data) setEncodedSize(m_image->data() ? m_image->data()->size() : 0); } -void CachedImage::addDataBuffer(ResourceBuffer* data) +void CachedImage::addDataBuffer(SharedBuffer& data) { - ASSERT(m_options.dataBufferingPolicy == BufferData); + ASSERT(dataBufferingPolicy() == BufferData); addIncrementalDataBuffer(data); + CachedResource::addDataBuffer(data); } void CachedImage::addData(const char* data, unsigned length) { - ASSERT(m_options.dataBufferingPolicy == DoNotBufferData); - addIncrementalDataBuffer(ResourceBuffer::create(data, length).get()); + ASSERT(dataBufferingPolicy() == DoNotBufferData); + addIncrementalDataBuffer(SharedBuffer::create(data, length)); + CachedResource::addData(data, length); } -void CachedImage::finishLoading(ResourceBuffer* data) +void CachedImage::finishLoading(SharedBuffer* data) { m_data = data; if (!m_image && data) createImage(); if (m_image) - m_image->setData(m_data->sharedBuffer(), true); + m_image->setData(data, true); - if (!canBeDrawn()) { - // There's no image to draw or its decoded size is bigger than the maximum allowed. + if (!m_image || m_image->isNull()) { + // Image decoding failed; the image data is malformed. error(errorOccurred() ? status() : DecodeError); if (inCache()) - memoryCache()->remove(this); + MemoryCache::singleton().remove(*this); return; } @@ -460,6 +454,16 @@ void CachedImage::finishLoading(ResourceBuffer* data) CachedResource::finishLoading(data); } +void CachedImage::didReplaceSharedBufferContents() +{ + if (m_image) { + // Let the Image know that the SharedBuffer has been rejigged, so it can let go of any references to the heap-allocated resource buffer. + // FIXME(rdar://problem/24275617): It would be better if we could somehow tell the Image's decoder to swap in the new contents without destroying anything. + m_image->destroyDecodedData(true); + } + CachedResource::didReplaceSharedBufferContents(); +} + void CachedImage::error(CachedResource::Status status) { checkShouldPaintBrokenImage(); @@ -478,23 +482,20 @@ void CachedImage::responseReceived(const ResourceResponse& response) void CachedImage::destroyDecodedData() { bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage()); - if (isSafeToMakePurgeable() && canDeleteImage && !isLoading()) { - // Image refs the data buffer so we should not make it purgeable while the image is alive. - // Invoking addClient() will reconstruct the image object. - m_image = 0; + if (canDeleteImage && !isLoading() && !hasClients()) { + m_image = nullptr; setDecodedSize(0); - if (!MemoryCache::shouldMakeResourcePurgeableOnEviction()) - makePurgeable(true); } else if (m_image && !errorOccurred()) m_image->destroyDecodedData(); } -void CachedImage::decodedSizeChanged(const Image* image, int delta) +void CachedImage::decodedSizeChanged(const Image* image, long long delta) { if (!image || image != m_image) return; - - setDecodedSize(decodedSize() + delta); + + ASSERT(delta >= 0 || decodedSize() + delta >= 0); + setDecodedSize(static_cast<unsigned>(decodedSize() + delta)); } void CachedImage::didDraw(const Image* image) @@ -509,132 +510,47 @@ void CachedImage::didDraw(const Image* image) CachedResource::didAccessDecodedData(timeStamp); } -bool CachedImage::shouldPauseAnimation(const Image* image) -{ - if (!image || image != m_image) - return false; - - CachedResourceClientWalker<CachedImageClient> w(m_clients); - while (CachedImageClient* c = w.next()) { - if (c->willRenderImage(this)) - return false; - } - - return true; -} - void CachedImage::animationAdvanced(const Image* image) { if (!image || image != m_image) return; - notifyObservers(); + CachedResourceClientWalker<CachedImageClient> clientWalker(m_clients); + while (CachedImageClient* client = clientWalker.next()) + client->newImageAnimationFrameAvailable(*this); } -void CachedImage::changedInRect(const Image* image, const IntRect& rect) +void CachedImage::changedInRect(const Image* image, const IntRect* rect) { if (!image || image != m_image) return; - notifyObservers(&rect); -} - -void CachedImage::resumeAnimatingImagesForLoader(CachedResourceLoader* loader) -{ - const CachedResourceLoader::DocumentResourceMap& resources = loader->allCachedResources(); - - for (CachedResourceLoader::DocumentResourceMap::const_iterator it = resources.begin(), end = resources.end(); it != end; ++it) { - const CachedResourceHandle<CachedResource>& resource = it->value; - if (!resource || !resource->isImage()) - continue; - CachedImage* cachedImage = static_cast<CachedImage*>(resource.get()); - if (!cachedImage->hasImage()) - continue; - Image* image = cachedImage->image(); - if (!image->isBitmapImage()) - continue; - BitmapImage* bitmapImage = toBitmapImage(image); - if (!bitmapImage->canAnimate()) - continue; - cachedImage->animationAdvanced(bitmapImage); - } + notifyObservers(rect); } bool CachedImage::currentFrameKnownToBeOpaque(const RenderElement* renderer) { Image* image = imageForRenderer(renderer); - if (image->isBitmapImage()) - image->nativeImageForCurrentFrame(); // force decode return image->currentFrameKnownToBeOpaque(); } -#if ENABLE(DISK_IMAGE_CACHE) -bool CachedImage::canUseDiskImageCache() const -{ - if (isLoading() || errorOccurred()) - return false; - - if (!m_data) - return false; - - if (isPurgeable()) - return false; - - if (m_data->size() < diskImageCache().minimumImageSize()) - return false; - - // "Cache-Control: no-store" resources may be marked as such because they may - // contain sensitive information. We should not write these resources to disk. - if (m_response.cacheControlContainsNoStore()) - return false; - - // Testing shows that PDF images did not work when memory mapped. - // However, SVG images and Bitmap images were fine. See: - // <rdar://problem/8591834> Disk Image Cache should support PDF Images - if (m_response.mimeType() == "application/pdf") - return false; - - return true; -} - -void CachedImage::useDiskImageCache() +bool CachedImage::isOriginClean(SecurityOrigin* origin) { - ASSERT(canUseDiskImageCache()); - ASSERT(!isUsingDiskImageCache()); - m_data->sharedBuffer()->allowToBeMemoryMapped(); -} -#endif - -bool CachedImage::isOriginClean(SecurityOrigin* securityOrigin) -{ - if (!image()->hasSingleSecurityOrigin()) - return false; - if (passesAccessControlCheck(securityOrigin)) - return true; - return !securityOrigin->taintsCanvas(response().url()); + ASSERT_UNUSED(origin, origin); + ASSERT(this->origin()); + ASSERT(origin->toString() == this->origin()->toString()); + return !loadFailedOrCanceled() && isCORSSameOrigin(); } -#if USE(CF) -// FIXME: We should look to incorporate the functionality of CachedImageManual -// into CachedImage or find a better place for this class. -// FIXME: Remove the USE(CF) once we make MemoryCache::addImageToCache() platform-independent. -CachedImageManual::CachedImageManual(const URL& url, Image* image) - : CachedImage(url, image) - , m_fakeClient(std::make_unique<CachedImageClient>()) +CachedResource::RevalidationDecision CachedImage::makeRevalidationDecision(CachePolicy cachePolicy) const { - // Use the incoming URL in the response field. This ensures that code - // using the response directly, such as origin checks for security, - // actually see something. - m_response.setURL(url); -} - -bool CachedImageManual::mustRevalidateDueToCacheHeaders(CachePolicy) const -{ - // Do not revalidate manually cached images. This mechanism is used as a - // way to efficiently share an image from the client to content and - // the URL for that image may not represent a resource that can be - // retrieved by standard means. If the manual caching SPI is used, it is - // incumbent on the client to only use valid resources. - return false; + if (UNLIKELY(isManuallyCached())) { + // Do not revalidate manually cached images. This mechanism is used as a + // way to efficiently share an image from the client to content and + // the URL for that image may not represent a resource that can be + // retrieved by standard means. If the manual caching SPI is used, it is + // incumbent on the client to only use valid resources. + return RevalidationDecision::No; + } + return CachedResource::makeRevalidationDecision(cachePolicy); } -#endif } // namespace WebCore |