sw/qa/extras/ooxmlimport/data/tdf159897_broken_link.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport2.cxx                |   48 ++++++++++++++
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx     |   51 ++++++++++++---
 3 files changed, 91 insertions(+), 8 deletions(-)

New commits:
commit efb805eb244ad9f0317083502412b5d38d7f048d
Author:     Tibor Nagy <tibor.nagy.ext...@allotropia.de>
AuthorDate: Mon Jun 10 22:33:45 2024 +0200
Commit:     Nagy Tibor <tibor.nagy.ext...@allotropia.de>
CommitDate: Tue Jun 11 11:27:31 2024 +0200

    tdf#159897 docx import: fix broken hyperlink
    
    If the ScreenTip contains quotation marks, the link will be incorrect
    
    Change-Id: I10f5039144c71bf5105cbd4dd9e82076a4d92fc6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168648
    Tested-by: Jenkins
    Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de>

diff --git a/sw/qa/extras/ooxmlimport/data/tdf159897_broken_link.docx 
b/sw/qa/extras/ooxmlimport/data/tdf159897_broken_link.docx
new file mode 100644
index 000000000000..70226dcb00ab
Binary files /dev/null and 
b/sw/qa/extras/ooxmlimport/data/tdf159897_broken_link.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index abd10a6c95ba..0c6e780c5a1e 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -56,6 +56,54 @@ public:
     }
 };
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf159897Broken_link)
+{
+    createSwDoc("tdf159897_broken_link.docx");
+
+    for (size_t i = 1; i < 10; ++i)
+    {
+        auto xPara(getParagraph(i));
+        auto xRun = getRun(xPara, 0);
+        OUString sURL = getProperty<OUString>(xRun, "HyperLinkURL");
+        CPPUNIT_ASSERT_EQUAL(OUString("https://libreoffice.org/";), sURL);
+
+        OUString sText;
+        switch (i)
+        {
+            case 1:
+                sText = "Zeroth link";
+                break;
+            case 2:
+                sText = "First \"link\"";
+                break;
+            case 3:
+                sText = "Second \" link \"";
+                break;
+            case 4:
+                sText = "Third \"\"\"link\"\"\"";
+                break;
+            case 5:
+                sText = "\"Fourth\" link";
+                break;
+            case 6:
+                sText = "Fifth \"5\" link";
+                break;
+            case 7:
+                sText = "Sixth \"6\" link";
+                break;
+            case 8:
+                sText = "Seventh \"link\"";
+                break;
+            case 9:
+                sText = "\"Eighth\" link";
+                break;
+        }
+
+        OUString sScreenTip = getProperty<OUString>(xRun, "HyperLinkName");
+        CPPUNIT_ASSERT_EQUAL(sText, sScreenTip);
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf143476LockedCanvas_twoShapes)
 {
     // Given a lockedCanvas in a docx document with compatibility to Word 
version 12 (2007).
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 7f026444894d..65840bf3b3f4 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -6122,6 +6122,7 @@ void FieldContext::AppendCommand(std::u16string_view 
rPart)
     ::std::vector<OUString> aResult;
     sal_Int32 nIndex = 0;
     bool bInString = false;
+    bool bScreenTip = false;
     OUString sPart;
     while (nIndex != -1)
     {
@@ -6131,17 +6132,51 @@ void FieldContext::AppendCommand(std::u16string_view 
rPart)
         if (sToken.isEmpty())
             continue;
 
-        if (sToken[0] == '"')
+        if (bScreenTip)
         {
-            bInStringNext = true;
-            sToken = sToken.copy(1);
+            bool bRemoveQuotation = true;
+            bInStringNext = (nIndex != -1) ? true : false;
+
+            if (sToken[0] == '"' && !bInString)
+                sToken = sToken.copy(1);
+
+            if (!sToken.isEmpty())
+            {
+                if (sToken[0] == '\')
+                {
+                    bRemoveQuotation = false;
+                    OUStringBuffer sBuffer;
+                    for (sal_Int32 i = 0; i < sToken.getLength(); ++i)
+                    {
+                        if (sToken[i] != '\')
+                        {
+                            sBuffer.append(sToken[i]);
+                        }
+                    }
+                    sToken = sBuffer.makeStringAndClear();
+                }
+            }
+
+            if (!bInStringNext && bRemoveQuotation)
+                sToken = sToken.copy(0, sToken.getLength() - 1);
         }
-        if (sToken.endsWith("\""))
+        else
         {
-            bInStringNext = false;
-            sToken = sToken.copy(0, sToken.getLength() - 1);
+            if (sToken[0] == '"')
+            {
+                bInStringNext = true;
+                sToken = sToken.copy(1);
+            }
+            if (sToken.endsWith("\""))
+            {
+                bInStringNext = false;
+                sToken = sToken.copy(0, sToken.getLength() - 1);
+            }
         }
 
+        if (sToken == "\o")
+            bScreenTip = true;
+
         if (bInString)
         {
             sPart += " " + sToken;
@@ -7939,7 +7974,7 @@ void DomainMapper_Impl::CloseFieldCommand()
 
                     if (!sTarget.isEmpty())
                         pContext->SetHyperlinkTarget(sTarget);
-                    else if (!sName.isEmpty())
+                    if (!sName.isEmpty())
                         pContext->SetHyperlinkName(sName);
                 }
                 break;
@@ -8852,7 +8887,7 @@ void DomainMapper_Impl::PopFieldContext()
 
                                 if (!pContext->GetHyperlinkTarget().isEmpty())
                                     
xCrsrProperties->setPropertyValue(u"HyperLinkTarget"_ustr, 
uno::Any(pContext->GetHyperlinkTarget()));
-                                else if 
(!pContext->GetHyperlinkName().isEmpty())
+                                if (!pContext->GetHyperlinkName().isEmpty())
                                     
xCrsrProperties->setPropertyValue(u"HyperLinkName"_ustr, 
uno::Any(pContext->GetHyperlinkName()));
 
                                 if (IsInTOC())

Reply via email to