sw/qa/core/layout/data/floattable-then-table.doc |binary sw/qa/core/layout/flycnt.cxx | 14 ++++++++++++++ sw/source/core/layout/flycnt.cxx | 9 +++++++++ 3 files changed, 23 insertions(+)
New commits: commit 845c16b25e2c65fb0ab75a9f2e5165658ed1c067 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Aug 8 08:17:17 2023 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Wed Aug 9 10:00:28 2023 +0200 tdf#156589 sw floattable: fix follow fly moving inside a table on the next page Opening the bugdoc and inserting a page break at the document start resulted in a crash. The direct problem was a nullptr deref in Notify_Background(), because pCnt reported true for IsInTab(), but then FindTabFrame() didn't find anything. The deeper problem was that SwFrame::GetNextFlyLeaf() had a case where it created a follow text frame for the anchor of a floating table, but that follow text frame went inside a table on the start of the next page, not to the start of the page. Fix the problem by continuing to use GetNextLayoutLeaf() (which knows how to traverse the layout tree from a fly frame to its anchor and then to a next page), but once we moved to a body on a next page and we would insert inside an inline table, insert before the table instead. Need to make sure the target is in a body frame, because a next layout leaf in a footer's table is not OK. (cherry picked from commit 0d571ff8079f858a5650bf6cbb38296d22cc58e1) Change-Id: I3ff6a0bbc2cac5f1bc2803a52a632c13053d4daa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155500 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/sw/qa/core/layout/data/floattable-then-table.doc b/sw/qa/core/layout/data/floattable-then-table.doc new file mode 100644 index 000000000000..8c9684e5950a Binary files /dev/null and b/sw/qa/core/layout/data/floattable-then-table.doc differ diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index 00449f38e317..a2b03b34f388 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -996,6 +996,20 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyGrowFromBottom) // frame on page 1 even when it would fit, and this lead to a crash on export later. CPPUNIT_ASSERT(!pFly->GetFollow()); } + +CPPUNIT_TEST_FIXTURE(Test, testSplitFlyIntoTable) +{ + // Given a document with a floating table, then an inline table on the next page: + createSwDoc("floattable-then-table.doc"); + + // When inserting a page break: + // Then make sure the layout doesn't crash: + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + pWrtShell->InsertPageBreak(); + // Without the accompanying fix in place, this test would have crashed, we tried to insert the + // second part of a floating table into a table on the next page, not before that table. + calcLayout(); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx index 0dbe031092dc..d674cebdc134 100644 --- a/sw/source/core/layout/flycnt.cxx +++ b/sw/source/core/layout/flycnt.cxx @@ -1614,6 +1614,15 @@ SwLayoutFrame *SwFrame::GetNextFlyLeaf( MakePageType eMakePage ) // The above conditions are not held, reject. pOldLayLeaf = pLayLeaf; pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); + + if (pLayLeaf && pLayLeaf->IsInDocBody() && !bSameBody && !pLayLeaf->IsInFly() && pLayLeaf->IsInTab()) + { + // We found a next leaf in a next body frame, which is in an inline table. Make + // sure we won't insert the follow anchor inside the table, but before it. + SwTabFrame* pTabFrame = pLayLeaf->FindTabFrame(); + pLayLeaf = pTabFrame->GetUpper(); + } + continue; } }