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(+)

New commits:
commit af0955d600cd3d54d26a87b9ff30e3c402a226dd
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Apr 20 18:48:30 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Apr 21 20:48:52 2022 +0200

    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 <michael.st...@allotropia.de>
    (cherry picked from commit 85aa57359befd7a21b3fdf36f2b362f50495f77c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133150
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx
index 3f73602e6bfa..b0f981477499 100644
--- a/sw/source/core/inc/layfrm.hxx
+++ b/sw/source/core/inc/layfrm.hxx
@@ -100,6 +100,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 d100e24526a4..3d92f2a9ce0e 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -165,6 +165,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<SwLayoutFrame 
const*>(pFrame));
+        if (pLay->ContainsDeleteForbiddenLayFrame())
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 const SwFrame* SwFrame::GetLower() const
 {
     return IsLayoutFrame() ? static_cast<const SwLayoutFrame*>(this)->Lower() 
: nullptr;
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index fe84f956a35c..e7a458737d30 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -1024,6 +1024,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()

Reply via email to