- Revision
- 243820
- Author
- rn...@webkit.org
- Date
- 2019-04-03 13:04:37 -0700 (Wed, 03 Apr 2019)
Log Message
Crash in HTMLCanvasElement::createContext2d after the element got adopted to a new document
https://bugs.webkit.org/show_bug.cgi?id=196527
Reviewed by Antti Koivisto.
We need to update CanvasBase::m_scriptExecutionContext when HTMLCanvasElement moves from
one document to another. Fixed the bug by making CanvasBase::scriptExecutionContext make
a virtual function call instead of directly storing a raw pointer. In HTMLCanvasElement,
we use Node::scriptExecutionContext(). Use ContextDestructionObserver in CustomPaintCanvas
and OffscreenCanvas instead of a raw pointer.
Unfortunately, no new tests since there is no reproducible test case.
* html/CanvasBase.cpp:
(WebCore::CanvasBase::CanvasBase):
* html/CanvasBase.h:
(WebCore::CanvasBase::scriptExecutionContext const):
* html/CustomPaintCanvas.cpp:
(WebCore::CustomPaintCanvas::CustomPaintCanvas):
* html/CustomPaintCanvas.h:
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::HTMLCanvasElement):
* html/HTMLCanvasElement.h:
* html/OffscreenCanvas.cpp:
(WebCore::OffscreenCanvas::OffscreenCanvas):
* html/OffscreenCanvas.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (243819 => 243820)
--- trunk/Source/WebCore/ChangeLog 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/ChangeLog 2019-04-03 20:04:37 UTC (rev 243820)
@@ -1,3 +1,32 @@
+2019-04-02 Ryosuke Niwa <rn...@webkit.org>
+
+ Crash in HTMLCanvasElement::createContext2d after the element got adopted to a new document
+ https://bugs.webkit.org/show_bug.cgi?id=196527
+
+ Reviewed by Antti Koivisto.
+
+ We need to update CanvasBase::m_scriptExecutionContext when HTMLCanvasElement moves from
+ one document to another. Fixed the bug by making CanvasBase::scriptExecutionContext make
+ a virtual function call instead of directly storing a raw pointer. In HTMLCanvasElement,
+ we use Node::scriptExecutionContext(). Use ContextDestructionObserver in CustomPaintCanvas
+ and OffscreenCanvas instead of a raw pointer.
+
+ Unfortunately, no new tests since there is no reproducible test case.
+
+ * html/CanvasBase.cpp:
+ (WebCore::CanvasBase::CanvasBase):
+ * html/CanvasBase.h:
+ (WebCore::CanvasBase::scriptExecutionContext const):
+ * html/CustomPaintCanvas.cpp:
+ (WebCore::CustomPaintCanvas::CustomPaintCanvas):
+ * html/CustomPaintCanvas.h:
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::HTMLCanvasElement):
+ * html/HTMLCanvasElement.h:
+ * html/OffscreenCanvas.cpp:
+ (WebCore::OffscreenCanvas::OffscreenCanvas):
+ * html/OffscreenCanvas.h:
+
2019-04-03 Myles C. Maxfield <mmaxfi...@apple.com>
Remove support for -apple-trailing-word
Modified: trunk/Source/WebCore/html/CanvasBase.cpp (243819 => 243820)
--- trunk/Source/WebCore/html/CanvasBase.cpp 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/CanvasBase.cpp 2019-04-03 20:04:37 UTC (rev 243820)
@@ -35,8 +35,7 @@
namespace WebCore {
-CanvasBase::CanvasBase(ScriptExecutionContext* scriptExecutionContext)
- : m_scriptExecutionContext(scriptExecutionContext)
+CanvasBase::CanvasBase()
{
}
Modified: trunk/Source/WebCore/html/CanvasBase.h (243819 => 243820)
--- trunk/Source/WebCore/html/CanvasBase.h 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/CanvasBase.h 2019-04-03 20:04:37 UTC (rev 243820)
@@ -74,7 +74,7 @@
bool originClean() const { return m_originClean; }
virtual SecurityOrigin* securityOrigin() const { return nullptr; }
- ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; }
+ ScriptExecutionContext* scriptExecutionContext() const { return canvasBaseScriptExecutionContext(); }
CanvasRenderingContext* renderingContext() const;
@@ -98,8 +98,10 @@
bool callTracingActive() const;
protected:
- CanvasBase(ScriptExecutionContext*);
+ CanvasBase();
+ virtual ScriptExecutionContext* canvasBaseScriptExecutionContext() const = 0;
+
std::unique_ptr<CanvasRenderingContext> m_context;
private:
@@ -107,7 +109,6 @@
#ifndef NDEBUG
bool m_didNotifyObserversCanvasDestroyed { false };
#endif
- ScriptExecutionContext* m_scriptExecutionContext;
HashSet<CanvasObserver*> m_observers;
};
Modified: trunk/Source/WebCore/html/CustomPaintCanvas.cpp (243819 => 243820)
--- trunk/Source/WebCore/html/CustomPaintCanvas.cpp 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/CustomPaintCanvas.cpp 2019-04-03 20:04:37 UTC (rev 243820)
@@ -39,7 +39,7 @@
}
CustomPaintCanvas::CustomPaintCanvas(ScriptExecutionContext& context, unsigned width, unsigned height)
- : CanvasBase(&context)
+ : ContextDestructionObserver(&context)
, m_size(width, height)
{
}
Modified: trunk/Source/WebCore/html/CustomPaintCanvas.h (243819 => 243820)
--- trunk/Source/WebCore/html/CustomPaintCanvas.h 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/CustomPaintCanvas.h 2019-04-03 20:04:37 UTC (rev 243820)
@@ -44,7 +44,7 @@
class ImageBitmap;
class PaintRenderingContext2D;
-class CustomPaintCanvas final : public RefCounted<CustomPaintCanvas>, public CanvasBase {
+class CustomPaintCanvas final : public RefCounted<CustomPaintCanvas>, public CanvasBase, private ContextDestructionObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -80,6 +80,7 @@
void refCanvasBase() final { ref(); }
void derefCanvasBase() final { deref(); }
+ ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
mutable GraphicsContext* m_destinationGraphicsContext = nullptr;
mutable IntSize m_size;
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (243819 => 243820)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2019-04-03 20:04:37 UTC (rev 243820)
@@ -116,7 +116,6 @@
HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , CanvasBase(&document)
, m_size(defaultWidth, defaultHeight)
{
ASSERT(hasTagName(canvasTag));
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.h (243819 => 243820)
--- trunk/Source/WebCore/html/HTMLCanvasElement.h 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.h 2019-04-03 20:04:37 UTC (rev 243820)
@@ -179,6 +179,8 @@
void refCanvasBase() final { HTMLElement::ref(); }
void derefCanvasBase() final { HTMLElement::deref(); }
+ ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return HTMLElement::scriptExecutionContext(); }
+
FloatRect m_dirtyRect;
mutable IntSize m_size;
Modified: trunk/Source/WebCore/html/OffscreenCanvas.cpp (243819 => 243820)
--- trunk/Source/WebCore/html/OffscreenCanvas.cpp 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/OffscreenCanvas.cpp 2019-04-03 20:04:37 UTC (rev 243820)
@@ -38,7 +38,7 @@
}
OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& context, unsigned width, unsigned height)
- : CanvasBase(&context)
+ : ContextDestructionObserver(&context)
, m_size(width, height)
{
}
Modified: trunk/Source/WebCore/html/OffscreenCanvas.h (243819 => 243820)
--- trunk/Source/WebCore/html/OffscreenCanvas.h 2019-04-03 19:47:58 UTC (rev 243819)
+++ trunk/Source/WebCore/html/OffscreenCanvas.h 2019-04-03 20:04:37 UTC (rev 243820)
@@ -45,7 +45,7 @@
using OffscreenRenderingContext = RefPtr<WebGLRenderingContext>;
#endif
-class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData {
+class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData, private ContextDestructionObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -94,7 +94,8 @@
bool isOffscreenCanvas() const final { return true; }
- ScriptExecutionContext* scriptExecutionContext() const final { return CanvasBase::scriptExecutionContext(); }
+ ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
+ ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
EventTargetInterface eventTargetInterface() const final { return OffscreenCanvasEventTargetInterfaceType; }
void refEventTarget() final { ref(); }