From 5dcc658d7fc6bd6f8002666e40e1f1bff3dd4c69 Mon Sep 17 00:00:00 2001 From: Szymon Kłos Date: Thu, 16 Nov 2023 17:13:37 +0100 Subject: lok: disconnect clipboard leftovers in Writer to avoid crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we closed one view which previously copied some larger selection in the Writer and other session after that modified content of that selection we got a crash. It was caused by old clipboard data still beeing used. On copy there is created SwTransferDdeLink which creates "Server" - SvLinkSource which is notified in SwTransferDdeLink::DataChanged when someone is editing previously copied selection. Let's disconnect that server on view close as it is no longer needed. some characteristic trace pieces for crash: libsofficeapp.so!LOKClipboard::setContents(LOKClipboard * this, const com::sun::star::uno::Reference & xTrans, const com::sun::star::uno::Reference & xClipboardOwner) ... libswlo.so!SwTransferable::RemoveDDELinkFormat(SwTransferable * this, vcl::Window & rWin) ... libsfxlo.so!sfx2::SvLinkSource::NotifyDataChanged(sfx2::SvLinkSource * this) ... libswlo.so!SwDataChanged::~SwDataChanged(SwDataChanged * this) Change-Id: I2ebab3db8bc42e20781874802563352ef263fdaa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159563 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159755 Tested-by: Jenkins Reviewed-by: Szymon Kłos --- sw/source/uibase/dochdl/swdtflvr.cxx | 15 ++++++++++----- sw/source/uibase/inc/swdtflvr.hxx | 2 ++ sw/source/uibase/inc/uivwimp.hxx | 2 ++ sw/source/uibase/uiview/uivwimp.cxx | 13 +++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) (limited to 'sw') diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index fc5f9f73a0a5..91eb38e0f45c 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -283,11 +283,7 @@ SwTransferable::~SwTransferable() SolarMutexGuard aSolarGuard; // the DDELink still needs the WrtShell! - if( m_xDdeLink.is() ) - { - static_cast( m_xDdeLink.get() )->Disconnect( true ); - m_xDdeLink.clear(); - } + DisconnectDDE(); m_pWrtShell = nullptr; @@ -393,6 +389,15 @@ void SwTransferable::RemoveDDELinkFormat(vcl::Window& rWin) CopyToClipboard(&rWin); } +void SwTransferable::DisconnectDDE() +{ + if( m_xDdeLink.is() ) + { + static_cast( m_xDdeLink.get() )->Disconnect( true ); + m_xDdeLink.clear(); + } +} + namespace { //Resolves: fdo#40717 surely when we create a clipboard document we should diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx index 86531267af9d..e7e1849a0dc9 100644 --- a/sw/source/uibase/inc/swdtflvr.hxx +++ b/sw/source/uibase/inc/swdtflvr.hxx @@ -185,6 +185,8 @@ public: // remove the DDE-Link format promise void RemoveDDELinkFormat(vcl::Window& rWin); + // disconnect to not receive DataChanged listener notifications + void DisconnectDDE(); // paste - methods and helper methods for the paste static bool IsPaste( const SwWrtShell&, const TransferableDataHelper& ); diff --git a/sw/source/uibase/inc/uivwimp.hxx b/sw/source/uibase/inc/uivwimp.hxx index cbdfb18c7fc9..65a0bf4f23e2 100644 --- a/sw/source/uibase/inc/uivwimp.hxx +++ b/sw/source/uibase/inc/uivwimp.hxx @@ -112,6 +112,8 @@ class SwView_Impl bool m_bSelectObject; bool m_bEditingPositionSet; + void DisconnectTransferableDDE(); + public: /// Redline author that's specific to this view. OUString m_sRedlineAuthor; diff --git a/sw/source/uibase/uiview/uivwimp.cxx b/sw/source/uibase/uiview/uivwimp.cxx index 71f97dbbc9d1..ed0c3c68fcfc 100644 --- a/sw/source/uibase/uiview/uivwimp.cxx +++ b/sw/source/uibase/uiview/uivwimp.cxx @@ -65,6 +65,7 @@ SwView_Impl::~SwView_Impl() m_xDispatchProviderInterceptor->Invalidate(); mxXTextView->Invalidate(); mxXTextView.clear(); + if( mxScanEvtLstnr.is() ) mxScanEvtLstnr->ViewDestroyed(); if( mxClipEvtLstnr.is() ) @@ -72,6 +73,8 @@ SwView_Impl::~SwView_Impl() mxClipEvtLstnr->AddRemoveListener( false ); mxClipEvtLstnr->ViewDestroyed(); } + DisconnectTransferableDDE(); + #if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS m_xConfigItem.reset(); #endif @@ -215,6 +218,16 @@ void SwView_Impl::Invalidate() } } +void SwView_Impl::DisconnectTransferableDDE() +{ + for (const auto& xTransferable: mxTransferables) + { + rtl::Reference pTransferable = xTransferable.get(); + if(pTransferable) + pTransferable->DisconnectDDE(); + } +} + void SwView_Impl::AddTransferable(SwTransferable& rTransferable) { //prevent removing of the non-referenced SwTransferable -- cgit