sw/qa/extras/odfimport/data/nested_footnote.fodt |   11 +++++++++++
 sw/qa/extras/odfimport/odfimport.cxx             |   15 +++++++++++++++
 xmloff/source/text/XMLFootnoteImportContext.cxx  |   14 +++++++++++++-
 xmloff/source/text/XMLFootnoteImportContext.hxx  |    1 +
 4 files changed, 40 insertions(+), 1 deletion(-)

New commits:
commit da0e4cdc4f6bf8e0e88a4dd0e00afdf68e59a883
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Nov 21 13:57:14 2024 +0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Nov 22 11:15:50 2024 +0100

    tdf#163974: ignore nested footnotes on ODF import
    
    That is a valid, but unsupported, markup, that is explicitly mentioned
    in ODF 1.4 part 3 "Schema" sect. 6.3.4 "<text:note-body>":
    
      Note: The schema allows for the inclusion of <text:note> elements as
      a descendant of a child of the <text:note-body> element. While this
      may be reasonable for note types, it is not reasonable for footnotes
      and endnotes. Conforming consumers need not support notes inside notes.
    
    (The "reasonable for note types" is obviously an editorial error from the 
time when ODF 1.1 text "reasonable for some future note types"
    was reviewed for ODF 1.2.)
    
    As the ODF also specifies, that a conforming consumer "need not
    interpret the semantics of all elements, attributes and attribute values"
    (ibid., sect. 2.4 "Consumer"), it is OK to silently drop this data, just
    as done for other similar cases.
    
    Change-Id: I0a417981087ebf225565628f14409661058d100d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176906
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 512ef23224987e3107e66241db3b42934e15a561)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176919
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/odfimport/data/nested_footnote.fodt 
b/sw/qa/extras/odfimport/data/nested_footnote.fodt
new file mode 100644
index 000000000000..812f4610926c
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/nested_footnote.fodt
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:body>
+  <office:text>
+   <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.<text:note 
text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body>
+       <text:p>Vestibulum consequat mi quis pretium semper.<text:note 
text:note-class="footnote"><text:note-citation>2</text:note-citation><text:note-body>
+           <text:p>Proin luctus orci ac neque venenatis, quis commodo dolor 
posuere.</text:p></text:note-body></text:note></text:p></text:note-body></text:note></text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/odfimport/odfimport.cxx 
b/sw/qa/extras/odfimport/odfimport.cxx
index 2525075b3ee5..e4bfa18a442d 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -59,6 +59,7 @@
 #include <docsh.hxx>
 #include <unotxdoc.hxx>
 #include <frmatr.hxx>
+#include <expfld.hxx>
 
 #if defined(_WIN32)
 #include <officecfg/Office/Common.hxx>
@@ -1639,6 +1640,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf162398)
     SwTransferable::PasteFormat(*pWrtShell, aDataHelper, 
SotClipboardFormatId::HTML);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf163974)
+{
+    // A document with a footnote inside a footnote must load normally, 
ignoring unsupported markup.
+    // Without the fix, this would fail to load.
+    createSwDoc("nested_footnote.fodt");
+
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell->HasFootnotes());
+    SwSeqFieldList footnotes;
+    pWrtShell->GetSeqFootnoteList(footnotes);
+    // If we ever support the nested footnotes, this would naturally change
+    CPPUNIT_ASSERT_EQUAL(size_t(1), footnotes.Count());
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/XMLFootnoteImportContext.cxx 
b/xmloff/source/text/XMLFootnoteImportContext.cxx
index a73147ec09f1..fc9605bd8651 100644
--- a/xmloff/source/text/XMLFootnoteImportContext.cxx
+++ b/xmloff/source/text/XMLFootnoteImportContext.cxx
@@ -19,6 +19,7 @@
 
 #include "XMLFootnoteImportContext.hxx"
 
+#include <comphelper/diagnose_ex.hxx>
 #include <rtl/ustring.hxx>
 #include <sal/log.hxx>
 #include <xmloff/xmlimp.hxx>
@@ -102,7 +103,16 @@ void XMLFootnoteImportContext::startFastElement(
     // save old cursor and install new one
     xOldCursor = rHelper.GetCursor();
     Reference<XText> xText(xTextContent, UNO_QUERY);
-    rHelper.SetCursor(xText->createTextCursor());
+    try
+    {
+        // May fail e.g. for a nested footnote, which is formally a valid ODF, 
but is not supported
+        rHelper.SetCursor(xText->createTextCursor());
+    }
+    catch (css::uno::RuntimeException&)
+    {
+        TOOLS_WARN_EXCEPTION("xmloff.text", "skipping the footnote: caught");
+        mbIsValid = false;
+    }
 
     // remember old list item and block (#89891#) and reset them
     // for the footnote
@@ -132,6 +142,8 @@ void XMLFootnoteImportContext::endFastElement(sal_Int32 )
 css::uno::Reference< css::xml::sax::XFastContextHandler > 
XMLFootnoteImportContext::createFastChildContext(
     sal_Int32 nElement, const css::uno::Reference< 
css::xml::sax::XFastAttributeList >& xAttrList )
 {
+    if (!mbIsValid)
+        return {};
     SvXMLImportContextRef xContext;
 
     switch(nElement)
diff --git a/xmloff/source/text/XMLFootnoteImportContext.hxx 
b/xmloff/source/text/XMLFootnoteImportContext.hxx
index d05b7b631c22..8321639bbd1a 100644
--- a/xmloff/source/text/XMLFootnoteImportContext.hxx
+++ b/xmloff/source/text/XMLFootnoteImportContext.hxx
@@ -42,6 +42,7 @@ class XMLFootnoteImportContext : public SvXMLImportContext
 
     /// old list item and block (#89891#)
     bool mbListContextPushed;
+    bool mbIsValid = true;
 
     /// text import helper; holds current XTextCursor (and XText)
     XMLTextImportHelper& rHelper;

Reply via email to