[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-4+backports' - sw/qa sw/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Wed May 19 08:53:19 UTC 2021
sw/qa/extras/layout/data/fdo43573-2-min.docx |binary
sw/qa/extras/layout/layout.cxx | 16 ++++++++++++++++
sw/source/core/layout/fly.cxx | 14 +++++++++-----
3 files changed, 25 insertions(+), 5 deletions(-)
New commits:
commit 2ee6b87e35d760d9a3c4558be692961352872ea1
Author: Michael Stahl <michael.stahl at allotropia.de>
AuthorDate: Wed May 5 12:21:42 2021 +0200
Commit: Michael Stahl <michael.stahl at allotropia.de>
CommitDate: Wed May 19 10:52:46 2021 +0200
tdf#142080 sw: layout: fix infinite loop in CalcContent()
On page 9, SwSectionFrame::Format() calls CalcContent() and that formats
all its content frames, then on SwTextFrame 91
SwObjectFormatter::FormatObj() fails becuase it moved forward.
With commit c799de145f7e289f31e3669646e5bd12814e6c5e this now sets the
o_rbPageHasFlysAnchoredBelowThis to true, which prevents a call to
SwLayouter::InsertMovedFwdFrame(), and the flys anchored in next frames
aren't moved off the page at this time.
Then the loop starts over at the beginning of the SwSectionFrame, and
frame 91 will be formatted again because the loop tries to format the
first frame on the next page to see if it will move back; now the
MoveBwd() isn't prevented any more so the result is the same failure
in SwObjectFormatter::FormatObj().
Fix this by ignoring the bRestartLayoutProcess in case the current frame
was originally on the next page and didn't move back (or, as is the case
here, moved back and then forward again); it should just be formatted
again on the next page. Once that happens, it will eventually be
entered into SwLayouter::InsertMovedFwdFrame() too.
This happens to fix another problem with this bugdoc too: the first
column of the section on page 9 is empty. This also happens in LO 6.4
but not LO 6.1.
An alternative would be to move the flys anchored below off the page as
is done in SwLayAction::FormatContent() now but sections can be in flys
or footnotes or headers so perhaps it should be done only at the
top-level.
(regression from c799de145f7e289f31e3669646e5bd12814e6c5e)
Change-Id: I0965aebb4e3cec687f4e70f8d5e3aa8a55da3393
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115144
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at allotropia.de>
(cherry picked from commit ed12269c42f75f553bb8a8770923406f7824e473)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115087
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 858cd97b2682510cbf6abddf68e63a502a4b3202)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115767
Tested-by: Michael Stahl <michael.stahl at allotropia.de>
diff --git a/sw/qa/extras/layout/data/fdo43573-2-min.docx b/sw/qa/extras/layout/data/fdo43573-2-min.docx
new file mode 100644
index 000000000000..429b7948ed02
Binary files /dev/null and b/sw/qa/extras/layout/data/fdo43573-2-min.docx differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 955fa2ff9bc6..b54f2bcf03c0 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -1171,6 +1171,22 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf116486)
CPPUNIT_ASSERT_EQUAL(OUString("4006"), aTop);
}
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, TestTdf142080)
+{
+ // this caused an infinite loop
+ load(DATA_DIRECTORY, "fdo43573-2-min.docx");
+
+ xmlDocPtr pLayout = parseLayoutDump();
+ // check the first paragraph on page 9 with its fly; the colum was empty too
+ assertXPath(pLayout, "/root/page[9]/body/section[1]/column[1]/body/txt[1]/Text[1]", "Portion",
+ "De kleur u (rood) in het rechtervlak (R), de kleur r (wit) beneden (D),");
+ SwTwips nPage9Top = getXPath(pLayout, "/root/page[9]/infos/bounds", "top").toInt32();
+ assertXPath(
+ pLayout,
+ "/root/page[9]/body/section[1]/column[1]/body/txt[1]/anchored/fly[1]/notxt/infos/bounds",
+ "top", OUString::number(nPage9Top + 1460));
+}
+
CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf128198)
{
SwDoc* pDoc = createDoc("tdf128198-1.docx");
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index b2e5ad630316..a47d95e1ae6d 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -1469,6 +1469,7 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl )
do
{
pLast = pFrame;
+ bool const wasFrameLowerOfLay(pLay->IsAnLower(pFrame));
if( pFrame->IsVertical() ?
( pFrame->GetUpper()->getFramePrintArea().Height() != pFrame->getFrameArea().Height() )
: ( pFrame->GetUpper()->getFramePrintArea().Width() != pFrame->getFrameArea().Width() ) )
@@ -1610,7 +1611,10 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl )
// #i28701# - restart layout process, if
// requested by floating screen object formatting
- if ( bRestartLayoutProcess )
+ if (bRestartLayoutProcess
+ // tdf#142080 if it was aleady on next page, and still is,
+ // ignore restart, as restart could cause infinite loop
+ && (wasFrameLowerOfLay || pLay->IsAnLower(pFrame)))
{
pFrame = pLay->ContainsAny();
pAgainObj1 = nullptr;
@@ -1674,10 +1678,10 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl )
pFrame->InvalidatePos_();
}
}
- // Stay in the pLay
- // Except for SectionFrames with Follow: the first ContentFrame of the Follow
- // will be formatted, so that it gets a chance to load in the pLay.
- // As long as these Frames are loading in pLay, we continue
+ // Stay in the pLay.
+ // Except for SectionFrames with Follow: the first ContentFrame of the
+ // Follow will be formatted, so that it gets a chance to move back
+ // into the pLay. Continue as long as these Frames land in pLay.
} while ( pFrame &&
( pLay->IsAnLower( pFrame ) ||
( pSect &&
More information about the Libreoffice-commits
mailing list