include/svx/svdedxv.hxx            |    2 ++
 svx/source/svdraw/svdedtv1.cxx     |    8 +++++++-
 svx/source/svdraw/svdedxv.cxx      |   10 ++++++++++
 sw/source/core/frmedt/feshview.cxx |    5 +++++
 sw/source/uibase/uiview/view.cxx   |    5 +++++
 5 files changed, 29 insertions(+), 1 deletion(-)

New commits:
commit 2bf269745bed9fefe32122fc432e239949bdf605
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Sep 14 13:46:53 2021 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Sep 14 15:34:55 2021 +0200

    sw: fix undo manager de-registration from editeng on shutdown
    
    editeng/ asserts in the ImpEditEngine dtor that the undo manager it owns
    is indeed an EditUndoManager, and not a subclass. This means that if a
    subclass is set as the undo manager of editeng, then SetUndoManager()
    should be called in pairs: once to set it and once to unset it. The
    unset should happen before destroying the EditEngine.
    
    This normally works because SwView either has an active text edit and
    then its dtor calls SdrEndTextEdit() or it doesn't have an active text
    edit.
    
    The broken case was when the text edit was already ended, but the draw
    view still had a text edit outliner, which has an EditEngine, which
    knows the sw undo manager. The product build deleted the sw undo manager
    when deleting the EditEngine, and then later when the SwExtTextInput
    dtor wanted to access the sw undo manager, it crashes due to
    use-after-free.
    
    Fix the problem by explicitly disposing the undo manager of the draw
    view in the dtor of SwView.
    
    Also fix a couple of more places where an SdrObject* is returned and we
    didn't check if the result is a nullptr.
    
    Caught by the loolstress tool in online.git:
    
    cp test/data/hello-world.odt /tmp/test.odt
    ./loolstress ws://localhost:9980 /tmp/test.odt 
test/traces/writer-hello-shape.txt /tmp/test.odt 
test/traces/writer-hello-shape.txt /tmp/test.odt 
test/traces/writer-hello-shape.txt /tmp/test.odt 
test/traces/writer-mash-text-table.txt /tmp/test.odt 
test/traces/writer-mash-text-table.txt
    
    Change-Id: Ib838b2adf900b4f3bec63d2d62d432327bc0c6c4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122086
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index 1b6e6c6b4501..7f25e3cfc459 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -293,6 +293,8 @@ public:
     /** helper function for selections with multiple SdrText for one 
SdrTextObj (f.e. tables ) */
     static void ApplyFormatPaintBrushToText( SfxItemSet const & rFormatSet, 
SdrTextObj& rTextObj, SdrText* pText, bool bNoCharacterFormats, bool 
bNoParagraphFormats );
 
+    void DisposeUndoManager();
+
 protected:
     virtual void OnBeginPasteOrDrop( PasteOrDropInfos* pInfo );
     virtual void OnEndPasteOrDrop( PasteOrDropInfos* pInfo );
diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
index bdb05d6cce34..307f673da391 100644
--- a/svx/source/svdraw/svdedtv1.cxx
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -899,7 +899,13 @@ void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, 
bool bOnlyHardAttr) con
     for(size_t a = 0; a < nMarkCount; ++a)
     {
         // #80277# merging was done wrong in the prev version
-        const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet();
+        SdrObject *pObj = GetMarkedObjectByIndex(a);
+        if (!pObj)
+        {
+            continue;
+        }
+
+        const SfxItemSet& rSet = pObj->GetMergedItemSet();
         SfxWhichIter aIter(rSet);
         sal_uInt16 nWhich(aIter.FirstWhich());
 
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 4769752ebeef..2d0b338b1cd8 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -2733,6 +2733,16 @@ void 
SdrObjEditView::ApplyFormatPaintBrushToText(SfxItemSet const& rFormatSet, S
     rTextObj.NbcSetOutlinerParaObjectForText(std::move(pTemp), pText);
 }
 
+void SdrObjEditView::DisposeUndoManager()
+{
+    if (pTextEditOutliner)
+    {
+        pTextEditOutliner->SetUndoManager(nullptr);
+    }
+
+    mpOldTextEditUndoManager = nullptr;
+}
+
 void SdrObjEditView::ApplyFormatPaintBrush(SfxItemSet& rFormatSet, bool 
bNoCharacterFormats,
                                            bool bNoParagraphFormats)
 {
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 4939e856e888..2041bc4e7451 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2690,6 +2690,11 @@ FlyProtectFlags SwFEShell::IsSelObjProtected( 
FlyProtectFlags eType ) const
         for( size_t i = rMrkList.GetMarkCount(); i; )
         {
             SdrObject *pObj = rMrkList.GetMark( --i )->GetMarkedSdrObj();
+            if (!pObj)
+            {
+                continue;
+            }
+
             if( !bParent )
             {
                 nChk |= ( pObj->IsMoveProtect() ? FlyProtectFlags::Pos : 
FlyProtectFlags::NONE ) |
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 7ac084f44aa4..30b4d76aa4b5 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -107,6 +107,7 @@
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <svtools/embedhlp.hxx>
 #include <tools/UnitConversion.hxx>
+#include <svx/svdoutl.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -1095,6 +1096,10 @@ SwView::~SwView()
     SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr;
     if( pSdrView && pSdrView->IsTextEdit() )
         pSdrView->SdrEndTextEdit( true );
+    else if (pSdrView)
+    {
+        pSdrView->DisposeUndoManager();
+    }
 
     SetWindow( nullptr );
 

Reply via email to