summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-08-17 22:50:01 +0200
committerMichael Stahl <mstahl@redhat.com>2014-08-20 16:40:13 +0200
commit939edde802b4de9abb5c9d23c61abb37916ce357 (patch)
tree350e6dd4fc28d695f37745ff7195cd8b4ec2bc76
parentc71c1b2bb3b0a1767cd062e46e7dd81cc1027fb1 (diff)
fdo#72695: avoid double-free race condition for SwXDocumentIndexMark
Change-Id: I08fef7f1de4cce468a4936e33d3684f847e1aa5b
-rw-r--r--sw/source/core/inc/unoidx.hxx6
-rw-r--r--sw/source/core/unocore/unocoll.cxx2
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx2
-rw-r--r--sw/source/core/unocore/unoidx.cxx34
-rw-r--r--sw/source/core/unocore/unoportenum.cxx2
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;