diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-05-27 10:47:53 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2017-07-06 15:36:22 +0200 |
commit | 3d39e0e1456aa00baa68c0a7e38b864a9b9a4d9e (patch) | |
tree | b739cca000f0dda21c5be4b89273d81d6450a065 /sw | |
parent | b75b0bd20a3805af9f6a329c9b365b3b6a276f50 (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.cxx | 18 | ||||
-rw-r--r-- | sw/source/uibase/inc/uivwimp.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/uiview/uivwimp.cxx | 21 |
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--; } |