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(-)
New commits: commit 5dcc658d7fc6bd6f8002666e40e1f1bff3dd4c69 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Thu Nov 16 17:13:37 2023 +0100 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Wed Nov 22 15:41:22 2023 +0100 lok: disconnect clipboard leftovers in Writer to avoid crash 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<com::sun::star::datatransfer::XTransferable> & xTrans, const com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboardOwner> & 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 <szymon.k...@collabora.com> 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<SwTransferDdeLink*>( 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<SwTransferDdeLink*>( 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<SwTransferable> pTransferable = xTransferable.get(); + if(pTransferable) + pTransferable->DisconnectDDE(); + } +} + void SwView_Impl::AddTransferable(SwTransferable& rTransferable) { //prevent removing of the non-referenced SwTransferable