sw/qa/core/layout/data/inline-endnote-section-delete.docx |binary
 sw/qa/core/layout/ftnfrm.cxx                              |   31 ++++++++++++++
 sw/source/core/layout/ftnfrm.cxx                          |    4 +
 3 files changed, 34 insertions(+), 1 deletion(-)

New commits:
commit 3f2d0414686a8f9a042413c47c4c8ffa5d61f436
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon May 27 09:41:18 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon May 27 11:27:34 2024 +0200

    tdf#160984 sw continuous endnotes: fix crash on loading 
forum-mso-en-7731.docx
    
    Regression from commit 1ae5ea3f78cca11ba18f2dd1a06f875263336a3b
    (tdf#160984 sw continuous endnotes: enable DOCX import, 2024-05-21), the
    bugdoc crashed in SwSectionFrame::GetEndSectFormat_().
    
    What seems to happen is that the first endnote is added to page 1, then
    more content is inserted, so the endnote is moved to page 2, which
    leaves an empty endnote section on page 1, which is marked for deletion
    in SwSectionFrame::MakeAll(), and will be deleted in
    SwRootFrame::DeleteEmptySct_(). At some point (after marking for
    deletion, before deletion) SwFootnoteBossFrame::AppendFootnote() tries
    to find the first endnote section in the layout, and finds this section,
    but it crashes because there is no SwSection attached to it, as marking
    for deletion in SwSectionFrame::DelEmpty() clears that.
    
    Fix the problem by ignoring to-be-deleted sections in
    SwFootnoteBossFrame::AppendFootnote(): this way a new, usable section
    will be created and the to-be-deleted section go away as the layout
    finishes.
    
    An alternative would be to check for SwSectionFrame::GetSection()
    earlier, as we iterate on pages (hoping that this way we find a later
    page that has a not-dead endnote section), but that leads to 6 pages
    instead of 4 pages for the bugdoc, so don't go that way.
    
    Change-Id: I9a21cbccb5a088314520c7ade55dbdf9966d1265
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168084
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/layout/data/inline-endnote-section-delete.docx 
b/sw/qa/core/layout/data/inline-endnote-section-delete.docx
new file mode 100644
index 000000000000..bf3d3e60d890
Binary files /dev/null and 
b/sw/qa/core/layout/data/inline-endnote-section-delete.docx differ
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index a7640e26ca9a..98387be6a983 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -17,6 +17,8 @@
 #include <rootfrm.hxx>
 #include <view.hxx>
 #include <wrtsh.hxx>
+#include <bodyfrm.hxx>
+#include <sectfrm.hxx>
 
 /// Covers sw/source/core/layout/ftnfrm.cxx fixes.
 class Test : public SwModelTestBase
@@ -122,4 +124,33 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(269), nEndnoteContTopMargin);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSectionDelete)
+{
+    // Given a document, ContinuousEndnotes is true, 3 pages, endnodes start 
on page 2:
+    // When laying out that document:
+    createSwDoc("inline-endnote-section-delete.docx");
+
+    // First page: just body text:
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage = pLayout->Lower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+    auto pBodyFrame = static_cast<SwBodyFrame*>(pPage->GetLower());
+    CPPUNIT_ASSERT(!pBodyFrame->GetLastLower()->IsSctFrame());
+    // Second page: ends with endnotes:
+    pPage = pPage->GetNext()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+    pBodyFrame = static_cast<SwBodyFrame*>(pPage->GetLower());
+    CPPUNIT_ASSERT(pBodyFrame->GetLastLower()->IsSctFrame());
+    auto pSection = static_cast<SwSectionFrame*>(pBodyFrame->GetLastLower());
+    CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+    // Third page: just endnotes:
+    pPage = pPage->GetNext()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+    pBodyFrame = static_cast<SwBodyFrame*>(pPage->GetLower());
+    CPPUNIT_ASSERT(pBodyFrame->GetLower()->IsSctFrame());
+    pSection = static_cast<SwSectionFrame*>(pBodyFrame->GetLower());
+    CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 548d8228063e..bb35d1c1025c 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -1626,7 +1626,9 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame 
*pRef, SwTextFootnote *
                 pEndnoteSection = pPage->GetEndNoteSection();
             }
             // If there are no endnotes sections yet, create one at the end of 
the document.
-            if (!pEndnoteSection)
+            // Ignore sections which are already marked for deletion, they 
don't have an SwSection
+            // anymore, so not usable for us.
+            if (!pEndnoteSection || !pEndnoteSection->GetSection())
             {
                 SwSection* pSwSection = 
pDoc->GetEndNoteInfo().GetSwSection(*pDoc);
                 pEndnoteSection = new SwSectionFrame(*pSwSection, pPage);

Reply via email to