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(); });
