diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2022-04-20 18:48:30 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2022-04-25 11:13:12 +0200 |
commit | 2a05d1aaf31686babd75d80316639e625ca5ea81 (patch) | |
tree | df3ab3fcfb0493c8cb49cdb2cbda8d710bc0cc9a | |
parent | e555cffdac7b786d166aea5efc750060be1532fa (diff) |
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.stahl@allotropia.de>
(cherry picked from commit 85aa57359befd7a21b3fdf36f2b362f50495f77c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133150
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r-- | sw/source/core/inc/layfrm.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/layout/findfrm.cxx | 21 | ||||
-rw-r--r-- | sw/source/core/layout/pagechg.cxx | 2 |
3 files changed, 24 insertions, 0 deletions
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() |