Bug 1326194 - Properly unlink observed targets. m=mrbkap r=mrbkap

MozReview-Commit-ID: EWk3kcoIteE

--HG--
extra : rebase_source : e1b68aaa8278b514c8b008db34a2519076313f7e
This commit is contained in:
Tobias Schneider 2017-01-19 14:51:09 -08:00
Родитель fe31d4bd44
Коммит 6bd84bf9d8
4 изменённых файлов: 52 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript">
// Crashes if 'target' doesn't get properly unlinked in nsNodeUtils::LastRelease
function crash() {
var target = document.getElementById('target');
var io = new IntersectionObserver(function () { }, { });
io.observe(target);
document.body.removeChild(target);
}
</script>
</head>
<body onload="crash()">
<div id="target" style="background: red; width: 50px; height: 50px"></div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript">
// Crashes if 'target' doesn't get properly unlinked in FragmentOrElement::Unlink
function crash() {
var target = document.createElement('div');
// By setting a custom prop we create a cycle between JS and C++ that requires the CC to break.
target.foo = 'bar';
var io = new IntersectionObserver(function () { }, { });
io.observe(target);
}
</script>
</head>
<body onload="crash()">
</body>
</html>

Просмотреть файл

@ -209,3 +209,5 @@ load 1230422.html
load 1251361.html
load 1304437.html
pref(dom.IntersectionObserver.enabled,true) load 1324209.html
pref(dom.IntersectionObserver.enabled,true) load 1326194-1.html
pref(dom.IntersectionObserver.enabled,true) load 1326194-2.html

Просмотреть файл

@ -297,6 +297,16 @@ nsNodeUtils::LastRelease(nsINode* aNode)
NodeWillBeDestroyed, (aNode));
}
if (aNode->IsElement()) {
Element* elem = aNode->AsElement();
FragmentOrElement::nsDOMSlots* domSlots =
static_cast<FragmentOrElement::nsDOMSlots*>(slots);
for (auto iter = domSlots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Key();
observer->UnlinkTarget(*elem);
}
}
delete slots;
aNode->mSlots = nullptr;
}