From 6d37fc005d0aabc9ddaecfb2ce7095107f3fa34f Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Tue, 23 May 2017 14:40:04 -0600 Subject: [PATCH] Bug 1361879: Ensure that sdnAccessible holds a strong reference to its creating AccessibleWrap if it was instantiated as a tearoff; r=tbsaunde MozReview-Commit-ID: CCgwa7BHUBK --HG-- extra : rebase_source : 974cadff7b42e3b38ba547b85792b00ebb12aecf extra : histedit_source : 56a8ed517994bafc02594ba2d9fbf014b47b89da%2C9c63efae8b6a3e056b76c788b6a3f21ddbd27972 --- accessible/windows/msaa/AccessibleWrap.cpp | 2 +- accessible/windows/sdn/sdnAccessible-inl.h | 18 +++++++++++++++--- accessible/windows/sdn/sdnAccessible.cpp | 4 ++-- accessible/windows/sdn/sdnAccessible.h | 10 +++++++++- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index 92c0a3e820c4..4449f9434a84 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -134,7 +134,7 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv) if (IsDefunct() || (!HasOwnContent() && !IsDoc())) return E_NOINTERFACE; - *ppv = static_cast(new sdnAccessible(GetNode())); + *ppv = static_cast(new sdnAccessible(WrapNotNull(this))); } if (nullptr == *ppv) { diff --git a/accessible/windows/sdn/sdnAccessible-inl.h b/accessible/windows/sdn/sdnAccessible-inl.h index a3d1a95e8094..4bbb4e5f7aeb 100644 --- a/accessible/windows/sdn/sdnAccessible-inl.h +++ b/accessible/windows/sdn/sdnAccessible-inl.h @@ -21,11 +21,23 @@ sdnAccessible::GetDocument() const return GetExistingDocAccessible(mNode->OwnerDoc()); } -inline Accessible* -sdnAccessible::GetAccessible() const +inline AccessibleWrap* +sdnAccessible::GetAccessible() { + if (mWrap) { + return mWrap; + } + DocAccessible* document = GetDocument(); - return document ? document->GetAccessibleEvenIfNotInMap(mNode) : nullptr; + if (!document) { + return nullptr; + } + + // Once we have an accessible, we should hold a reference to it so that we + // may preserve object identity. + mWrap = + static_cast(document->GetAccessibleEvenIfNotInMap(mNode)); + return mWrap; } } // namespace a11y diff --git a/accessible/windows/sdn/sdnAccessible.cpp b/accessible/windows/sdn/sdnAccessible.cpp index 9a6a34b0ca64..74f420f61c4c 100644 --- a/accessible/windows/sdn/sdnAccessible.cpp +++ b/accessible/windows/sdn/sdnAccessible.cpp @@ -38,7 +38,7 @@ sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr) return S_OK; } - AccessibleWrap* accessible = static_cast(GetAccessible()); + AccessibleWrap* accessible = GetAccessible(); if (accessible) return accessible->QueryInterface(aREFIID, aInstancePtr); @@ -98,7 +98,7 @@ sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName, // application can compare this to the childID we return for events such as // focus events, to correlate back to data nodes in their internal object // model. - Accessible* accessible = GetAccessible(); + AccessibleWrap* accessible = GetAccessible(); if (accessible) { *aUniqueID = AccessibleWrap::GetChildIDFor(accessible); } else { diff --git a/accessible/windows/sdn/sdnAccessible.h b/accessible/windows/sdn/sdnAccessible.h index f8b785a04baa..03d44bd6b1c1 100644 --- a/accessible/windows/sdn/sdnAccessible.h +++ b/accessible/windows/sdn/sdnAccessible.h @@ -12,6 +12,7 @@ #include "IUnknownImpl.h" #include "mozilla/Attributes.h" +#include "mozilla/NotNull.h" namespace mozilla { namespace a11y { @@ -27,6 +28,12 @@ public: } ~sdnAccessible() { } + explicit sdnAccessible(NotNull aAccWrap) + : mNode(aAccWrap->GetNode()) + , mWrap(aAccWrap) + { + } + /** * Retrun if the object is defunct. */ @@ -40,7 +47,7 @@ public: /* * Return associated accessible if any. */ - Accessible* GetAccessible() const; + AccessibleWrap* GetAccessible(); //IUnknown DECL_IUNKNOWN @@ -111,6 +118,7 @@ public: private: nsCOMPtr mNode; + RefPtr mWrap; }; } // namespace a11y