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

fdo#72695: avoid double-free race condition for SwXMeta/SwXMetaField

Change-Id: Ic5754dc479d7d55ce4e0f2713c5545db75a300c2
üst 37198ff2
...@@ -86,10 +86,10 @@ protected: ...@@ -86,10 +86,10 @@ protected:
xParentText, xParentText,
TextRangeList_t const*const pPortions); TextRangeList_t const*const pPortions);
public:
SwXMeta(SwDoc *const pDoc); SwXMeta(SwDoc *const pDoc);
public:
SAL_WNODEPRECATED_DECLARATIONS_PUSH SAL_WNODEPRECATED_DECLARATIONS_PUSH
static ::com::sun::star::uno::Reference< static ::com::sun::star::uno::Reference<
::com::sun::star::rdf::XMetadatable > ::com::sun::star::rdf::XMetadatable >
...@@ -101,6 +101,9 @@ public: ...@@ -101,6 +101,9 @@ public:
::std::auto_ptr<TextRangeList_t const>(0)); ::std::auto_ptr<TextRangeList_t const>(0));
SAL_WNODEPRECATED_DECLARATIONS_POP SAL_WNODEPRECATED_DECLARATIONS_POP
static css::uno::Reference<css::rdf::XMetadatable>
CreateXMeta(SwDoc & rDoc, bool isField);
/// init params with position of the attribute content (w/out CH_TXTATR) /// init params with position of the attribute content (w/out CH_TXTATR)
bool SetContentRange( bool SetContentRange(
SwTxtNode *& rpNode, sal_Int32 & rStart, sal_Int32 & rEnd) const; SwTxtNode *& rpNode, sal_Int32 & rStart, sal_Int32 & rEnd) const;
...@@ -260,10 +263,13 @@ private: ...@@ -260,10 +263,13 @@ private:
xParentText, xParentText,
TextRangeList_t const*const pPortions); TextRangeList_t const*const pPortions);
public: friend css::uno::Reference<css::rdf::XMetadatable>
SwXMeta::CreateXMeta(SwDoc &, bool);
SwXMetaField(SwDoc *const pDoc); SwXMetaField(SwDoc *const pDoc);
public:
// XServiceInfo // XServiceInfo
virtual OUString SAL_CALL getImplementationName() virtual OUString SAL_CALL getImplementationName()
throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
......
...@@ -821,10 +821,10 @@ uno::Reference< uno::XInterface > SwXServiceProvider::MakeInstance(sal_uInt16 ...@@ -821,10 +821,10 @@ uno::Reference< uno::XInterface > SwXServiceProvider::MakeInstance(sal_uInt16
xRet = (cppu::OWeakObject*) pDoc->getIDocumentChartDataProviderAccess().GetChartDataProvider( true /* create - if not yet available */ ); xRet = (cppu::OWeakObject*) pDoc->getIDocumentChartDataProviderAccess().GetChartDataProvider( true /* create - if not yet available */ );
break; break;
case SW_SERVICE_TYPE_META: case SW_SERVICE_TYPE_META:
xRet = static_cast< ::cppu::OWeakObject* >( new SwXMeta(pDoc) ); xRet = SwXMeta::CreateXMeta(*pDoc, false);
break; break;
case SW_SERVICE_FIELDTYPE_METAFIELD: case SW_SERVICE_FIELDTYPE_METAFIELD:
xRet = static_cast< ::cppu::OWeakObject* >(new SwXMetaField(pDoc)); xRet = SwXMeta::CreateXMeta(*pDoc, true);
break; break;
default: default:
throw uno::RuntimeException(); throw uno::RuntimeException();
......
...@@ -649,6 +649,7 @@ private: ...@@ -649,6 +649,7 @@ private:
::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper
public: public:
uno::WeakReference<uno::XInterface> m_wThis;
::cppu::OInterfaceContainerHelper m_EventListeners; ::cppu::OInterfaceContainerHelper m_EventListeners;
SAL_WNODEPRECATED_DECLARATIONS_PUSH SAL_WNODEPRECATED_DECLARATIONS_PUSH
::std::auto_ptr<const TextRangeList_t> m_pTextPortions; ::std::auto_ptr<const TextRangeList_t> m_pTextPortions;
...@@ -694,14 +695,20 @@ void SwXMeta::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew ) ...@@ -694,14 +695,20 @@ void SwXMeta::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
ClientModify(this, pOld, pNew); ClientModify(this, pOld, pNew);
if (!GetRegisteredIn()) // removed => dispose if (GetRegisteredIn())
{ {
m_bIsDisposed = true; return; // core object still alive
lang::EventObject const ev( }
static_cast< ::cppu::OWeakObject&>(m_Text.GetXMeta()));
m_EventListeners.disposeAndClear(ev); m_bIsDisposed = true;
m_Text.Invalidate(); m_Text.Invalidate();
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);
} }
uno::Reference<text::XText> SwXMeta::GetParentText() const uno::Reference<text::XText> SwXMeta::GetParentText() const
...@@ -725,6 +732,18 @@ SwXMeta::~SwXMeta() ...@@ -725,6 +732,18 @@ SwXMeta::~SwXMeta()
{ {
} }
uno::Reference<rdf::XMetadatable>
SwXMeta::CreateXMeta(SwDoc & rDoc, bool const isField)
{
SwXMeta *const pXMeta((isField)
? new SwXMetaField(& rDoc) : new SwXMeta(& rDoc));
// this is why the constructor is private: need to acquire pXMeta here
uno::Reference<rdf::XMetadatable> const xMeta(pXMeta);
// need a permanent Reference to initialize m_wThis
pXMeta->m_pImpl->m_wThis = xMeta;
return xMeta;
}
SAL_WNODEPRECATED_DECLARATIONS_PUSH SAL_WNODEPRECATED_DECLARATIONS_PUSH
uno::Reference<rdf::XMetadatable> uno::Reference<rdf::XMetadatable>
SwXMeta::CreateXMeta(::sw::Meta & rMeta, SwXMeta::CreateXMeta(::sw::Meta & rMeta,
...@@ -779,6 +798,8 @@ SwXMeta::CreateXMeta(::sw::Meta & rMeta, ...@@ -779,6 +798,8 @@ SwXMeta::CreateXMeta(::sw::Meta & rMeta,
xMeta.set(pXMeta); xMeta.set(pXMeta);
// in order to initialize the weak pointer cache in the core object // in order to initialize the weak pointer cache in the core object
rMeta.SetXMeta(xMeta); rMeta.SetXMeta(xMeta);
// need a permanent Reference to initialize m_wThis
pXMeta->m_pImpl->m_wThis = xMeta;
return xMeta; return xMeta;
} }
SAL_WNODEPRECATED_DECLARATIONS_POP SAL_WNODEPRECATED_DECLARATIONS_POP
......
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