diff options
author | Szymon Kłos <szymon.klos@collabora.com> | 2023-11-16 17:13:37 +0100 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2023-11-22 15:41:22 +0100 |
commit | 5dcc658d7fc6bd6f8002666e40e1f1bff3dd4c69 (patch) | |
tree | 5caf154afd472161a4f28cafbf6af371207cea9a /sw | |
parent | 55936f6ad8fb73d8b78a843de378758cc31009ad (diff) |
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.klos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/uibase/dochdl/swdtflvr.cxx | 15 | ||||
-rw-r--r-- | sw/source/uibase/inc/swdtflvr.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/inc/uivwimp.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/uiview/uivwimp.cxx | 13 |
4 files changed, 27 insertions, 5 deletions
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 |