[webkit-changes] [WebKit/WebKit] ade36a: HTMLCanvasElement is orphaned causing a HTMLDocume...

Ryan Reno noreply at github.com
Sun May 7 05:27:03 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: ade36a336115d4a570eba730ef89fbfb168d3d21
      https://github.com/WebKit/WebKit/commit/ade36a336115d4a570eba730ef89fbfb168d3d21
  Author: Ryan Reno <rreno at apple.com>
  Date:   2023-05-07 (Sun, 07 May 2023)

  Changed paths:
    A LayoutTests/fast/canvas/canvas-gradient-can-outlive-context-expected.txt
    A LayoutTests/fast/canvas/canvas-gradient-can-outlive-context.html
    A LayoutTests/fast/canvas/canvas-state-stack-gradient-expected.txt
    A LayoutTests/fast/canvas/canvas-state-stack-gradient.html
    A LayoutTests/http/tests/canvas/ctx.2d-canvas-style-no-document-leak-expected.txt
    A LayoutTests/http/tests/canvas/ctx.2d-canvas-style-no-document-leak.html
    A LayoutTests/http/tests/canvas/resources/background.png
    A LayoutTests/http/tests/canvas/resources/ctx.2d-fillStyle-color.html
    A LayoutTests/http/tests/canvas/resources/ctx.2d-fillStyle-gradient.html
    A LayoutTests/http/tests/canvas/resources/ctx.2d-fillStyle-pattern.html
    M Source/WebCore/html/canvas/CanvasGradient.cpp
    M Source/WebCore/html/canvas/CanvasGradient.h
    M Source/WebCore/html/canvas/CanvasStyle.cpp
    M Source/WebCore/html/canvas/CanvasStyle.h

  Log Message:
  -----------
  HTMLCanvasElement is orphaned causing a HTMLDocument leak on YouTube video pages
https://bugs.webkit.org/show_bug.cgi?id=256262
rdar://108845985

Reviewed by Darin Adler.

CanvasRenderingContext2DBase has a State stack for setting up drawing
state. Two of the fields - strokeStyle and fillStyle - each hold CanvasStyle
objects. These objects may be set with colors or images or gradients. In
the case of a CanvasGradient, the gradient has a strong reference
to the context which creates a reference cycle.

CanvasRenderingContext2DBase -> State -> CanvasStyle -> CanvasGradient -> CanvasRenderingContext(2DBase)

What makes this cycle dangerous is the CanvasRenderingContext will
increase the ref count of an HTMLCanvasElement which, being a Node, will
increment the referencingNodeCount of a Document object. So if a
gradient is set on the context's fillStyle or strokeStyle we can cause a
Document leak if the state is never cleared like on YouTube video pages.

This patch changes the CanvasGradient object to hold a weak reference to
the CanvasRenderingContext instead of a strong reference which breaks the cycle.

* LayoutTests/fast/canvas
    Add tests to verify the now-decoupled lifetimes of gradient and
    context do not cause crashes.
* LayoutTests/fast/canvas/canvas-gradient-can-outlive-context-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-gradient-can-outlive-context.html: Added.
* LayoutTests/fast/canvas/canvas-state-stack-gradient-expected.txt: Added.
* LayoutTests/fast/canvas/canvas-state-stack-gradient.html: Added.

* LayoutTests/http/tests/canvas
    Add a test to verify that setting the style of a 2D canvas context
    does not leak Documents.
* LayoutTests/http/tests/canvas/ctx.2d-canvas-style-no-document-leak-expected.txt: Added.
* LayoutTests/http/tests/canvas/ctx.2d-canvas-style-no-document-leak.html: Added.
* LayoutTests/http/tests/canvas/resources/background.png: Added.
* LayoutTests/http/tests/canvas/resources/ctx.2d-fillStyle-color.html: Added.
* LayoutTests/http/tests/canvas/resources/ctx.2d-fillStyle-gradient.html: Added.
* LayoutTests/http/tests/canvas/resources/ctx.2d-fillStyle-pattern.html: Added.

* Source/WebCore/html/canvas/CanvasGradient.cpp:
(WebCore::CanvasGradient::addColorStop):
* Source/WebCore/html/canvas/CanvasGradient.h:
* Source/WebCore/html/canvas/CanvasStyle.cpp:
(WebCore::parseColor):
    Since the gradient can outlive the context that created it, we need
    to be able to parse colors without having a CSSParserContext
    reference. This overload calls CSSParser::parseColorWithoutContext
    in that case.
* Source/WebCore/html/canvas/CanvasStyle.h:
(WebCore::CanvasStyle::canvasGradient const):

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




More information about the webkit-changes mailing list