summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2023-11-16 17:13:37 +0100
committerSzymon Kłos <szymon.klos@collabora.com>2023-11-22 15:41:22 +0100
commit5dcc658d7fc6bd6f8002666e40e1f1bff3dd4c69 (patch)
tree5caf154afd472161a4f28cafbf6af371207cea9a /sw
parent55936f6ad8fb73d8b78a843de378758cc31009ad (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.cxx15
-rw-r--r--sw/source/uibase/inc/swdtflvr.hxx2
-rw-r--r--sw/source/uibase/inc/uivwimp.hxx2
-rw-r--r--sw/source/uibase/uiview/uivwimp.cxx13
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