summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-05-27 10:47:53 +0200
committerAndras Timar <andras.timar@collabora.com>2017-07-06 15:36:22 +0200
commit3d39e0e1456aa00baa68c0a7e38b864a9b9a4d9e (patch)
treeb739cca000f0dda21c5be4b89273d81d6450a065 /sw
parentb75b0bd20a3805af9f6a329c9b365b3b6a276f50 (diff)
tdf#107976 sw: let a view handle multiple transferables
Otherwise only the last transferable gets unregistered on closing the view, which means a use-after-free when trying to paste something copied from a closed document. (cherry picked from commit 336f893c57c3c0281d4899629ad55603837d5d40) Conflicts: sw/qa/extras/uiwriter/uiwriter.cxx sw/source/uibase/inc/uivwimp.hxx Reviewed-on: https://gerrit.libreoffice.org/39499 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Stahl <mstahl@redhat.com> (cherry picked from commit 747be68119f2c85f1cdf6151fac67cd8cb840b76) Change-Id: I65594e07fa4fefe7ae51a12455b755d64700a00d
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx18
-rw-r--r--sw/source/uibase/inc/uivwimp.hxx2
-rw-r--r--sw/source/uibase/uiview/uivwimp.cxx21
3 files changed, 31 insertions, 10 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index b3c0ff237025..90b54c38d19d 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -90,6 +90,7 @@
#include <drawfont.hxx>
#include <txtfrm.hxx>
#include <hyp.hxx>
+#include <swdtflvr.hxx>
#include <editeng/svxenum.hxx>
#include <comphelper/propertysequence.hxx>
#include <sfx2/classificationhelper.hxx>
@@ -230,6 +231,7 @@ public:
void testTdf104814();
void testTdf105417();
void testTdf105625();
+ void testTdf107976();
void testCreateDocxAnnotation();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
@@ -353,6 +355,7 @@ public:
CPPUNIT_TEST(testTdf104814);
CPPUNIT_TEST(testTdf105417);
CPPUNIT_TEST(testTdf105625);
+ CPPUNIT_TEST(testTdf107976);
CPPUNIT_TEST(testCreateDocxAnnotation);
CPPUNIT_TEST_SUITE_END();
@@ -4475,6 +4478,21 @@ void SwUiWriterTest::testCreateDocxAnnotation()
CPPUNIT_ASSERT_EQUAL(aResultText, xField->getPropertyValue("Content").get<OUString>());
}
+void SwUiWriterTest::testTdf107976()
+{
+ // Create a document and create two transferables.
+ SwDoc* pDoc = createDoc();
+ SwWrtShell& rShell = *pDoc->GetDocShell()->GetWrtShell();
+ rtl::Reference<SwTransferable> pTransferable(new SwTransferable(rShell));
+ rtl::Reference<SwTransferable> pTransferable2(new SwTransferable(rShell));
+ // Now close the document.
+ mxComponent->dispose();
+ mxComponent.clear();
+ // This failed: the first shell had a pointer to the deleted shell.
+ CPPUNIT_ASSERT(!pTransferable->GetShell());
+ CPPUNIT_ASSERT(!pTransferable2->GetShell());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/uibase/inc/uivwimp.hxx b/sw/source/uibase/inc/uivwimp.hxx
index 0b84e88d8bdf..f0bc96d7e661 100644
--- a/sw/source/uibase/inc/uivwimp.hxx
+++ b/sw/source/uibase/inc/uivwimp.hxx
@@ -94,7 +94,7 @@ class SwView_Impl
css::uno::Reference< css::lang::XEventListener > xClipEvtLstnr;
css::uno::Reference< css::frame::XDispatchProviderInterceptor > xDisProvInterceptor;
css::uno::Reference< css::view::XSelectionSupplier > mxXTextView; // UNO object
- css::uno::WeakReference< css::lang::XUnoTunnel > xTransferable;
+ std::vector< css::uno::WeakReference< css::lang::XUnoTunnel > > mxTransferables;
// temporary document for printing text of selection / multi selection
// in PDF export.
diff --git a/sw/source/uibase/uiview/uivwimp.cxx b/sw/source/uibase/uiview/uivwimp.cxx
index 60bcbc615579..687c24479d73 100644
--- a/sw/source/uibase/uiview/uivwimp.cxx
+++ b/sw/source/uibase/uiview/uivwimp.cxx
@@ -214,15 +214,18 @@ void SwView_Impl::AddClipboardListener()
void SwView_Impl::Invalidate()
{
GetUNOObject_Impl()->Invalidate();
- Reference< XUnoTunnel > xTunnel(xTransferable.get(), UNO_QUERY);
- if(xTunnel.is())
-
+ for (const auto& xTransferable: mxTransferables)
{
- SwTransferable* pTransferable = reinterpret_cast< SwTransferable * >(
- sal::static_int_cast< sal_IntPtr >(
- xTunnel->getSomething(SwTransferable::getUnoTunnelId())));
- if(pTransferable)
- pTransferable->Invalidate();
+ Reference< XUnoTunnel > xTunnel(xTransferable.get(), UNO_QUERY);
+ if(xTunnel.is())
+
+ {
+ SwTransferable* pTransferable = reinterpret_cast< SwTransferable * >(
+ sal::static_int_cast< sal_IntPtr >(
+ xTunnel->getSomething(SwTransferable::getUnoTunnelId())));
+ if(pTransferable)
+ pTransferable->Invalidate();
+ }
}
}
@@ -231,7 +234,7 @@ void SwView_Impl::AddTransferable(SwTransferable& rTransferable)
//prevent removing of the non-referenced SwTransferable
rTransferable.m_refCount++;
{
- xTransferable = Reference<XUnoTunnel> (&rTransferable);
+ mxTransferables.push_back(uno::WeakReference<lang::XUnoTunnel>(uno::Reference<lang::XUnoTunnel>(&rTransferable)));
}
rTransferable.m_refCount--;
}