diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-05-10 14:19:16 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2021-05-12 10:51:52 +0200 |
commit | b1062705a3b97dff81835d39c4c411651b847121 (patch) | |
tree | 324b2ab3f0ad3efec214ead50606c4a5dd36f2f0 | |
parent | ebd6569f7556b0ffb0f10a888416ff10150975a7 (diff) |
svx: fix crash with active text edit vs slide delete
The problem is that SdrObjEditView::HideSdrPage() may delete
SdrPaintView::mpPageView when it calls SdrGlueEditView::HideSdrPage().
But SdrObjEditView::pTextEditPV is a non-owning reference to that.
GetTextEditBackgroundColor() in svx/ calls
SdrObjEditView::GetTextEditPageView(), so in case
SdrObjEditView::pTextEditPV is not cleared, we would access a deleted
SdrPageView.
(cherry picked from commit 014f33066a99488c52d10d8f5ff470ca6e2242f6)
Change-Id: I948bae8e0e8d557e38aa8f243e9eea522b21a043
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115341
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sd/qa/unit/tiledrendering/data/duplicate-undo.odp | bin | 0 -> 11346 bytes | |||
-rw-r--r-- | sd/qa/unit/tiledrendering/tiledrendering.cxx | 50 | ||||
-rw-r--r-- | svx/source/svdraw/svdedxv.cxx | 6 |
3 files changed, 56 insertions, 0 deletions
diff --git a/sd/qa/unit/tiledrendering/data/duplicate-undo.odp b/sd/qa/unit/tiledrendering/data/duplicate-undo.odp Binary files differnew file mode 100644 index 000000000000..f66c9f6081d5 --- /dev/null +++ b/sd/qa/unit/tiledrendering/data/duplicate-undo.odp diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 161aed640277..109cc29edc87 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -129,6 +129,7 @@ public: void testLanguageAllText(); void testInsertDeletePageInvalidation(); void testSpellOnlineRenderParameter(); + void testSlideDuplicateUndo(); CPPUNIT_TEST_SUITE(SdTiledRenderingTest); CPPUNIT_TEST(testCreateDestroy); @@ -183,6 +184,7 @@ public: CPPUNIT_TEST(testLanguageAllText); CPPUNIT_TEST(testInsertDeletePageInvalidation); CPPUNIT_TEST(testSpellOnlineRenderParameter); + CPPUNIT_TEST(testSlideDuplicateUndo); CPPUNIT_TEST_SUITE_END(); @@ -2561,6 +2563,54 @@ void SdTiledRenderingTest::testSpellOnlineRenderParameter() CPPUNIT_ASSERT_EQUAL(!bSet, pXImpressDocument->GetDoc()->GetOnlineSpell()); } +void SdTiledRenderingTest::testSlideDuplicateUndo() +{ + // Create two views. + SdXImpressDocument* pXImpressDocument = createDoc("duplicate-undo.odp"); + int nView0 = SfxLokHelper::getView(); + SfxLokHelper::createView(); + pXImpressDocument->initializeForTiledRendering({}); + int nView1 = SfxLokHelper::getView(); + SfxLokHelper::setView(nView0); + + // Switch to the 3rd slide on view 0, and start text editing. + { + pXImpressDocument->setPart(2); + sd::ViewShell* pViewShell0 = pXImpressDocument->GetDocShell()->GetViewShell(); + SdrView* pView = pViewShell0->GetView(); + SdPage* pActualPage = pViewShell0->GetActualPage(); + SdrObject* pObject = pActualPage->GetObj(1); + SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject); + pView->MarkObj(pTextObj, pView->GetSdrPageView()); + SfxStringItem aInputString(SID_ATTR_CHAR, "x"); + pViewShell0->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR, + SfxCallMode::SYNCHRON, { &aInputString }); + CPPUNIT_ASSERT(pView->IsTextEdit()); + CPPUNIT_ASSERT(pView->GetTextEditPageView()); + } + + // Duplicate the first slide on view 1 and undo it. + SfxLokHelper::setView(nView1); + comphelper::dispatchCommand(".uno:DuplicatePage", {}); + Scheduler::ProcessEventsToIdle(); + pXImpressDocument->setPart(0, /*bAllowChangeFocus=*/false); + pXImpressDocument->setPart(1, /*bAllowChangeFocus=*/false); + SfxLokHelper::setView(nView0); + pXImpressDocument->setPart(0, /*bAllowChangeFocus=*/false); + pXImpressDocument->setPart(3, /*bAllowChangeFocus=*/false); + SfxLokHelper::setView(nView1); + pXImpressDocument->getUndoManager()->undo(); + // Without the accompanying fix in place, this would have tried to access the outdated page view + // pointer, potentially leading to a crash. + pXImpressDocument->setPart(2, /*bAllowChangeFocus=*/false); + + // Make sure that view 0 now doesn't have an outdated page view pointer. + SfxLokHelper::setView(nView0); + sd::ViewShell* pViewShell0 = pXImpressDocument->GetDocShell()->GetViewShell(); + SdrView* pView0 = pViewShell0->GetView(); + CPPUNIT_ASSERT(!pView0->GetTextEditPageView()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index 43ea7336af56..fefeb43fe7bc 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -210,6 +210,12 @@ void SdrObjEditView::HideSdrPage() { lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), GetFirstOutputDevice()); + if (pTextEditPV == GetSdrPageView()) + { + // HideSdrPage() will clear mpPageView, avoid a dangling pointer. + pTextEditPV = nullptr; + } + SdrGlueEditView::HideSdrPage(); } |