Crash when font completes downloading after calling 2D canvas setText() multiple...
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Sep 2015 05:33:16 +0000 (05:33 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Sep 2015 05:33:16 +0000 (05:33 +0000)
commit2e79a73552c7a89e56f89c656d3255a8eb1566bd
treeb547a9f1f09030d938ae1fdf6eada75bfad9a917
parent19d058b1cae39f18c75d6c1fe32b41ffb98399e1
Crash when font completes downloading after calling 2D canvas setText() multiple times
https://bugs.webkit.org/show_bug.cgi?id=148789

Reviewed by Darin Adler.

Source/WebCore:

The CSSFontSelector has a list of clients, and when fonts complete downloading, these
clients get a call back. CanvasRenderingContext2D::State is one such of these clients. However,
the CSSFontSelector may be destroyed and recreated at any time. We were getting into a case
where multiple CSSFontSelectors were thinking that the same CanvasRenderingContext2D::State were
their client. When the CanvasRenderingContext2D::State was destroyed, it only unregistered
itself from one of the CSSFontSelectors, which means the CSSFontSelector left over has a dangling
pointer to it.

The solution is to implement a new helper class, FontProxy, to hold the
CanvasRenderingContext2D::State's font, and maintain the invariant that this object is always
registered to exactly one CSSFontSelector, and this CSSFontSelector is the one which is associated
with the FontProxy's FontCascade object. This patch maintains this invariant, as well as protecting
all access to the State's FontCascade object so no one can reach in and change it without going
through functions which maintain the invariant.

Test: fast/canvas/font-selector-crash.html

* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::registerForInvalidationCallbacks):
(WebCore::CSSFontSelector::unregisterForInvalidationCallbacks):
(WebCore::CSSFontSelector::dispatchInvalidationCallbacks):
* css/CSSFontSelector.h:
* dom/Document.cpp:
(WebCore::Document::fontsNeedUpdate):
(WebCore::Document::fontSelector):
(WebCore::Document::clearStyleResolver):
* dom/Document.h:
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::State::State):
(WebCore::CanvasRenderingContext2D::State::operator=):
(WebCore::CanvasRenderingContext2D::FontProxy::~FontProxy):
(WebCore::CanvasRenderingContext2D::FontProxy::FontProxy):
(WebCore::CanvasRenderingContext2D::FontProxy::update):
(WebCore::CanvasRenderingContext2D::FontProxy::fontsNeedUpdate):
(WebCore::CanvasRenderingContext2D::FontProxy::initialize):
(WebCore::CanvasRenderingContext2D::FontProxy::fontMetrics):
(WebCore::CanvasRenderingContext2D::FontProxy::fontDescription):
(WebCore::CanvasRenderingContext2D::FontProxy::width):
(WebCore::CanvasRenderingContext2D::FontProxy::drawBidiText):
(WebCore::CanvasRenderingContext2D::font):
(WebCore::CanvasRenderingContext2D::setFont):
(WebCore::CanvasRenderingContext2D::measureText):
(WebCore::CanvasRenderingContext2D::drawTextInternal):
(WebCore::CanvasRenderingContext2D::State::~State): Deleted.
(WebCore::CanvasRenderingContext2D::State::fontsNeedUpdate): Deleted.
(WebCore::CanvasRenderingContext2D::accessFont): Deleted.
* html/canvas/CanvasRenderingContext2D.h:
* platform/graphics/FontSelector.h:

LayoutTests:

* fast/canvas/font-selector-crash-expected.txt: Added.
* fast/canvas/font-selector-crash.html: Added.
* fast/canvas/resources/font-selector-crash.ttf: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189421 268f45cc-cd09-0410-ab3c-d52691b4dbfc
12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/font-selector-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/font-selector-crash.html [new file with mode: 0644]
LayoutTests/fast/canvas/resources/font-selector-crash.ttf [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSFontSelector.cpp
Source/WebCore/css/CSSFontSelector.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
Source/WebCore/html/canvas/CanvasRenderingContext2D.h
Source/WebCore/platform/graphics/FontSelector.h