Commit 9fb4d73e authored by fs's avatar fs Committed by Commit bot

Add connected-paranoia in SVGElement::UpdateRelativeLengthsInformation

When (animated attribute) mutations are trigger by a 'id' change (via
an IdTargetObserver), relative lengths state may be revalidated while
the element are in the process of being removed from the document, but
has not yet been marked as such. If relative length state is updated in
such a case, the |elements_with_relative_lengths_| set could end up in
an inconsistent state.
Instead of only relying on the connected bit of the current element,
also check all the ancestors to make sure.

BUG=705200

Review-Url: https://codereview.chromium.org/2817913002
Cr-Commit-Position: refs/heads/master@{#464408}
parent 2d3892d9
<!DOCTYPE html>
<svg>
<g id="g1">
<text id="text1"/>
</g>
<g id="g2">
<text id="text2"/>
<animate values="100" href="#text2" attributeName="x" dur="4s"/>
</g>
</svg>
<p>PASS if no crash</p>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
var g1 = document.getElementById("g1");
var g2 = document.getElementById("g2");
var text1 = document.getElementById("text1");
window.onload = function() {
requestAnimationFrame(function() {
g1.remove();
text1.appendChild(document.querySelector("svg"));
g1.appendChild(g2);
if (window.testRunner)
testRunner.notifyDone();
});
};
</script>
......@@ -535,10 +535,17 @@ void SVGElement::UpdateRelativeLengthsInformation(
SVGElement* client_element) {
DCHECK(client_element);
// Through an unfortunate chain of events, we can end up calling this while a
// subtree is being removed, and before the subtree has been properly
// "disconnected". Hence check the entire ancestor chain to avoid propagating
// relative length clients up into ancestors that have already been
// disconnected.
// If we're not yet in a document, this function will be called again from
// insertedInto(). Do nothing now.
if (!isConnected())
return;
for (Node& current_node : NodeTraversal::InclusiveAncestorsOf(*this)) {
if (!current_node.isConnected())
return;
}
// An element wants to notify us that its own relative lengths state changed.
// Register it in the relative length map, and register us in the parent
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment