Crash when appending an SVG <use> element dynamically which has animated SVG <path...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Jul 2015 23:56:58 +0000 (23:56 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Jul 2015 23:56:58 +0000 (23:56 +0000)
commit1833f80a342669f19b22effd83562fbe70a3afc4
treedc37e5dbe252cb638e1749504cad2ca1be427832
parenta8299ca1e84ae14172602f84e25168cfab9a4970
Crash when appending an SVG <use> element dynamically which has animated SVG <path> element
https://bugs.webkit.org/show_bug.cgi?id=146690
<rdar://problem/20790376>

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2015-07-08
Reviewed by Dean Jackson.

Source/WebCore:

Test: svg/animations/insert-animate-use-path-while-animation.svg

The crashing call stack shows that
SVGAnimatedListPropertyTearOff<SVGPathSegList>::m_animVal is null when
trying to access it in synchronizeWrappersIfNeeded(). This happens because
animationStarted() was not called for this animatedType.

SVGAnimateElementBase::resetAnimatedType() calls
SVGAnimatedPathAnimator::startAnimValAnimation() at the beginning of the
animation. For the target element and all its instances, this function calls
SVGAnimatedPathSegListPropertyTearOff::animationStarted() which calls
SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted(). This
last function allocates the member m_animVal when calling
SVGAnimatedListPropertyTearOff<SVGPathSegList>::animVal().

When adding a new instance of the same animating target element,
SVGAnimateElementBase::resetAnimatedType() just keeps calling
SVGAnimatedPathAnimator::animValDidChange() for all the instances of the
targetElement without ensuring that all of them have started their
animations.

The fix is to make SVGAnimatedPathAnimator::resetAnimValToBaseVal() ensure
that animationStarted() is called for the targetElement and all its instances.

* svg/SVGAnimatedPath.cpp:
(WebCore::SVGAnimatedPathAnimator::startAnimValAnimation): Move resetting
the animation value and starting the animatedTypes code to a new overriding
function which is named resetAnimValToBaseVal().

(WebCore::SVGAnimatedPathAnimator::resetAnimValToBaseVal): Call the overriding
function which calls buildSVGPathByteStreamFromSVGPathSegList() as before
and ensure that all the animatedTypes have started their animations.

* svg/SVGAnimatedPath.h:

LayoutTests:

When adding dynamically a new <use> element which references an animated
SVG path after the animation starts, ensure that WebKit is not crashing.

* svg/animations/insert-animate-use-path-while-animation-expected.txt: Added.
* svg/animations/insert-animate-use-path-while-animation.svg: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@186541 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/svg/animations/insert-animate-use-path-while-animation-expected.txt [new file with mode: 0644]
LayoutTests/svg/animations/insert-animate-use-path-while-animation.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/svg/SVGAnimatedPath.cpp
Source/WebCore/svg/SVGAnimatedPath.h