Bug 1945081 - Window's indexed getter should not expose shadow DOM iframe, r=farre

Differential Revision: https://phabricator.services.mozilla.com/D240390
This commit is contained in:
Olli Pettay
2025-03-06 12:08:48 +00:00
parent 44b61dcf56
commit 420e8abf0f
6 changed files with 75 additions and 6 deletions

View File

@@ -752,6 +752,10 @@ static bool OwnerAllowsFullscreen(const Element& aEmbedder) {
void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
mEmbeddedByThisProcess = true;
if (RefPtr<WindowContext> parent = GetParentWindowContext()) {
parent->ClearLightDOMChildren();
}
// Update embedder-element-specific fields in a shared transaction.
// Don't do this when clearing our embedder, as we're being destroyed either
// way.
@@ -1220,6 +1224,21 @@ Span<RefPtr<BrowsingContext>> BrowsingContext::NonSyntheticChildren() const {
return Span<RefPtr<BrowsingContext>>();
}
BrowsingContext* BrowsingContext::NonSyntheticLightDOMChildAt(
uint32_t aIndex) const {
if (WindowContext* current = mCurrentWindowContext) {
return current->NonSyntheticLightDOMChildAt(aIndex);
}
return nullptr;
}
uint32_t BrowsingContext::NonSyntheticLightDOMChildrenCount() const {
if (WindowContext* current = mCurrentWindowContext) {
return current->NonSyntheticLightDOMChildrenCount();
}
return 0;
}
void BrowsingContext::GetWindowContexts(
nsTArray<RefPtr<WindowContext>>& aWindows) {
aWindows.AppendElements(mWindowContexts);

View File

@@ -541,6 +541,9 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
Span<RefPtr<BrowsingContext>> NonSyntheticChildren() const;
BrowsingContext* NonSyntheticLightDOMChildAt(uint32_t aIndex) const;
uint32_t NonSyntheticLightDOMChildrenCount() const;
const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
return mWindowContexts;
}

View File

@@ -137,6 +137,8 @@ void WindowContext::AppendChildBrowsingContext(
"Mismatched groups?");
MOZ_DIAGNOSTIC_ASSERT(!mChildren.Contains(aBrowsingContext));
ClearLightDOMChildren();
mChildren.AppendElement(aBrowsingContext);
if (!aBrowsingContext->IsEmbedderTypeObjectOrEmbed()) {
mNonSyntheticChildren.AppendElement(aBrowsingContext);
@@ -153,6 +155,7 @@ void WindowContext::RemoveChildBrowsingContext(
BrowsingContext* aBrowsingContext) {
MOZ_DIAGNOSTIC_ASSERT(Group() == aBrowsingContext->Group(),
"Mismatched groups?");
ClearLightDOMChildren();
mChildren.RemoveElement(aBrowsingContext);
mNonSyntheticChildren.RemoveElement(aBrowsingContext);
@@ -177,6 +180,36 @@ void WindowContext::UpdateChildSynthetic(BrowsingContext* aBrowsingContext,
}
}
void WindowContext::ClearLightDOMChildren() {
mNonSyntheticLightDOMChildren.reset();
}
void WindowContext::EnsureLightDOMChildren() {
if (mNonSyntheticLightDOMChildren.isSome()) {
return;
}
mNonSyntheticLightDOMChildren.emplace();
for (const RefPtr<BrowsingContext>& bc : mNonSyntheticChildren) {
if (Element* el = bc->GetEmbedderElement(); el && el->IsInShadowTree()) {
continue;
}
mNonSyntheticLightDOMChildren->AppendElement(bc);
}
}
BrowsingContext* WindowContext::NonSyntheticLightDOMChildAt(uint32_t aIndex) {
EnsureLightDOMChildren();
return aIndex < mNonSyntheticLightDOMChildren->Length()
? mNonSyntheticLightDOMChildren->ElementAt(aIndex).get()
: nullptr;
}
uint32_t WindowContext::NonSyntheticLightDOMChildrenCount() {
EnsureLightDOMChildren();
return mNonSyntheticLightDOMChildren->Length();
}
void WindowContext::SendCommitTransaction(ContentParent* aParent,
const BaseTransaction& aTxn,
uint64_t aEpoch) {
@@ -668,6 +701,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WindowContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildren)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNonSyntheticChildren)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNonSyntheticLightDOMChildren);
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@@ -675,6 +709,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WindowContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNonSyntheticChildren)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNonSyntheticLightDOMChildren)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
} // namespace dom

View File

@@ -166,6 +166,9 @@ class WindowContext : public nsISupports, public nsWrapperCache {
return mNonSyntheticChildren;
}
BrowsingContext* NonSyntheticLightDOMChildAt(uint32_t aIndex);
uint32_t NonSyntheticLightDOMChildrenCount();
// Cast this object to it's parent-process canonical form.
WindowGlobalParent* Canonical();
@@ -366,6 +369,10 @@ class WindowContext : public nsISupports, public nsWrapperCache {
// BrowsingContext.
void RecomputeCanExecuteScripts(bool aApplyChanges = true);
void ClearLightDOMChildren();
void EnsureLightDOMChildren();
const uint64_t mInnerWindowId;
const uint64_t mOuterWindowId;
RefPtr<BrowsingContext> mBrowsingContext;
@@ -386,6 +393,12 @@ class WindowContext : public nsISupports, public nsWrapperCache {
// from named targeting, `Window.frames` etc.
nsTArray<RefPtr<BrowsingContext>> mNonSyntheticChildren;
// mNonSyntheticLightDOMChildren is otherwise the same as
// mNonSyntheticChildren, but it contains only those BrowsingContexts where
// embedder is in light DOM. The contents of the array are computed lazily and
// cleared if there are changes to mChildren.
Maybe<nsTArray<RefPtr<BrowsingContext>>> mNonSyntheticLightDOMChildren;
bool mIsDiscarded = false;
bool mIsInProcess = false;