Skip to content

Commit

Permalink
Merge r243820 - Crash in HTMLCanvasElement::createContext2d after the…
Browse files Browse the repository at this point in the history
… 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:
  • Loading branch information
rniwa authored and carlosgcampos committed Apr 8, 2019
1 parent 12dfc06 commit 523a2ae
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 11 deletions.
29 changes: 29 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,32 @@
2019-04-02 Ryosuke Niwa <rniwa@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-03-26 Dean Jackson <dino@apple.com>

vertexAttribPointer must restrict offset parameter
Expand Down
3 changes: 1 addition & 2 deletions Source/WebCore/html/CanvasBase.cpp
Expand Up @@ -34,8 +34,7 @@

namespace WebCore {

CanvasBase::CanvasBase(ScriptExecutionContext* scriptExecutionContext)
: m_scriptExecutionContext(scriptExecutionContext)
CanvasBase::CanvasBase()
{
}

Expand Down
7 changes: 4 additions & 3 deletions Source/WebCore/html/CanvasBase.h
Expand Up @@ -74,7 +74,7 @@ class CanvasBase {
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;

Expand All @@ -98,7 +98,9 @@ class CanvasBase {
bool callTracingActive() const;

protected:
CanvasBase(ScriptExecutionContext*);
CanvasBase();

virtual ScriptExecutionContext* canvasBaseScriptExecutionContext() const = 0;

std::unique_ptr<CanvasRenderingContext> m_context;

Expand All @@ -107,7 +109,6 @@ class CanvasBase {
#ifndef NDEBUG
bool m_didNotifyObserversCanvasDestroyed { false };
#endif
ScriptExecutionContext* m_scriptExecutionContext;
HashSet<CanvasObserver*> m_observers;
};

Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/CustomPaintCanvas.cpp
Expand Up @@ -39,7 +39,7 @@ Ref<CustomPaintCanvas> CustomPaintCanvas::create(ScriptExecutionContext& context
}

CustomPaintCanvas::CustomPaintCanvas(ScriptExecutionContext& context, unsigned width, unsigned height)
: CanvasBase(&context)
: ContextDestructionObserver(&context)
, m_size(width, height)
{
}
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/html/CustomPaintCanvas.h
Expand Up @@ -44,7 +44,7 @@ namespace WebCore {
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:

Expand Down Expand Up @@ -80,6 +80,7 @@ class CustomPaintCanvas final : public RefCounted<CustomPaintCanvas>, public Can

void refCanvasBase() final { ref(); }
void derefCanvasBase() final { deref(); }
ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }

mutable GraphicsContext* m_destinationGraphicsContext = nullptr;
mutable IntSize m_size;
Expand Down
1 change: 0 additions & 1 deletion Source/WebCore/html/HTMLCanvasElement.cpp
Expand Up @@ -120,7 +120,6 @@ static size_t activePixelMemory = 0;

HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
, CanvasBase(&document)
, m_size(defaultWidth, defaultHeight)
{
ASSERT(hasTagName(canvasTag));
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/html/HTMLCanvasElement.h
Expand Up @@ -185,6 +185,8 @@ class HTMLCanvasElement final : public HTMLElement, public CanvasBase {
void refCanvasBase() final { HTMLElement::ref(); }
void derefCanvasBase() final { HTMLElement::deref(); }

ScriptExecutionContext* canvasBaseScriptExecutionContext() const final { return HTMLElement::scriptExecutionContext(); }

FloatRect m_dirtyRect;
mutable IntSize m_size;

Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/OffscreenCanvas.cpp
Expand Up @@ -38,7 +38,7 @@ Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& context, un
}

OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& context, unsigned width, unsigned height)
: CanvasBase(&context)
: ContextDestructionObserver(&context)
, m_size(width, height)
{
}
Expand Down
5 changes: 3 additions & 2 deletions Source/WebCore/html/OffscreenCanvas.h
Expand Up @@ -45,7 +45,7 @@ class WebGLRenderingContext;
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:

Expand Down Expand Up @@ -94,7 +94,8 @@ class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasB

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(); }
Expand Down

0 comments on commit 523a2ae

Please sign in to comment.