From ea6a13c6a0ced9c4669ceae08cbd539a62e696e2 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 20 Apr 2022 18:48:30 +0200 Subject: sw: layout: fix crash when deleting page with section being formatted This crashes only when calling storeToURL() with writer_pdf_Export? There is a text frame 112, followed by section frame 126, which contains table frame 127. The section frame 126 is being formatted, which in SwFrame::PrepareMake() formats its prev, text frame 112. This does MoveBwd() and in SwContentFrame::MakeAll() formats its next, tab frame 127. This also does MoveBwd() and then there is this really odd condition in SwTabFrame::Paste() where it calls SwFrame::CheckPageDescs() if it *doesn't* have a RES_PAGEDESC item and the page has a non-default page style - this condition remains inexplicable since initial CVS import. Then CheckPageDesc() sees the (next) page is empty and deletes it. So check in sw::IsPageFrameEmpty() that there aren't any sections with IsDeleteForbidden() set. (regression from commit b9ef71476fd70bc13f50ebe80390e0730d1b7afb) Change-Id: I3c64fe40fabffc255c4146a35c678ce6a1cc09c9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133222 Tested-by: Jenkins Reviewed-by: Michael Stahl (cherry picked from commit 85aa57359befd7a21b3fdf36f2b362f50495f77c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133151 Reviewed-by: Xisco Fauli (cherry picked from commit 116b246e42a1c807e4e693bd020231a22f05abcd) --- sw/source/core/inc/layfrm.hxx | 1 + sw/source/core/layout/findfrm.cxx | 21 +++++++++++++++++++++ sw/source/core/layout/pagechg.cxx | 2 ++ 3 files changed, 24 insertions(+) diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx index f39c9ae513e9..589133216ea6 100644 --- a/sw/source/core/inc/layfrm.hxx +++ b/sw/source/core/inc/layfrm.hxx @@ -99,6 +99,7 @@ public: SwPrintData const*const pPrintData = nullptr ) const override; const SwFrame *Lower() const { return m_pLower; } SwFrame *Lower() { return m_pLower; } + bool ContainsDeleteForbiddenLayFrame() const; const SwContentFrame *ContainsContent() const; inline SwContentFrame *ContainsContent(); const SwCellFrame *FirstCell() const; diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx index 786c7627d7c9..522dde378dcc 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -161,6 +161,27 @@ const SwFrame *SwLayoutFrame::ContainsAny( const bool _bInvestigateFootnoteForSe return nullptr; } +bool SwLayoutFrame::ContainsDeleteForbiddenLayFrame() const +{ + if (IsDeleteForbidden()) + { + return true; + } + for (SwFrame const* pFrame = Lower(); pFrame; pFrame = pFrame->GetNext()) + { + if (!pFrame->IsLayoutFrame()) + { + continue; + } + SwLayoutFrame const*const pLay(static_cast(pFrame)); + if (pLay->ContainsDeleteForbiddenLayFrame()) + { + return true; + } + } + return false; +} + const SwFrame* SwFrame::GetLower() const { return IsLayoutFrame() ? static_cast(this)->Lower() : nullptr; diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index 118dc4c04212..cff4e15f4dd5 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -1027,6 +1027,8 @@ bool IsPageFrameEmpty(SwPageFrame const& rPage) rPage.FindFootnoteCont() || (nullptr != (pBody = rPage.FindBodyCont()) && ( pBody->ContainsContent() || + // check for section frames that are being formatted on the stack + rPage.ContainsDeleteForbiddenLayFrame() || // #i47580# // Do not delete page if there's an empty tabframe // left. I think it might be correct to use ContainsAny() -- cgit