summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-08-08 08:17:17 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-08-08 09:42:34 +0200
commit0d571ff8079f858a5650bf6cbb38296d22cc58e1 (patch)
treeb3d63adf884dae6e398bc3533440cba3b54d8143 /sw
parent9fabf47aba423d74d8cfa2dc2cb28d24df83a8ea (diff)
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. Change-Id: I3ff6a0bbc2cac5f1bc2803a52a632c13053d4daa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155444 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/layout/data/floattable-then-table.docbin0 -> 50688 bytes
-rw-r--r--sw/qa/core/layout/flycnt.cxx14
-rw-r--r--sw/source/core/layout/flycnt.cxx9
3 files changed, 23 insertions, 0 deletions
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
--- /dev/null
+++ b/sw/qa/core/layout/data/floattable-then-table.doc
Binary files differ
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index 6207a956f574..ba688728743b 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 25e3f45c0bfa..113eaafbce9d 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;
}
}