From 4ea1fca123ecf1e5aec961087f4b9771b24c57ea Mon Sep 17 00:00:00 2001 From: James Teh Date: Wed, 19 Apr 2023 23:16:15 +0000 Subject: [PATCH] Bug 1751943: Fix doc tree mutation during AddChildDoc. r=nlapre Differential Revision: https://phabricator.services.mozilla.com/D173916 --- accessible/ipc/DocAccessibleParent.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp index 9d76a0180075..05c33a122915 100644 --- a/accessible/ipc/DocAccessibleParent.cpp +++ b/accessible/ipc/DocAccessibleParent.cpp @@ -906,11 +906,13 @@ ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, if (bridge) { #if defined(XP_WIN) if (!StaticPrefs::accessibility_cache_enabled_AtStartup()) { + RefPtr thisDoc = this; + RefPtr childDoc = aChildDoc; // Send a COM proxy for the embedded document to the embedder process // hosting the iframe. This will be returned as the child of the // embedder OuterDocAccessible. RefPtr docAcc; - aChildDoc->GetCOMInterface((void**)getter_AddRefs(docAcc)); + childDoc->GetCOMInterface((void**)getter_AddRefs(docAcc)); MOZ_ASSERT(docAcc); if (docAcc) { RefPtr docWrapped( @@ -920,30 +922,39 @@ ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, IDispatchHolder docHolder(std::move(docPtr)); if (bridge->SendSetEmbeddedDocAccessibleCOMProxy(docHolder)) { # if defined(MOZ_SANDBOX) - aChildDoc->mDocProxyStream = docHolder.GetPreservedStream(); + childDoc->mDocProxyStream = docHolder.GetPreservedStream(); # endif // defined(MOZ_SANDBOX) } } if (!outerDoc) { return IPC_FAIL(this, "OuterDoc removed while adding child doc"); } + if (childDoc->IsShutdown()) { + return IPC_FAIL(this, "Child doc removed while adding it"); + } // Send a COM proxy for the embedder OuterDocAccessible to the embedded // document process. This will be returned as the parent of the // embedded document. - aChildDoc->SendParentCOMProxy(outerDoc); + childDoc->SendParentCOMProxy(outerDoc); + if (childDoc->IsShutdown()) { + return IPC_FAIL(this, "Child doc removed while adding it"); + } if (nsWinUtils::IsWindowEmulationStarted()) { // The embedded document should use the same emulated window handle as // its embedder. It will return the embedder document (not a window // accessible) as the parent accessible, so we pass a null accessible // when sending the window to the embedded document. - Unused << aChildDoc->SendEmulatedWindow( + Unused << childDoc->SendEmulatedWindow( reinterpret_cast(mEmulatedWindowHandle), nullptr); } + if (thisDoc->IsShutdown()) { + return IPC_FAIL(this, "Parent doc removed while adding child doc"); + } // Send a COM proxy for the top level document to the embedded document // process. This will be returned when the client calls QueryService // with SID_IAccessibleContentDocument on an accessible in the embedded // document. - DocAccessibleParent* topDoc = this; + DocAccessibleParent* topDoc = thisDoc; while (DocAccessibleParent* parentDoc = topDoc->ParentDoc()) { topDoc = parentDoc; } @@ -957,7 +968,7 @@ ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, IAccessibleHolder::COMPtrType topDocPtr( mscom::ToProxyUniquePtr(std::move(topDocWrapped))); IAccessibleHolder topDocHolder(std::move(topDocPtr)); - if (aChildDoc->SendTopLevelDocCOMProxy(topDocHolder)) { + if (childDoc->SendTopLevelDocCOMProxy(topDocHolder)) { # if defined(MOZ_SANDBOX) aChildDoc->mTopLevelDocProxyStream = topDocHolder.GetPreservedStream(); @@ -967,6 +978,9 @@ ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, if (!outerDoc) { return IPC_FAIL(this, "OuterDoc removed while adding child doc"); } + if (childDoc->IsShutdown()) { + return IPC_FAIL(this, "Child doc removed while adding it"); + } } if (nsWinUtils::IsWindowEmulationStarted()) { aChildDoc->SetEmulatedWindowHandle(mEmulatedWindowHandle);