editeng/source/editeng/editview.cxx |    2 ++
 editeng/source/outliner/outlvw.cxx  |    2 ++
 include/editeng/editview.hxx        |    1 +
 include/editeng/outliner.hxx        |    1 +
 svx/source/svdraw/svdedxv.cxx       |   16 +++++++++++-----
 5 files changed, 17 insertions(+), 5 deletions(-)

New commits:
commit d5efff4057f61c583246bce559fdd0a221ae7d53
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Mon Jul 29 12:35:50 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Aug 6 08:22:19 2024 +0200

    cool#9352 unassign cursor on SdrObjEditView to avoid crash
    
    On stress test with shapes and typing a segfault ocurred due to
    using a freed vcl::Cursor.
    
    On SdrObjEditView::SdrEndTextEdit, delete pOLV can delete the cursor
    remembered in pTECursorBuffer. But if it is set to the window before
    the deletion, it will be safely removed from the window.
    
    And on SdrObjEditView::ModelHasChanged a re-anchoring sets a cursor
    on the window that sholdn't be there and other SdrObjEditView can
    see, remeber, and use it even after this one died and freed the
    cursor.
    
    Change-Id: I3cfef3b68b77e6e6b49c3b68297a6a20e1f9394a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171184
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    (cherry picked from commit 3b5738ab1a646d089fa7cc59ffaeda7d011c1e07)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171287

diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index f10bffc6b1fc..debc22469a3d 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -554,6 +554,8 @@ void EditView::HideCursor(bool bDeactivate)
     }
 }
 
+bool EditView::IsCursorVisible() const { return 
pImpEditView->GetCursor()->IsVisible(); }
+
 Pair EditView::Scroll( tools::Long ndX, tools::Long ndY, ScrollRangeCheck 
nRangeCheck )
 {
     return pImpEditView->Scroll( ndX, ndY, nRangeCheck );
diff --git a/editeng/source/outliner/outlvw.cxx 
b/editeng/source/outliner/outlvw.cxx
index 356d8076481c..6115ea129a38 100644
--- a/editeng/source/outliner/outlvw.cxx
+++ b/editeng/source/outliner/outlvw.cxx
@@ -1225,6 +1225,8 @@ void OutlinerView::HideCursor(bool bDeactivate)
     pEditView->HideCursor(bDeactivate);
 }
 
+bool OutlinerView::IsCursorVisible() const { return 
pEditView->IsCursorVisible(); }
+
 void OutlinerView::SetWindow( vcl::Window* pWin )
 {
     pEditView->SetWindow( pWin );
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 7b363b260fed..ffc917460383 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -207,6 +207,7 @@ public:
     tools::Rectangle       GetEditCursor() const;
     void            ShowCursor( bool bGotoCursor = true, bool bForceVisCursor 
= true, bool bActivate = false );
     void            HideCursor( bool bDeactivate = false );
+    bool IsCursorVisible() const;
 
     void            SetSelectionMode( EESelectionMode eMode );
 
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index ad59f8e9751e..aad1b9456fa1 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -220,6 +220,7 @@ public:
 
     void        ShowCursor( bool bGotoCursor = true, bool bActivate = false );
     void        HideCursor( bool bDeactivate = false );
+    bool IsCursorVisible() const;
 
     Outliner*   GetOutliner() const { return pOwner; }
 
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 42be2aff97fb..43ed9b470bf1 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -363,8 +363,8 @@ void SdrObjEditView::ModelHasChanged()
             for (size_t nOV = 0; nOV < nOutlViewCnt; nOV++)
             {
                 OutlinerView* pOLV = mpTextEditOutliner->GetView(nOV);
+                vcl::Window* pWin = pOLV->GetWindow();
                 { // invalidate old OutlinerView area
-                    vcl::Window* pWin = pOLV->GetWindow();
                     tools::Rectangle aTmpRect(aOldArea);
                     sal_uInt16 nPixSiz = pOLV->GetInvalidateMore() + 1;
                     Size aMore(pWin->PixelToLogic(Size(nPixSiz, nPixSiz)));
@@ -379,9 +379,15 @@ void SdrObjEditView::ModelHasChanged()
                 if (bColorChg)
                     pOLV->SetBackgroundColor(aNewColor);
 
+                bool bWasCoursorVisible = pOLV->IsCursorVisible();
+                vcl::Cursor* pOldCursor = pWin->GetCursor();
                 pOLV->SetOutputArea(
                     aTextEditArea); // because otherwise, we're not 
re-anchoring correctly
                 ImpInvalidateOutlinerView(*pOLV);
+                // Undo SetOutputArea setting and showing the cursor
+                if (!bWasCoursorVisible)
+                    pOLV->HideCursor();
+                pWin->SetCursor(pOldCursor);
             }
             mpTextEditOutlinerView->ShowCursor();
         }
@@ -1768,6 +1774,10 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool 
bDontDeleteReally)
             // to call AdjustMarkHdl() always.
             AdjustMarkHdl();
         }
+        if (pTEWin != nullptr)
+        {
+            pTEWin->SetCursor(pTECursorBuffer);
+        }
         // delete all OutlinerViews
         for (size_t i = pTEOutliner->GetViewCount(); i > 0;)
         {
@@ -1799,10 +1809,6 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool 
bDontDeleteReally)
             delete pTEOutliner;
         else
             pTEOutliner->Clear();
-        if (pTEWin != nullptr)
-        {
-            pTEWin->SetCursor(pTECursorBuffer);
-        }
         maHdlList.SetMoveOutside(false);
         if (eRet != SdrEndTextEditKind::Unchanged)
         {

Reply via email to