Kaydet (Commit) bd6f0559 authored tarafından Michael Stahl's avatar Michael Stahl

fdo#72695: avoid double-free race condition for SwXFootnote

Change-Id: Id7832d8e65723ae30ad2b5ce95d145def53998f0
üst 2c057a59
...@@ -67,13 +67,13 @@ protected: ...@@ -67,13 +67,13 @@ protected:
virtual ~SwXFootnote(); virtual ~SwXFootnote();
SwXFootnote(SwDoc & rDoc, SwFmtFtn & rFmt); SwXFootnote(SwDoc & rDoc, SwFmtFtn & rFmt);
SwXFootnote(const bool bEndnote);
public: public:
SwXFootnote(const bool bEndnote);
static css::uno::Reference<css::text::XFootnote> static css::uno::Reference<css::text::XFootnote>
CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt); CreateXFootnote(SwDoc & rDoc, SwFmtFtn * pFootnoteFmt,
bool isEndnote = false);
// XInterface // XInterface
virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
......
...@@ -613,10 +613,10 @@ uno::Reference< uno::XInterface > SwXServiceProvider::MakeInstance(sal_uInt16 ...@@ -613,10 +613,10 @@ uno::Reference< uno::XInterface > SwXServiceProvider::MakeInstance(sal_uInt16
break; break;
case SW_SERVICE_TYPE_FOOTNOTE : case SW_SERVICE_TYPE_FOOTNOTE :
xRet = (cppu::OWeakObject*)new SwXFootnote(false); xRet = SwXFootnote::CreateXFootnote(*pDoc, 0, false);
break; break;
case SW_SERVICE_TYPE_ENDNOTE : case SW_SERVICE_TYPE_ENDNOTE :
xRet = (cppu::OWeakObject*)new SwXFootnote(true); xRet = SwXFootnote::CreateXFootnote(*pDoc, 0, true);
break; break;
case SW_SERVICE_CONTENT_INDEX_MARK : case SW_SERVICE_CONTENT_INDEX_MARK :
case SW_SERVICE_USER_INDEX_MARK : case SW_SERVICE_USER_INDEX_MARK :
...@@ -1836,7 +1836,7 @@ uno::Any SwXFootnotes::getByIndex(sal_Int32 nIndex) ...@@ -1836,7 +1836,7 @@ uno::Any SwXFootnotes::getByIndex(sal_Int32 nIndex)
if(nCount == nIndex) if(nCount == nIndex)
{ {
xRef = SwXFootnote::CreateXFootnote(*GetDoc(), xRef = SwXFootnote::CreateXFootnote(*GetDoc(),
const_cast<SwFmtFtn&>(rFtn)); &const_cast<SwFmtFtn&>(rFtn));
aRet <<= xRef; aRet <<= xRef;
break; break;
} }
...@@ -1865,7 +1865,7 @@ sal_Bool SwXFootnotes::hasElements(void) throw( uno::RuntimeException, std::exce ...@@ -1865,7 +1865,7 @@ sal_Bool SwXFootnotes::hasElements(void) throw( uno::RuntimeException, std::exce
Reference<XFootnote> SwXFootnotes::GetObject( SwDoc& rDoc, const SwFmtFtn& rFmt ) Reference<XFootnote> SwXFootnotes::GetObject( SwDoc& rDoc, const SwFmtFtn& rFmt )
{ {
return SwXFootnote::CreateXFootnote(rDoc, const_cast<SwFmtFtn&>(rFmt)); return SwXFootnote::CreateXFootnote(rDoc, &const_cast<SwFmtFtn&>(rFmt));
} }
OUString SwXReferenceMarks::getImplementationName(void) throw( RuntimeException, std::exception ) OUString SwXReferenceMarks::getImplementationName(void) throw( RuntimeException, std::exception )
......
...@@ -608,7 +608,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry ...@@ -608,7 +608,7 @@ bool getCrsrPropertyValue(const SfxItemPropertySimpleEntry& rEntry
{ {
const uno::Reference< text::XFootnote > xFootnote = const uno::Reference< text::XFootnote > xFootnote =
SwXFootnote::CreateXFootnote(*rPam.GetDoc(), SwXFootnote::CreateXFootnote(*rPam.GetDoc(),
const_cast<SwFmtFtn&>(rFtn)); &const_cast<SwFmtFtn&>(rFtn));
*pAny <<= xFootnote; *pAny <<= xFootnote;
} }
} }
......
...@@ -50,6 +50,7 @@ private: ...@@ -50,6 +50,7 @@ private:
public: public:
SwXFootnote & m_rThis; SwXFootnote & m_rThis;
uno::WeakReference<uno::XInterface> m_wThis;
const bool m_bIsEndnote; const bool m_bIsEndnote;
::cppu::OInterfaceContainerHelper m_EventListeners; ::cppu::OInterfaceContainerHelper m_EventListeners;
bool m_bIsDescriptor; bool m_bIsDescriptor;
...@@ -96,7 +97,12 @@ void SwXFootnote::Impl::Invalidate() ...@@ -96,7 +97,12 @@ void SwXFootnote::Impl::Invalidate()
} }
m_pFmtFtn = 0; m_pFmtFtn = 0;
m_rThis.SetDoc(0); m_rThis.SetDoc(0);
lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(m_rThis)); uno::Reference<uno::XInterface> const xThis(m_wThis);
if (!xThis.is())
{ // fdo#72695: if UNO object is already dead, don't revive it with event
return;
}
lang::EventObject const ev(xThis);
m_EventListeners.disposeAndClear(ev); m_EventListeners.disposeAndClear(ev);
} }
...@@ -127,16 +133,27 @@ SwXFootnote::~SwXFootnote() ...@@ -127,16 +133,27 @@ SwXFootnote::~SwXFootnote()
} }
uno::Reference<text::XFootnote> uno::Reference<text::XFootnote>
SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn & rFootnoteFmt) SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFmtFtn *const pFootnoteFmt,
bool const isEndnote)
{ {
// i#105557: do not iterate over the registered clients: race condition // i#105557: do not iterate over the registered clients: race condition
uno::Reference<text::XFootnote> xNote; uno::Reference<text::XFootnote> xNote;
xNote = rFootnoteFmt.GetXFootnote(); if (pFootnoteFmt)
{
xNote = pFootnoteFmt->GetXFootnote();
}
if (!xNote.is()) if (!xNote.is())
{ {
SwXFootnote *const pNote(new SwXFootnote(rDoc, rFootnoteFmt)); SwXFootnote *const pNote((pFootnoteFmt)
? new SwXFootnote(rDoc, *pFootnoteFmt)
: new SwXFootnote(isEndnote));
xNote.set(pNote); xNote.set(pNote);
rFootnoteFmt.SetXFootnote(xNote); if (pFootnoteFmt)
{
pFootnoteFmt->SetXFootnote(xNote);
}
// need a permanent Reference to initialize m_wThis
pNote->m_pImpl->m_wThis = xNote;
} }
return xNote; return xNote;
} }
......
...@@ -1239,7 +1239,7 @@ CreateParentXText(SwDoc & rDoc, const SwPosition& rPos) ...@@ -1239,7 +1239,7 @@ CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
FindSttNodeByType(SwFootnoteStartNode)) FindSttNodeByType(SwFootnoteStartNode))
{ {
xParentText.set(SwXFootnote::CreateXFootnote(rDoc, xParentText.set(SwXFootnote::CreateXFootnote(rDoc,
const_cast<SwFmtFtn&>(rFtn)), uno::UNO_QUERY); &const_cast<SwFmtFtn&>(rFtn)), uno::UNO_QUERY);
break; break;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment