summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <jan-marek.glogowski@extern.cib.de>2020-02-04 14:29:46 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2020-02-05 02:38:29 +0100
commit7d886eec953efa593708db9560d0e69ac12c99cf (patch)
tree9978b8f1b157706e0c277d090813a3babd5cbf99
parentc161478ed50f6ee8878335db113f8850a136615b (diff)
tdf#129912 correctly stop unstyled footnote parsing
The bug document somehow manages to generated a footnote, which never terminates the format loop in SwTextFrame::Format_. It contains an unstyled footnote, which I wasn't able to reproduce to create in Word. So I manually edited the XML of the included unit test document, which I used to develop the original patch, and which reproduces the broken parsing behaviour. This patch correctly stops the parsing of the custom footnote reference, if the text run containing the footnote reference is finished, which also fixes loading the bug document. The unit test checks various footnote variants, which represent different problems I found when developing the custom footnote parsing in commit a991ad93dcd6807d0eacd11a50c2ae43a2cfb882 ("tdf#121441 improve DOCX footnote import") and now also includes an unstyled one. It also contains a (still?) broken footnote test, with a complex differing footnote. Change-Id: I748955285d76b6f3122d1da5d8823068f3d7633f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87981 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
-rw-r--r--sw/qa/extras/ooxmlimport/data/tdf129912.docxbin0 -> 19435 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport2.cxx36
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx1
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx7
4 files changed, 43 insertions, 1 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/tdf129912.docx b/sw/qa/extras/ooxmlimport/data/tdf129912.docx
new file mode 100644
index 000000000000..d87255ffd61d
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/tdf129912.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 7ba2aae3d74a..7688e1927acb 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -25,6 +25,8 @@
#include <IMark.hxx>
#include <sortedobjs.hxx>
#include <anchoredobject.hxx>
+#include <fmtftn.hxx>
+#include <ftnidx.hxx>
class Test : public SwModelTestBase
{
@@ -541,6 +543,40 @@ DECLARE_OOXMLIMPORT_TEST(testTdf129659, "tdf129659.docx")
// don't crash on footnote with page break
}
+DECLARE_OOXMLIMPORT_TEST(testTdf129912, "tdf129912.docx")
+{
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // Goto*FootnoteAnchor iterates the footnotes in a ring, so we need the amount of footnotes to stop the loop
+ sal_Int32 nCount = pWrtShell->GetDoc()->GetFootnoteIdxs().size();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), nCount);
+
+ // the expected footnote labels
+ // TODO: the 5th label is actually wrong (missing the "PR" after the symbol part), but the "b" is there?!
+ const sal_Unicode pLabel5[] = { u'\xF0D1', u'\xF031', u'\xF032', u'\x0062' };
+ const OUString sFootnoteLabels[] = {
+ OUString(u'\xF0A7'), "1", "2", OUString(u'\xF020'), { pLabel5, SAL_N_ELEMENTS(pLabel5) }
+ };
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(SAL_N_ELEMENTS(sFootnoteLabels)), nCount);
+
+ pWrtShell->GotoPrevFootnoteAnchor();
+ nCount--;
+ while (nCount >= 0)
+ {
+ SwFormatFootnote aFootnoteNote;
+ CPPUNIT_ASSERT(pWrtShell->GetCurFootnote(&aFootnoteNote));
+ OUString sNumStr = aFootnoteNote.GetNumStr();
+ if (sNumStr.isEmpty())
+ sNumStr = OUString::number(aFootnoteNote.GetNumber());
+ CPPUNIT_ASSERT_EQUAL(sFootnoteLabels[nCount], sNumStr);
+ pWrtShell->GotoPrevFootnoteAnchor();
+ nCount--;
+ }
+}
+
// tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 83237017ea84..aa8e7f02d6b0 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -957,7 +957,6 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
break;
case NS_ooxml::LN_CT_FtnEdnRef_id:
// footnote or endnote reference id - not needed
- m_pImpl->StartCustomFootnote(m_pImpl->GetTopContext());
break;
case NS_ooxml::LN_CT_Color_themeColor:
m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue));
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index fe4570e2286c..54e76f987ed8 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -687,6 +687,13 @@ void DomainMapper_Impl::PopProperties(ContextType eId)
deferredCharacterProperties.clear();
}
+ if (!IsInFootOrEndnote() && IsInCustomFootnote() && !m_aPropertyStacks[eId].empty())
+ {
+ PropertyMapPtr pRet = m_aPropertyStacks[eId].top();
+ if (pRet->GetFootnote().is() && m_pFootnoteContext.is())
+ EndCustomFootnote();
+ }
+
m_aPropertyStacks[eId].pop();
m_aContextStack.pop();
if(!m_aContextStack.empty() && !m_aPropertyStacks[m_aContextStack.top()].empty())