Bug 1505887 - Fix FindChromeAccessOnlySubtreeOwner so that we handle UA widget being ChromeOnlyAccess root. r=smaug

A single video controls test crashed without this, while dereferencing
a null anonOwnerRelated in:

  https://searchfox.org/mozilla-central/rev/c0b26c40769a1e5607a1ae8be37fe64df64fc55e/dom/base/FragmentOrElement.cpp#964

I think this is the right fix for it, but the code that uses this is kind of
complex, so worth double-checking... :)
This commit is contained in:
Emilio Cobos Álvarez 2018-11-15 22:28:56 +01:00
Родитель 3e9ed9a373
Коммит 3b96bec450
3 изменённых файлов: 33 добавлений и 36 удалений

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

@ -883,17 +883,18 @@ FragmentOrElement::GetChildren(uint32_t aFilter)
return list.forget();
}
static nsIContent*
FindChromeAccessOnlySubtreeOwner(nsIContent* aContent)
static nsINode*
FindChromeAccessOnlySubtreeOwner(nsINode* aNode)
{
if (aContent->ChromeOnlyAccess()) {
bool chromeAccessOnly = false;
while (aContent && !chromeAccessOnly) {
chromeAccessOnly = aContent->IsRootOfChromeAccessOnlySubtree();
aContent = aContent->GetParent();
if (!aNode->ChromeOnlyAccess()) {
return aNode;
}
while (aNode && !aNode->IsRootOfChromeAccessOnlySubtree()) {
aNode = aNode->GetParentNode();
}
return aContent;
return aNode ? aNode->GetParentOrHostNode() : nullptr;
}
already_AddRefed<nsINode>
@ -904,11 +905,7 @@ FindChromeAccessOnlySubtreeOwner(EventTarget* aTarget)
return node.forget();
}
if (!node->IsContent()) {
return nullptr;
}
node = FindChromeAccessOnlySubtreeOwner(node->AsContent());
node = FindChromeAccessOnlySubtreeOwner(node);
return node.forget();
}
@ -951,9 +948,9 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
(aVisitor.mEvent->mOriginalTarget == this &&
(aVisitor.mRelatedTargetIsInAnon =
relatedTarget->ChromeOnlyAccess()))) {
nsIContent* anonOwner = FindChromeAccessOnlySubtreeOwner(this);
nsINode* anonOwner = FindChromeAccessOnlySubtreeOwner(this);
if (anonOwner) {
nsIContent* anonOwnerRelated =
nsINode* anonOwnerRelated =
FindChromeAccessOnlySubtreeOwner(relatedTarget);
if (anonOwnerRelated) {
// Note, anonOwnerRelated may still be inside some other

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

@ -178,26 +178,6 @@ public:
*/
virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter) = 0;
/**
* Get whether this content is C++-generated anonymous content
* @see nsIAnonymousContentCreator
* @return whether this content is anonymous
*/
bool IsRootOfNativeAnonymousSubtree() const
{
NS_ASSERTION(!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) ||
(HasFlag(NODE_IS_ANONYMOUS_ROOT) &&
HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)),
"Some flags seem to be missing!");
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT);
}
bool IsRootOfChromeAccessOnlySubtree() const
{
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT |
NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS);
}
/**
* Makes this content anonymous
* @see nsIAnonymousContentCreator

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

@ -1232,6 +1232,26 @@ public:
return HasFlag(NODE_IS_IN_SHADOW_TREE);
}
/**
* Get whether this node is C++-generated anonymous content
* @see nsIAnonymousContentCreator
* @return whether this content is anonymous
*/
bool IsRootOfNativeAnonymousSubtree() const
{
NS_ASSERTION(!HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) ||
(HasFlag(NODE_IS_ANONYMOUS_ROOT) &&
HasFlag(NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE)),
"Some flags seem to be missing!");
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT);
}
bool IsRootOfChromeAccessOnlySubtree() const
{
return HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT |
NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS);
}
/**
* Returns true if |this| node is the common ancestor of the start/end
* nodes of a Range in a Selection or a descendant of such a common ancestor.