sw/qa/extras/rtfexport/rtfexport3.cxx       |   47 ++++++++++++++++++++++++++++
 sw/source/filter/ww8/rtfattributeoutput.cxx |   12 +++++--
 sw/source/filter/ww8/rtfattributeoutput.hxx |    2 -
 3 files changed, 57 insertions(+), 4 deletions(-)

New commits:
commit a4bdd833a252ed4d942e4478fc820f9f2ee725fe
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Mar 1 20:57:38 2021 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Mar 3 12:16:24 2021 +0100

    tdf#140552 RTF export: fix hyperlink, in footnote, in hyperlink
    
    Regression from commit 7d42346ba77c9c4df241ea40eaf550993ca18783
    (tdf#90421 RTF export: ignore hyperlinks without an URL, 2015-04-21),
    URLs can be nested in the footnote case, which requires a stack.
    Otherwise the inner URL clears "the" URL and we don't close the outer
    field as we believe it's empty, so it was not started.
    
    Change-Id: I9f87ddbb7e597c413bf836eb9b58beb76722361f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111794
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 5a74baa4f033f84c4bbcec869a68eef149f77161)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111778
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111823
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx 
b/sw/qa/extras/rtfexport/rtfexport3.cxx
index 7bb20cbb410e..45f84f5c5089 100644
--- a/sw/qa/extras/rtfexport/rtfexport3.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport3.cxx
@@ -13,6 +13,7 @@
 #include <com/sun/star/text/XFootnotesSupplier.hpp>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
 #include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
 
 class Test : public SwModelTestBase
 {
@@ -236,6 +237,52 @@ DECLARE_RTFEXPORT_TEST(testTdf112520, "tdf112520.docx")
                          getProperty<text::TextContentAnchorType>(getShape(3), 
"AnchorType"));
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testNestedHyperlink)
+{
+    // Given a hyperlink contains a footnote which contains a hyperlink:
+    {
+        createSwDoc();
+        uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, 
uno::UNO_QUERY);
+        uno::Reference<text::XTextContent> xFootnote(
+            xFactory->createInstance("com.sun.star.text.Footnote"), 
uno::UNO_QUERY);
+        uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
+        uno::Reference<text::XText> xText = xTextDocument->getText();
+        uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+        xText->insertString(xCursor, "a", /*bAbsorb=*/false);
+        xText->insertTextContent(xCursor, xFootnote, /*bAbsorb=*/false);
+        xText->insertString(xCursor, "b", /*bAbsorb=*/false);
+        xCursor->gotoStart(/*bExpand=*/false);
+        xCursor->gotoEnd(/*bExpand=*/true);
+        uno::Reference<beans::XPropertySet> xCursorProps(xCursor, 
uno::UNO_QUERY);
+        xCursorProps->setPropertyValue("HyperLinkURL", 
uno::makeAny(OUString("http://body.com/";)));
+        uno::Reference<text::XText> xFootnoteText(xFootnote, uno::UNO_QUERY);
+        xCursor = xFootnoteText->createTextCursor();
+        xFootnoteText->insertString(xCursor, "x", /*bAbsorb=*/false);
+        xCursor->gotoStart(/*bExpand=*/false);
+        xCursor->gotoEnd(/*bExpand=*/true);
+        xCursorProps.set(xCursor, uno::UNO_QUERY);
+        xCursorProps->setPropertyValue("HyperLinkURL",
+                                       
uno::makeAny(OUString("http://footnote.com/";)));
+    }
+
+    // When exporting to RTF:
+    // Without the accompanying fix in place, this test would have failed with:
+    // assertion failed
+    // - Expression: xComponent.is()
+    // i.e. the RTF output was not well-formed, loading failed.
+    reload(mpFilter, "nested-hyperlink.rtf");
+
+    // Then make sure both hyperlinks are have the correct URLs.
+    uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
+    uno::Reference<text::XTextRange> xPortion = getRun(xParagraph, 1);
+    CPPUNIT_ASSERT_EQUAL(OUString("http://body.com/";),
+                         getProperty<OUString>(xPortion, "HyperLinkURL"));
+    auto xFootnote = 
getProperty<uno::Reference<text::XText>>(getRun(xParagraph, 2), "Footnote");
+    uno::Reference<text::XTextRange> xFootnotePortion = 
getRun(getParagraphOfText(1, xFootnote), 1);
+    CPPUNIT_ASSERT_EQUAL(OUString("http://footnote.com/";),
+                         getProperty<OUString>(xFootnotePortion, 
"HyperLinkURL"));
+}
+
 DECLARE_RTFEXPORT_TEST(testTdf121623, "tdf121623.rtf")
 {
     // This was 2, multicolumn section was ignored at the table.
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 10d38a569e92..fe7f24e474be 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -530,7 +530,7 @@ void RtfAttributeOutput::EndRuby(const SwTextNode& rNode, 
sal_Int32 nPos)
 
 bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& 
rTarget)
 {
-    m_sURL = rUrl;
+    m_aURLs.push(rUrl);
     // Ignore hyperlink without a URL.
     if (!rUrl.isEmpty())
     {
@@ -560,7 +560,13 @@ bool RtfAttributeOutput::StartURL(const OUString& rUrl, 
const OUString& rTarget)
 
 bool RtfAttributeOutput::EndURL(bool const isAtEndOfParagraph)
 {
-    if (!m_sURL.isEmpty())
+    if (m_aURLs.empty())
+    {
+        return true;
+    }
+
+    const OUString& rURL = m_aURLs.top();
+    if (!rURL.isEmpty())
     {
         // UGLY: usually EndRun is called earlier, but there is an extra
         // call to OutAttrWithRange() when at the end of the paragraph,
@@ -580,8 +586,8 @@ bool RtfAttributeOutput::EndURL(bool const 
isAtEndOfParagraph)
             // close the field group
             m_aRun->append('}');
         }
-        m_sURL.clear();
     }
+    m_aURLs.pop();
     return true;
 }
 
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx 
b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 2493ce38fbb0..2a739a330f1e 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -617,7 +617,7 @@ private:
     std::optional<css::drawing::FillStyle> m_oFillStyle;
 
     /// If we're in the process of exporting a hyperlink, then its URL.
-    OUString m_sURL;
+    std::stack<OUString> m_aURLs;
 
     /// If original file had \sbauto.
     bool m_bParaBeforeAutoSpacing;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to