source: webkit/trunk/Source/WebCore/loader/ImageLoader.h

Last change on this file was 293804, checked in by Chris Dumez, 3 years ago

Crash under WebCore: WebCore::CachedResourceClientWalker<WebCore::CachedImageClient>::next()
https://bugs.webkit.org/show_bug.cgi?id=240072
<rdar://92717726>

Reviewed by Geoff Garen.

Have CachedResource and CachedResourceClientWalker hold the clients via WeakPtrs instead of
raw pointers and null check them before usage. This is a lot safer.

  • Source/WTF/WTF.xcodeproj/project.pbxproj:
  • Source/WTF/wtf/WeakHashCountedSet.h: Added.

(WTF::WeakHashCountedSet::begin):
(WTF::WeakHashCountedSet::end):
(WTF::WeakHashCountedSet::begin const):
(WTF::WeakHashCountedSet::end const):
(WTF::WeakHashCountedSet::find):
(WTF::WeakHashCountedSet::find const):
(WTF::WeakHashCountedSet::contains const):
(WTF::WeakHashCountedSet::computeSize const):
(WTF::WeakHashCountedSet::clear):
(WTF::Counter>::add):
(WTF::Counter>::remove):

  • Source/WebCore/html/HTMLLinkElement.h:
  • Source/WebCore/loader/DocumentThreadableLoader.h:
  • Source/WebCore/loader/ImageLoader.h:
  • Source/WebCore/loader/LinkLoader.h:
  • Source/WebCore/loader/cache/CachedImage.cpp:

(WebCore::CachedImage::addClientWaitingForAsyncDecoding):

  • Source/WebCore/loader/cache/CachedResource.cpp:

(WebCore::CachedResource::didAddClient):
(WebCore::CachedResource::addClientToSet):
(WebCore::CachedResource::removeClient):
(WebCore::CachedResource::switchClientsToRevalidatedResource):

  • Source/WebCore/loader/cache/CachedResource.h:

(WebCore::CachedResource::hasClients const):
(WebCore::CachedResource::hasClient):
(WebCore::CachedResource::numberOfClients const):

  • Source/WebCore/loader/cache/CachedResourceClient.h:
  • Source/WebCore/loader/cache/CachedResourceClientWalker.h:

(WebCore::CachedResourceClientWalker::CachedResourceClientWalker):
(WebCore::CachedResourceClientWalker::next):

  • Source/WebCore/rendering/RenderObject.h:

Canonical link: https://commits.webkit.org/250278@main

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1/*
2 * Copyright (C) 1999 Lars Knoll ([email protected])
3 * (C) 1999 Antti Koivisto ([email protected])
4 * Copyright (C) 2004, 2009 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#pragma once
24
25#include "CachedImageClient.h"
26#include "CachedResourceHandle.h"
27#include "Element.h"
28#include "Timer.h"
29#include <wtf/Vector.h>
30#include <wtf/text/AtomString.h>
31
32namespace WebCore {
33
34class DeferredPromise;
35class Document;
36class ImageLoader;
37class Page;
38class RenderImageResource;
39
40template<typename T> class EventSender;
41using ImageEventSender = EventSender<ImageLoader>;
42
43enum class RelevantMutation : bool { No, Yes };
44
45class ImageLoader : public CachedImageClient {
46 WTF_MAKE_FAST_ALLOCATED;
47public:
48 virtual ~ImageLoader();
49
50 // This function should be called when the element is attached to a document; starts
51 // loading if a load hasn't already been started.
52 void updateFromElement(RelevantMutation = RelevantMutation::No);
53
54 // This function should be called whenever the 'src' attribute is set, even if its value
55 // doesn't change; starts new load unconditionally (matches Firefox and Opera behavior).
56 void updateFromElementIgnoringPreviousError(RelevantMutation = RelevantMutation::No);
57
58 void elementDidMoveToNewDocument(Document&);
59
60 Element& element() { return m_element; }
61 const Element& element() const { return m_element; }
62
63 bool imageComplete() const { return m_imageComplete; }
64
65 CachedImage* image() const { return m_image.get(); }
66 void clearImage(); // Cancels pending beforeload and load events, and doesn't dispatch new ones.
67
68 size_t pendingDecodePromisesCountForTesting() const { return m_decodingPromises.size(); }
69 void decode(Ref<DeferredPromise>&&);
70
71 void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
72
73 // FIXME: Delete this code. beforeload event no longer exists.
74 bool hasPendingBeforeLoadEvent() const { return m_hasPendingBeforeLoadEvent; }
75 bool hasPendingActivity() const { return m_hasPendingLoadEvent || m_hasPendingErrorEvent; }
76
77 void dispatchPendingEvent(ImageEventSender*);
78
79 static void dispatchPendingBeforeLoadEvents(Page*);
80 static void dispatchPendingLoadEvents(Page*);
81 static void dispatchPendingErrorEvents(Page*);
82
83 void loadDeferredImage();
84
85 bool isDeferred() const { return m_lazyImageLoadState == LazyImageLoadState::Deferred || m_lazyImageLoadState == LazyImageLoadState::LoadImmediately; }
86
87 Document& document() { return m_element.document(); }
88
89protected:
90 explicit ImageLoader(Element&);
91 void notifyFinished(CachedResource&, const NetworkLoadMetrics&) override;
92 void didStartLoading() override;
93
94private:
95 void resetLazyImageLoading(Document&);
96 enum class LazyImageLoadState : uint8_t { None, Deferred, LoadImmediately, FullImage };
97
98 virtual void dispatchLoadEvent() = 0;
99 virtual String sourceURI(const AtomString&) const = 0;
100
101 void updatedHasPendingEvent();
102 void didUpdateCachedImage(RelevantMutation, CachedResourceHandle<CachedImage>&&);
103
104 void dispatchPendingBeforeLoadEvent();
105 void dispatchPendingLoadEvent();
106 void dispatchPendingErrorEvent();
107
108 RenderImageResource* renderImageResource();
109 void updateRenderer();
110
111 void clearImageWithoutConsideringPendingLoadEvent();
112 void clearFailedLoadURL();
113
114 bool hasPendingDecodePromises() const { return !m_decodingPromises.isEmpty(); }
115 void resolveDecodePromises();
116 void rejectDecodePromises(ASCIILiteral message);
117 void decode();
118
119 void timerFired();
120
121 VisibleInViewportState imageVisibleInViewport(const Document&) const override;
122
123 Element& m_element;
124 CachedResourceHandle<CachedImage> m_image;
125 Timer m_derefElementTimer;
126 RefPtr<Element> m_protectedElement;
127 AtomString m_failedLoadURL;
128 Vector<RefPtr<DeferredPromise>> m_decodingPromises;
129 bool m_hasPendingBeforeLoadEvent : 1;
130 bool m_hasPendingLoadEvent : 1;
131 bool m_hasPendingErrorEvent : 1;
132 bool m_imageComplete : 1;
133 bool m_loadManually : 1;
134 bool m_elementIsProtected : 1;
135 bool m_inUpdateFromElement : 1;
136 LazyImageLoadState m_lazyImageLoadState { LazyImageLoadState::None };
137};
138
139}
Note: See TracBrowser for help on using the repository browser.