summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-05-31 18:07:14 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2023-05-31 20:31:33 +0200
commit66eabacb7c3618d2724470203d7e95c256334520 (patch)
tree98fa5a82c87531ea444c173f9eee104f7f3f1a4c /sw/source
parent192167f635e87e1acee9c31d1153285479dc04ab (diff)
tdf#155611: SwFrame::FindNext sometimes returns a sub-frame of this frame
This resulted in wrong split of the section frame, when the table frame was the last in the section, the split needed to happen after that table (i.e., at the very end of the section), and passing the table frame as pFrameStartAfter gave its last cell's subtable as pSav (i.e., the frame to move after the split). The first frame of the last cell (the one prior to pSav) got lost from the layout, and wasn't destroyed when SwRootFrame was destroyed, and then it crashed referencing destroyed root frame and view shell. Change-Id: I1a539818aa890f65e961f4185ce50916ce7e4e4f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152454 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/layout/sectfrm.cxx16
1 files changed, 15 insertions, 1 deletions
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 1faaae683379..18fac7a397b1 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -523,7 +523,21 @@ void SwSectionFrame::MergeNext( SwSectionFrame* pNxt )
SwSectionFrame* SwSectionFrame::SplitSect( SwFrame* pFrameStartAfter, SwFrame* pFramePutAfter )
{
assert(!pFrameStartAfter || IsAnLower(pFrameStartAfter));
- SwFrame* pSav = pFrameStartAfter ? pFrameStartAfter->FindNext() : ContainsAny();
+ SwFrame* pSav;
+ if (pFrameStartAfter)
+ {
+ pSav = pFrameStartAfter->FindNext();
+ // If pFrameStartAfter is a complex object like table, and it has no next,
+ // its FindNext may return its own last subframe. In this case, assume that
+ // we are at the end.
+ if (pSav && pFrameStartAfter->IsLayoutFrame())
+ if (static_cast<SwLayoutFrame*>(pFrameStartAfter)->IsAnLower(pSav))
+ pSav = nullptr;
+ }
+ else
+ {
+ pSav = ContainsAny();
+ }
if (pSav && !IsAnLower(pSav))
pSav = nullptr; // we are at the very end