summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-05-10 14:19:16 +0200
committerAndras Timar <andras.timar@collabora.com>2021-05-12 10:51:52 +0200
commitb1062705a3b97dff81835d39c4c411651b847121 (patch)
tree324b2ab3f0ad3efec214ead50606c4a5dd36f2f0
parentebd6569f7556b0ffb0f10a888416ff10150975a7 (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.odpbin0 -> 11346 bytes
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx50
-rw-r--r--svx/source/svdraw/svdedxv.cxx6
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
new file mode 100644
index 000000000000..f66c9f6081d5
--- /dev/null
+++ b/sd/qa/unit/tiledrendering/data/duplicate-undo.odp
Binary files differ
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();
}