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:
committed by
Xisco Fauli
parent
78cbe0b2fb
commit
2c5fa02813
Binary file not shown.
@@ -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:
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user