diff options
author | Michael Stahl <mstahl@redhat.com> | 2014-08-17 22:50:01 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2014-08-20 16:40:13 +0200 |
commit | 939edde802b4de9abb5c9d23c61abb37916ce357 (patch) | |
tree | 350e6dd4fc28d695f37745ff7195cd8b4ec2bc76 | |
parent | c71c1b2bb3b0a1767cd062e46e7dd81cc1027fb1 (diff) |
fdo#72695: avoid double-free race condition for SwXDocumentIndexMark
Change-Id: I08fef7f1de4cce468a4936e33d3684f847e1aa5b
-rw-r--r-- | sw/source/core/inc/unoidx.hxx | 6 | ||||
-rw-r--r-- | sw/source/core/unocore/unocoll.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/unocore/unocrsrhelper.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/unocore/unoidx.cxx | 34 | ||||
-rw-r--r-- | sw/source/core/unocore/unoportenum.cxx | 2 |
5 files changed, 32 insertions, 14 deletions
diff --git a/sw/source/core/inc/unoidx.hxx b/sw/source/core/inc/unoidx.hxx index a1b5d1d0d5ae..a877774b0470 100644 --- a/sw/source/core/inc/unoidx.hxx +++ b/sw/source/core/inc/unoidx.hxx @@ -213,15 +213,15 @@ private: SwXDocumentIndexMark(SwDoc & rDoc, SwTOXType & rType, SwTOXMark & rMark); -public: - /// descriptor SwXDocumentIndexMark(const TOXTypes eToxType); +public: + static ::com::sun::star::uno::Reference< ::com::sun::star::text::XDocumentIndexMark> CreateXDocumentIndexMark(SwDoc & rDoc, - SwTOXType & rType, SwTOXMark & rMark); + SwTOXType * pType, SwTOXMark * pMark, TOXTypes eType = TOX_INDEX); static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId(); diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx index a7ff947b1c92..7dc282fc5065 100644 --- a/sw/source/core/unocore/unocoll.cxx +++ b/sw/source/core/unocore/unocoll.cxx @@ -627,7 +627,7 @@ uno::Reference< uno::XInterface > SwXServiceProvider::MakeInstance(sal_uInt16 eType = TOX_CONTENT; else if(SW_SERVICE_USER_INDEX_MARK == nObjectType) eType = TOX_USER; - xRet = (cppu::OWeakObject*)new SwXDocumentIndexMark(eType); + xRet = SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, 0, 0, eType); } break; case SW_SERVICE_CONTENT_INDEX : diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index 51dcd9ba39d3..faa62ae26e02 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -482,7 +482,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry const uno::Reference< text::XDocumentIndexMark > xRef = SwXDocumentIndexMark::CreateXDocumentIndexMark( *rPam.GetDoc(), - *const_cast<SwTOXType*>(rMark.GetTOXType()), rMark); + const_cast<SwTOXType*>(rMark.GetTOXType()), &rMark); (*pAny) <<= xRef; } } diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx index 00baf17aad6d..ef76573b6644 100644 --- a/sw/source/core/unocore/unoidx.cxx +++ b/sw/source/core/unocore/unoidx.cxx @@ -1184,7 +1184,7 @@ throw (beans::UnknownPropertyException, lang::WrappedTargetException, SwTOXMark* pMark = aMarks[i]; pxMarks[i] = SwXDocumentIndexMark::CreateXDocumentIndexMark( *m_pImpl->m_pDoc, - *const_cast<SwTOXType*>(pType), *pMark); + const_cast<SwTOXType*>(pType), pMark); } aRet <<= aXMarks; } @@ -1529,6 +1529,7 @@ private: public: + uno::WeakReference<uno::XInterface> m_wThis; SfxItemPropertySet const& m_rPropSet; const TOXTypes m_eTOXType; ::cppu::OInterfaceContainerHelper m_EventListeners; @@ -1619,8 +1620,13 @@ void SwXDocumentIndexMark::Impl::Invalidate() } if (!m_bInReplaceMark) // #i109983# only dispose on delete, not on replace! { - lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis)); - m_EventListeners.disposeAndClear(ev); + uno::Reference<uno::XInterface> const xThis(m_wThis); + // fdo#72695: if UNO object is already dead, don't revive it with event + if (xThis.is()) + { + lang::EventObject const ev(xThis); + m_EventListeners.disposeAndClear(ev); + } } m_pDoc = 0; m_pTOXMark = 0; @@ -1654,18 +1660,30 @@ SwXDocumentIndexMark::~SwXDocumentIndexMark() uno::Reference<text::XDocumentIndexMark> SwXDocumentIndexMark::CreateXDocumentIndexMark( - SwDoc & rDoc, SwTOXType & rType, SwTOXMark & rMark) + SwDoc & rDoc, SwTOXType *const pType, SwTOXMark *const pMark, + TOXTypes const eType) { + assert((pType != 0) == (pMark != 0)); // re-use existing SwXDocumentIndexMark // NB: xmloff depends on this caching to generate ID from the address! // #i105557#: do not iterate over the registered clients: race condition - uno::Reference< text::XDocumentIndexMark > xTOXMark(rMark.GetXTOXMark()); + uno::Reference<text::XDocumentIndexMark> xTOXMark; + if (pMark) + { + xTOXMark = pMark->GetXTOXMark(); + } if (!xTOXMark.is()) { - SwXDocumentIndexMark *const pNew = - new SwXDocumentIndexMark(rDoc, rType, rMark); + SwXDocumentIndexMark *const pNew((pMark) + ? new SwXDocumentIndexMark(rDoc, *pType, *pMark) + : new SwXDocumentIndexMark(eType)); xTOXMark.set(pNew); - rMark.SetXTOXMark(xTOXMark); + if (pMark) + { + pMark->SetXTOXMark(xTOXMark); + } + // need a permanent Reference to initialize m_wThis + pNew->m_pImpl->m_wThis = xTOXMark; } return xTOXMark; } diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index d79d3e3e7307..9eabdcf50699 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -538,7 +538,7 @@ lcl_CreateTOXMarkPortion( const Reference<XTextContent> xContent( SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, - *const_cast<SwTOXType*>(rTOXMark.GetTOXType()), rTOXMark), + const_cast<SwTOXType*>(rTOXMark.GetTOXType()), & rTOXMark), uno::UNO_QUERY); SwXTextPortion* pPortion = 0; |