[Libreoffice-commits] core.git: 4 commits - accessibility/source include/svx sd/source svx/source

Michael Stahl mstahl at redhat.com
Fri Jun 30 15:15:46 UTC 2017


 accessibility/source/extended/accessibletabbarbase.cxx |    2 
 include/svx/svdedtv.hxx                                |    3 -
 sd/source/filter/xml/sdxmlwrp.cxx                      |    3 -
 sd/source/ui/docshell/docshell.cxx                     |   10 ++++
 svx/source/svdraw/svdedtv.cxx                          |   39 ++++++++++-------
 5 files changed, 38 insertions(+), 19 deletions(-)

New commits:
commit 3d59018b1ed816b4399cad4c2c4818cf25d4f4a1
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Jun 30 16:13:06 2017 +0200

    tdf#108833 sd: don't unconditionally enable Undo after import
    
    Change-Id: Id637e649ccf3782658832d909b3a7150a0606229

diff --git a/sd/source/filter/xml/sdxmlwrp.cxx b/sd/source/filter/xml/sdxmlwrp.cxx
index 38ef1d3f6341..4eed0b02cc38 100644
--- a/sd/source/filter/xml/sdxmlwrp.cxx
+++ b/sd/source/filter/xml/sdxmlwrp.cxx
@@ -453,6 +453,7 @@ bool SdXMLFilter::Import( ErrCode& nError )
             comphelper::getProcessComponentContext();
 
     SdDrawDocument* pDoc = mrDocShell.GetDoc();
+    bool const bWasUndo(pDoc->IsUndoEnabled());
     pDoc->EnableUndo(false);
     pDoc->NewOrLoadCompleted( NEW_DOC );
     pDoc->CreateFirstPages();
@@ -769,7 +770,7 @@ bool SdXMLFilter::Import( ErrCode& nError )
 
     fixupOutlinePlaceholderNumberingDepths(pDoc);
 
-    pDoc->EnableUndo(true);
+    pDoc->EnableUndo(bWasUndo);
     mrDocShell.ClearUndoBuffer();
     return nRet == ERRCODE_NONE;
 }
commit b2b085441dc79fb78607dbf1969c12a40db58214
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Jun 30 15:23:15 2017 +0200

    accessibility: fix horrible memory leak in AccessibleTabBarBase
    
    Reproducing tdf#108833 failed because applying the Master Page takes
    > 2 hours; the time is spent calling vcl::Window listeners, of which
    there were some 39525 after a couple minutes, almost all of which
    AccessibleTabBarBase.
    
    AccessibleTabBarBase::WindowEventListener() has an inverted condition
    that suppresses the event that is generated from TabBar::Clear()
    and thus when DrawViewShell::ResetActualPage() calls Clear() no
    AccessibleTabBarPage is removed but then the InsertPage() calls create
    duplicate objects that again register as listeners.
    
    The condition is obviously inverted given the CVS commit message:
    
    1.2.88.1
    log
    @#135353# do not pass VCLEVENT_TABBAR_PAGEREMOVED (all) to objects other than AccessibleTabBarPageList
    @
    text
    a69 8
    
            if( ( pWinEvent->GetId() == VCLEVENT_TABBAR_PAGEREMOVED ) &&
                ( (sal_uInt16)(sal_IntPtr) pWinEvent->GetData() == TAB_PAGE_NOTFOUND ) &&
                ( dynamic_cast< AccessibleTabBarPageList *> (this) != NULL ) )
            {
                return 0;
            }
    
    Change-Id: I2a3b86bbd0f0251a966f41b316a3b313517df24f

diff --git a/accessibility/source/extended/accessibletabbarbase.cxx b/accessibility/source/extended/accessibletabbarbase.cxx
index e1cec85dee48..af42864d3149 100644
--- a/accessibility/source/extended/accessibletabbarbase.cxx
+++ b/accessibility/source/extended/accessibletabbarbase.cxx
@@ -46,7 +46,7 @@ IMPL_LINK( AccessibleTabBarBase, WindowEventListener, VclWindowEvent&, rEvent, v
 
     if( ( rEvent.GetId() == VclEventId::TabbarPageRemoved ) &&
         ( (sal_uInt16)reinterpret_cast<sal_IntPtr>(rEvent.GetData()) == TabBar::PAGE_NOT_FOUND ) &&
-        ( dynamic_cast< AccessibleTabBarPageList *> (this) != nullptr ) )
+        (dynamic_cast<AccessibleTabBarPageList *>(this) == nullptr))
     {
         return;
     }
commit a54ba50db2c341f0f0e47d77dbe64a6e588bc911
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Jun 30 12:43:21 2017 +0200

    tdf#108863 svx: fix use-after-free in SdrEditView::DeleteMarkedObj()
    
    The sdr::ViewSelection has multiple vectors with pointers to the same
    SdrObjects, and those are only cleared in
    sdr::ViewSelection::SetEdgesOfMarkedNodesDirty(), so deleting SdrObjects
    that are marked must be delayed until after that is called.
    
    Change-Id: I7ab18cb2116164a71dce29bf10eca974061ab424

diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx
index 81c680f1c085..039f56cae89b 100644
--- a/include/svx/svdedtv.hxx
+++ b/include/svx/svdedtv.hxx
@@ -154,7 +154,8 @@ protected:
 
     // Removes all objects of the MarkList from their ObjLists including Undo.
     // The entries in rMark remain.
-    void DeleteMarkedList(const SdrMarkList& rMark); // DeleteMarked -> DeleteMarkedList
+    // @return a list of objects that must be deleted after the outermost EndUndo
+    std::vector<SdrObject *> DeleteMarkedList(SdrMarkList const& rMark); // DeleteMarked -> DeleteMarkedList
 
     // Check possibilities of all marked objects
     virtual void CheckPossibilities();
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index 0382ffc77659..f3d5a046de14 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -678,8 +678,9 @@ void SdrEditView::ForceMarkedObjToAnotherPage()
     }
 }
 
-void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
+std::vector<SdrObject*> SdrEditView::DeleteMarkedList(SdrMarkList const& rMark)
 {
+    std::vector<SdrObject*> ret;
     if (rMark.GetMarkCount()!=0)
     {
         rMark.ForceSort();
@@ -733,10 +734,8 @@ void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
 
                 if( !bUndo )
                 {
-                    if( bIs3D )
-                        aRemoved3DObjects.push_back( pObj ); // may be needed later
-                    else
-                        SdrObject::Free(pObj);
+                    // tdf#108863 don't delete objects before EndUndo()
+                    ret.push_back(pObj);
                 }
             }
 
@@ -746,21 +745,22 @@ void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
                 delete aUpdaters.back();
                 aUpdaters.pop_back();
             }
-
-            if( !bUndo )
-            {
-                // now delete removed scene objects
-                while(!aRemoved3DObjects.empty())
-                {
-                    SdrObject::Free( aRemoved3DObjects.back() );
-                    aRemoved3DObjects.pop_back();
-                }
-            }
         }
 
         if( bUndo )
             EndUndo();
     }
+    return ret;
+}
+
+static void lcl_LazyDelete(std::vector<SdrObject*> & rLazyDelete)
+{
+    // now delete removed scene objects
+    while (!rLazyDelete.empty())
+    {
+        SdrObject::Free( rLazyDelete.back() );
+        rLazyDelete.pop_back();
+    }
 }
 
 void SdrEditView::DeleteMarkedObj()
@@ -775,6 +775,7 @@ void SdrEditView::DeleteMarkedObj()
     BrkAction();
     BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::Delete);
 
+    std::vector<SdrObject*> lazyDeleteObjects;
     // remove as long as something is selected. This allows to schedule objects for
     // removal for a next run as needed
     while(GetMarkedObjectCount())
@@ -835,7 +836,11 @@ void SdrEditView::DeleteMarkedObj()
 
         // original stuff: remove selected objects. Handle clear will
         // do something only once
-        DeleteMarkedList(GetMarkedObjectList());
+        auto temp(DeleteMarkedList(GetMarkedObjectList()));
+        for (auto p : temp)
+        {
+            lazyDeleteObjects.push_back(p);
+        }
         GetMarkedObjectListWriteAccess().Clear();
         maHdlList.Clear();
 
@@ -865,6 +870,8 @@ void SdrEditView::DeleteMarkedObj()
     // end undo and change messaging moved at the end
     EndUndo();
     MarkListHasChanged();
+
+    lcl_LazyDelete(lazyDeleteObjects);
 }
 
 void SdrEditView::CopyMarkedObj()
commit 495284716f49072e432b8425944cc67dfe0df0e0
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Jun 30 12:39:26 2017 +0200

    tdf#108863 sd: disable Undo earlier if no Undo Steps
    
    If 0 Undo Steps, the Undo is disabled by a timer somewhere calling
    SfxShell::SetUndoManager().  This seems a bit risky, so disable it
    already when the sd::UndoManager is created.
    
    Change-Id: I9caf14fe32251d1f92cb5fa0683838316275eab3

diff --git a/sd/source/ui/docshell/docshell.cxx b/sd/source/ui/docshell/docshell.cxx
index fa35e3a9808b..1ae312469225 100644
--- a/sd/source/ui/docshell/docshell.cxx
+++ b/sd/source/ui/docshell/docshell.cxx
@@ -18,6 +18,11 @@
  */
 
 #include "DrawDocShell.hxx"
+
+#include <officecfg/Office/Common.hxx>
+
+#include <unotools/configmgr.hxx>
+
 #include <vcl/svapp.hxx>
 
 #include <sfx2/docfac.hxx>
@@ -108,6 +113,11 @@ void DrawDocShell::Construct( bool bClipboard )
     SetBaseModel( new SdXImpressDocument( this, bClipboard ) );
     SetPool( &mpDoc->GetItemPool() );
     mpUndoManager = new sd::UndoManager;
+    if (!utl::ConfigManager::IsAvoidConfig()
+        && officecfg::Office::Common::Undo::Steps::get() < 1)
+    {
+        mpUndoManager->EnableUndo(false); // tdf#108863 disable if 0 steps
+    }
     mpDoc->SetSdrUndoManager( mpUndoManager );
     mpDoc->SetSdrUndoFactory( new sd::UndoFactory );
     UpdateTablePointers();


More information about the Libreoffice-commits mailing list