crashtesting: put the endnote section under the column the text ends in

seen on converting interop-test-files/odt/tdf118553-1.odt, tdf118558-1.odt
and tdf91677-1.odt to doc and reloading the exports

One dies with a stack overflow, SwFrame::InvalidateInfFlags recursing
between a column frame and a body frame that are each other's upper. The
other two abort on the pTmp->IsTabFrame() assertion at
sw/source/core/layout/sectfrm.cxx:2016 in SwFrame::GetNextSctLeaf, reached
through SwFrame::GetNextFootnoteLeaf and SwContentFrame::MoveFootnoteCntFwd.

Every doc import turns on ContinuousEndnotes, so AppendFootnote makes a
section frame for the endnotes at the end of the document and inserts it
into the page's body frame. When the page style has more than one column the
body's lowers are column frames and all the text lives in the column bodies,
so the endnote section became a sibling of the columns. Its next sibling is
then a column frame, which GetNextSctLeaf doesn't expect, and the move it
makes puts a column frame under its own child body frame.

since:

commit 6885dcd7ec
Date:   Tue May 14 08:28:33 2024 +0200

    tdf#160984 sw continuous endnotes: switch to a section-based layout

so work out where the section belongs once, in GetEndNoteSectionUpper, and
let both the insert and GetEndNoteSection ask it

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I474131fca4f74254a5168d79d83ba11116abc692
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/12675
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit f29d74eea952d3a9ea90b32afe2c9a8047afc10a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211310
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
This commit is contained in:
Caolán McNamara
2026-09-22 15:29:29 +02:00
committed by Xisco Fauli
parent 78cbe0b2fb
commit 2c5fa02813
5 changed files with 41 additions and 2 deletions
+16
View File
@@ -118,6 +118,22 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection)
CPPUNIT_ASSERT_EQUAL(2, nToplevelSections);
}
CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndColumns)
{
// Given a DOC file with an endnote and a page style with two columns, ContinuousEndnotes is
// true:
createSwDoc("inline-endnote-and-columns.doc");
// When laying out that document:
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
// Then make sure the endnote section is inside a column of the body text:
// Without the accompanying fix in place, this test would have failed with an assertion in
// SwFrame::GetNextSctLeaf(), the endnote section was a sibling of the columns.
assertXPath(pXmlDoc, "/root/page/body/column/body/section", 1);
assertXPath(pXmlDoc, "/root/page/body/section", 0);
}
CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
{
// Given a document, ContinuousEndnotes is true:
+2
View File
@@ -218,6 +218,8 @@ public:
void SetFootnotePage( bool b ) { m_bFootnotePage = b; }
void SetEndNotePage( bool b ) { m_bEndNotePage = b; }
SwSectionFrame* GetEndNoteSection();
/// The frame an endnote section at the end of the document is a lower of.
SwLayoutFrame* GetEndNoteSectionUpper();
sal_uInt16 GetPhyPageNum() const { return m_nPhyPageNum;}
void SetPhyPageNum( sal_uInt16 nNum ) { m_nPhyPageNum = nNum;}
+22 -1
View File
@@ -66,7 +66,7 @@ SwContentFrame *SwPageFrame::FindLastBodyContent()
return pRet;
}
SwSectionFrame* SwPageFrame::GetEndNoteSection()
SwLayoutFrame* SwPageFrame::GetEndNoteSectionUpper()
{
SwLayoutFrame* pBody = FindBodyCont();
if (!pBody)
@@ -75,6 +75,27 @@ SwSectionFrame* SwPageFrame::GetEndNoteSection()
}
SwFrame* pLast = pBody->GetLastLower();
if (!pLast || !pLast->IsColumnFrame())
{
return pBody;
}
// A body frame with columns keeps its text in the column bodies, so the body text ends at
// the end of the last column's body.
SwFrame* pColumnBody = static_cast<SwLayoutFrame*>(pLast)->Lower();
assert(pColumnBody && pColumnBody->IsBodyFrame() && "column frame without a body frame");
return static_cast<SwLayoutFrame*>(pColumnBody);
}
SwSectionFrame* SwPageFrame::GetEndNoteSection()
{
SwLayoutFrame* pUpper = GetEndNoteSectionUpper();
if (!pUpper)
{
return nullptr;
}
SwFrame* pLast = pUpper->GetLastLower();
if (!pLast || !pLast->IsSctFrame())
{
return nullptr;
+1 -1
View File
@@ -1658,7 +1658,7 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame *pRef, SwTextFootnote *
{
SwSection* pSwSection = rDoc.GetEndNoteInfo().GetSwSection(rDoc);
pEndnoteSection = new SwSectionFrame(*pSwSection, pPage);
SwLayoutFrame* pParent = pPage->FindBodyCont();
SwLayoutFrame* pParent = pPage->GetEndNoteSectionUpper();
SwFrame* pBefore = pPage->FindLastBodyContent();
while (pBefore)
{