sd/source/ui/func/fuarea.cxx   |    9 +++++----
 sd/source/ui/func/fuline.cxx   |    9 +++++----
 sd/source/ui/func/futransf.cxx |   16 ++++++++++------
 3 files changed, 20 insertions(+), 14 deletions(-)

New commits:
commit 48573e2e40a2c342862f9b72481b6769bd2c3ad0
Author:     Andras Timar <[email protected]>
AuthorDate: Mon Mar 23 08:07:01 2026 +0100
Commit:     Andras Timar <[email protected]>
CommitDate: Mon Mar 23 09:06:19 2026 +0100

    sd: prevent use-after-free in async dialog callbacks
    
    Capture rtl::Reference<FuXxx> in StartExecuteAsync lambdas to prevent
    the FuPoor-derived objects from being destroyed while the async dialog
    is still open. Without this, deleting a page (or other actions that
    replace the current function) while a transform/line/area dialog is
    open causes a SIGSEGV when the callback fires with a dangling this
    pointer.
    
    Also guard setUndo() in FuTransform against an empty mark list, since
    the marked objects may be gone after page deletion.
    
    Backport of 580e4488d558 and 664d746a3f92, adapted for co-26.04
    (mrViewShell/mrDoc references instead of mpViewShell/mpDoc pointers).
    
    Change-Id: Ie8e8a87e86bbc8573310f89c9a4f8c16c80af448
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201689
    Reviewed-by: Miklos Vajna <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202409
    Reviewed-by: Andras Timar <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sd/source/ui/func/fuarea.cxx b/sd/source/ui/func/fuarea.cxx
index 1a34d25e7454..acedfcfca5d5 100644
--- a/sd/source/ui/func/fuarea.cxx
+++ b/sd/source/ui/func/fuarea.cxx
@@ -59,10 +59,11 @@ void FuArea::DoExecute( SfxRequest& rReq )
     VclPtr<AbstractSvxAreaTabDialog> pDlg(
         pFact->CreateSvxAreaTabDialog(mrViewShell.GetFrameWeld(), &aNewAttr, 
&mrDoc, true, bHasSlideBackground));
 
-    pDlg->StartExecuteAsync([pDlg, pView = this->mpView, pViewShell = 
&this->mrViewShell](sal_Int32 nResult){
+    rtl::Reference<FuArea> xThis(this); // prevent premature release during 
async processing
+    pDlg->StartExecuteAsync([pDlg, xThis=std::move(xThis)](sal_Int32 nResult){
         if (nResult == RET_OK)
         {
-            pView->SetAttributes (*(pDlg->GetOutputItemSet ()));
+            xThis->mpView->SetAttributes (*(pDlg->GetOutputItemSet ()));
 
             // attributes changed, update Listboxes in Objectbars
             static const sal_uInt16 SidArray[] = {
@@ -76,11 +77,11 @@ void FuArea::DoExecute( SfxRequest& rReq )
                 SID_ATTR_FILL_USE_SLIDE_BACKGROUND,
                 0 };
 
-            pViewShell->GetViewFrame()->GetBindings().Invalidate( SidArray );
+            xThis->mrViewShell.GetViewFrame()->GetBindings().Invalidate( 
SidArray );
         }
 
         // deferred until the dialog ends
-        pViewShell->Cancel();
+        xThis->mrViewShell.Cancel();
 
         pDlg->disposeOnce();
     });
diff --git a/sd/source/ui/func/fuline.cxx b/sd/source/ui/func/fuline.cxx
index 868fc97163d2..b276a6c4a65e 100644
--- a/sd/source/ui/func/fuline.cxx
+++ b/sd/source/ui/func/fuline.cxx
@@ -68,10 +68,11 @@ void FuLine::DoExecute( SfxRequest& rReq )
     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
     VclPtr<SfxAbstractTabDialog> pDlg( 
pFact->CreateSvxLineTabDialog(mrViewShell.GetFrameWeld(), &aNewAttr, &mrDoc, 
pObj, bHasMarked) );
 
-    pDlg->StartExecuteAsync([pDlg, this](sal_Int32 nResult){
+    rtl::Reference<FuLine> xThis(this); // prevent premature release during 
async processing
+    pDlg->StartExecuteAsync([pDlg, xThis=std::move(xThis)](sal_Int32 nResult){
         if (nResult == RET_OK)
         {
-            mpView->SetAttributes (*(pDlg->GetOutputItemSet ()));
+            xThis->mpView->SetAttributes (*(pDlg->GetOutputItemSet ()));
 
             // some attributes are changed, we have to update the listboxes in 
the objectbars
             static const sal_uInt16 SidArray[] = {
@@ -86,11 +87,11 @@ void FuLine::DoExecute( SfxRequest& rReq )
                 SID_ATTR_LINE_CAP,                  // (SID_SVX_START+1111)
                 0 };
 
-            mrViewShell.GetViewFrame()->GetBindings().Invalidate( SidArray );
+            xThis->mrViewShell.GetViewFrame()->GetBindings().Invalidate( 
SidArray );
         }
 
         // deferred until the dialog ends
-        mrViewShell.Cancel();
+        xThis->mrViewShell.Cancel();
 
         pDlg->disposeOnce();
     });
diff --git a/sd/source/ui/func/futransf.cxx b/sd/source/ui/func/futransf.cxx
index 0cacbe32c0b2..eabd1f936393 100644
--- a/sd/source/ui/func/futransf.cxx
+++ b/sd/source/ui/func/futransf.cxx
@@ -113,17 +113,21 @@ void FuTransform::DoExecute( SfxRequest& rReq )
     auto xRequest = std::make_shared<SfxRequest>(rReq);
     rReq.Ignore(); // the 'old' request is not relevant any more
 
-    pDlg->StartExecuteAsync([bWelded, pDlg, xRequest=std::move(xRequest), 
this](sal_Int32 nResult){
+    rtl::Reference<FuTransform> xThis(this); // prevent premature release 
during async processing
+    pDlg->StartExecuteAsync([bWelded, pDlg, xRequest=std::move(xRequest), 
xThis=std::move(xThis)](sal_Int32 nResult){
         if (nResult == RET_OK)
         {
-            xRequest->Done(*(pDlg->GetOutputItemSet()));
-            // Page margin is already calculated at this point.
-            setUndo(mpView, xRequest->GetArgs(), false);
+            if (xThis->mpView->GetMarkedObjectList().GetMarkCount() != 0)
+            {
+                xRequest->Done(*(pDlg->GetOutputItemSet()));
+                // Page margin is already calculated at this point.
+                setUndo(xThis->mpView, xRequest->GetArgs(), false);
+            }
         }
 
         // deferred until the dialog ends
-        mrViewShell.Invalidate(SID_RULER_OBJECT);
-        mrViewShell.Cancel();
+        xThis->mrViewShell.Invalidate(SID_RULER_OBJECT);
+        xThis->mrViewShell.Cancel();
         if (bWelded)
             pDlg->disposeOnce();
     });

Reply via email to