diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-05-31 18:07:14 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2023-05-31 20:31:33 +0200 |
commit | 66eabacb7c3618d2724470203d7e95c256334520 (patch) | |
tree | 98fa5a82c87531ea444c173f9eee104f7f3f1a4c /sw/source | |
parent | 192167f635e87e1acee9c31d1153285479dc04ab (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.cxx | 16 |
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 |