[Libreoffice-commits] core.git: writerperfect/qa writerperfect/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Jan 19 08:08:22 UTC 2018


 writerperfect/qa/unit/EPUBExportTest.cxx                      |   11 ++
 writerperfect/qa/unit/data/writer/epubexport/image-link.fodt  |    2 
 writerperfect/qa/unit/data/writer/epubexport/link-invalid.odt |binary
 writerperfect/source/writer/exp/txtparai.cxx                  |   30 +++++--
 writerperfect/source/writer/exp/xmlimp.cxx                    |   39 +++++-----
 writerperfect/source/writer/exp/xmlimp.hxx                    |   15 +++
 6 files changed, 68 insertions(+), 29 deletions(-)

New commits:
commit 5c4d5021000584ac541e4d0323586c4ff926173f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 18 11:49:45 2018 +0100

    EPUB export: fix validation error on invalid relative links
    
    It's valid to have a relative link that points nowhere in ODF, but the
    same is not true for EPUB.
    
    Change-Id: I7884032e277a0c53d0c513cea70dd2ee29ccd85c

diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index f52667a9b6ce..5a1c21c0e48f 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -85,6 +85,7 @@ public:
     void testTableCellWidth();
     void testTableRowHeight();
     void testLink();
+    void testLinkInvalid();
     void testLinkCharFormat();
     void testLinkNamedCharFormat();
     void testTableWidth();
@@ -129,6 +130,7 @@ public:
     CPPUNIT_TEST(testTableCellWidth);
     CPPUNIT_TEST(testTableRowHeight);
     CPPUNIT_TEST(testLink);
+    CPPUNIT_TEST(testLinkInvalid);
     CPPUNIT_TEST(testLinkCharFormat);
     CPPUNIT_TEST(testLinkNamedCharFormat);
     CPPUNIT_TEST(testTableWidth);
@@ -662,6 +664,15 @@ void EPUBExportTest::testLink()
     assertXPath(mpXmlDoc, "//xhtml:p/xhtml:a", "href", "https://libreoffice.org/");
 }
 
+void EPUBExportTest::testLinkInvalid()
+{
+    createDoc("link-invalid.odt", {});
+
+    mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml");
+    // This was 1, invalid relative link was not filtered out.
+    assertXPath(mpXmlDoc, "//xhtml:p/xhtml:a", 0);
+}
+
 void EPUBExportTest::testLinkCharFormat()
 {
     createDoc("link-charformat.fodt", {});
diff --git a/writerperfect/qa/unit/data/writer/epubexport/image-link.fodt b/writerperfect/qa/unit/data/writer/epubexport/image-link.fodt
index 9414e36fd723..0796cea3e4b1 100644
--- a/writerperfect/qa/unit/data/writer/epubexport/image-link.fodt
+++ b/writerperfect/qa/unit/data/writer/epubexport/image-link.fodt
@@ -16,7 +16,7 @@
   </office:master-styles>
   <office:body>
     <office:text>
-      <text:p text:style-name="Standard"><draw:a xlink:type="simple" xlink:href="meta.cover-image.png"><draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="as-char" svg:width="1.806cm" svg:height="1.806cm" draw:z-index="0"><draw:image loext:mime-type="image/png"><office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAAAFz
+      <text:p text:style-name="Standard"><draw:a xlink:type="simple" xlink:href="http://libreoffice.org/"><draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="as-char" svg:width="1.806cm" svg:height="1.806cm" draw:z-index="0"><draw:image loext:mime-type="image/png"><office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAAAFz
         UkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAA
         AAJiS0dEAACqjSMyAAAACW9GRnMAAAAGAAAAAAAMc1XTAAAACXBIWXMAAA3XAAAN1wFCKJt4
         AAAACXZwQWcAAABMAAAAQACdMTgbAAABzUlEQVRo3u3ZPU/CQBjA8X+Jxs3ESUDj4iK+LA5+
diff --git a/writerperfect/qa/unit/data/writer/epubexport/link-invalid.odt b/writerperfect/qa/unit/data/writer/epubexport/link-invalid.odt
new file mode 100644
index 000000000000..3bbbdeb921e3
Binary files /dev/null and b/writerperfect/qa/unit/data/writer/epubexport/link-invalid.odt differ
diff --git a/writerperfect/source/writer/exp/txtparai.cxx b/writerperfect/source/writer/exp/txtparai.cxx
index 309f80ce607a..904c865bf90d 100644
--- a/writerperfect/source/writer/exp/txtparai.cxx
+++ b/writerperfect/source/writer/exp/txtparai.cxx
@@ -237,6 +237,7 @@ public:
 
 private:
     librevenge::RVNGPropertyList m_aPropertyList;
+    PopupState m_ePopupState = PopupState::NONE;
 };
 
 XMLTextFrameHyperlinkContext::XMLTextFrameHyperlinkContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
@@ -265,8 +266,12 @@ void XMLTextFrameHyperlinkContext::startElement(const OUString &/*rName*/, const
             FillStyles(rAttributeValue, mrImport.GetAutomaticTextStyles(), mrImport.GetTextStyles(), m_aPropertyList);
         else
         {
-            if (rAttributeName == "xlink:href" && mrImport.FillPopupData(rAttributeValue, aPropertyList))
-                continue;
+            if (rAttributeName == "xlink:href")
+            {
+                m_ePopupState = mrImport.FillPopupData(rAttributeValue, aPropertyList);
+                if (m_ePopupState != PopupState::NotConsumed)
+                    continue;
+            }
 
             // This affects the link's properties.
             OString sName = OUStringToOString(rAttributeName, RTL_TEXTENCODING_UTF8);
@@ -275,12 +280,14 @@ void XMLTextFrameHyperlinkContext::startElement(const OUString &/*rName*/, const
         }
     }
 
-    mrImport.GetGenerator().openLink(aPropertyList);
+    if (m_ePopupState != PopupState::Ignore)
+        mrImport.GetGenerator().openLink(aPropertyList);
 }
 
 void XMLTextFrameHyperlinkContext::endElement(const OUString &/*rName*/)
 {
-    mrImport.GetGenerator().closeLink();
+    if (m_ePopupState != PopupState::Ignore)
+        mrImport.GetGenerator().closeLink();
 }
 
 void XMLTextFrameHyperlinkContext::characters(const OUString &rChars)
@@ -306,6 +313,7 @@ public:
 
 private:
     librevenge::RVNGPropertyList m_aPropertyList;
+    PopupState m_ePopupState = PopupState::NONE;
 };
 
 XMLHyperlinkContext::XMLHyperlinkContext(XMLImport &rImport, const librevenge::RVNGPropertyList &rPropertyList)
@@ -334,8 +342,12 @@ void XMLHyperlinkContext::startElement(const OUString &/*rName*/, const css::uno
             FillStyles(rAttributeValue, mrImport.GetAutomaticTextStyles(), mrImport.GetTextStyles(), m_aPropertyList);
         else
         {
-            if (rAttributeName == "xlink:href" && mrImport.FillPopupData(rAttributeValue, aPropertyList))
-                continue;
+            if (rAttributeName == "xlink:href")
+            {
+                m_ePopupState = mrImport.FillPopupData(rAttributeValue, aPropertyList);
+                if (m_ePopupState != PopupState::NotConsumed)
+                    continue;
+            }
 
             // This affects the link's properties.
             OString sName = OUStringToOString(rAttributeName, RTL_TEXTENCODING_UTF8);
@@ -344,12 +356,14 @@ void XMLHyperlinkContext::startElement(const OUString &/*rName*/, const css::uno
         }
     }
 
-    mrImport.GetGenerator().openLink(aPropertyList);
+    if (m_ePopupState != PopupState::Ignore)
+        mrImport.GetGenerator().openLink(aPropertyList);
 }
 
 void XMLHyperlinkContext::endElement(const OUString &/*rName*/)
 {
-    mrImport.GetGenerator().closeLink();
+    if (m_ePopupState != PopupState::Ignore)
+        mrImport.GetGenerator().closeLink();
 }
 
 void XMLHyperlinkContext::characters(const OUString &rChars)
diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx
index 811e604a3801..f600840be1d7 100644
--- a/writerperfect/source/writer/exp/xmlimp.cxx
+++ b/writerperfect/source/writer/exp/xmlimp.cxx
@@ -367,7 +367,7 @@ const librevenge::RVNGPropertyList &XMLImport::GetMetaData()
     return maMetaData;
 }
 
-bool XMLImport::FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList)
+PopupState XMLImport::FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList)
 {
     uno::Reference<uri::XUriReference> xUriRef;
     try
@@ -378,32 +378,33 @@ bool XMLImport::FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList
     {
         SAL_WARN("writerperfect", "XMLImport::FillPopupData: XUriReference::parse() failed:" << rException.Message);
     }
-    bool bRelative = false;
+    bool bAbsolute = true;
     if (xUriRef.is())
-        bRelative = !xUriRef->isAbsolute();
-    if (!bRelative)
-        return false;
+        bAbsolute = xUriRef->isAbsolute();
+    if (bAbsolute)
+        return PopupState::NotConsumed;
 
     OUString aAbs = maMediaDir + rURL;
     if (aAbs.isEmpty())
-        return false;
+        return PopupState::NotConsumed;
 
     SvFileStream aStream(aAbs, StreamMode::READ);
-    if (aStream.IsOpen())
-    {
-        librevenge::RVNGBinaryData aBinaryData;
-        SvMemoryStream aMemoryStream;
-        aMemoryStream.WriteStream(aStream);
-        aBinaryData.append(static_cast<const unsigned char *>(aMemoryStream.GetBuffer()), aMemoryStream.GetSize());
-        rPropList.insert("office:binary-data", aBinaryData);
+    if (!aStream.IsOpen())
+        // Relative link, but points to non-existing file: don't emit that to
+        // librevenge, since it will be invalid anyway.
+        return PopupState::Ignore;
 
-        INetURLObject aAbsURL(aAbs);
-        OUString aMimeType = GetMimeType(aAbsURL.GetExtension());
-        rPropList.insert("librevenge:mime-type", aMimeType.toUtf8().getStr());
-        return true;
-    }
+    librevenge::RVNGBinaryData aBinaryData;
+    SvMemoryStream aMemoryStream;
+    aMemoryStream.WriteStream(aStream);
+    aBinaryData.append(static_cast<const unsigned char *>(aMemoryStream.GetBuffer()), aMemoryStream.GetSize());
+    rPropList.insert("office:binary-data", aBinaryData);
+
+    INetURLObject aAbsURL(aAbs);
+    OUString aMimeType = GetMimeType(aAbsURL.GetExtension());
+    rPropList.insert("librevenge:mime-type", aMimeType.toUtf8().getStr());
 
-    return false;
+    return PopupState::Consumed;
 }
 
 const std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &XMLImport::GetPageMetafiles() const
diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx
index 9de89810f458..246eb45dbd16 100644
--- a/writerperfect/source/writer/exp/xmlimp.hxx
+++ b/writerperfect/source/writer/exp/xmlimp.hxx
@@ -33,6 +33,19 @@ namespace exp
 
 class XMLImportContext;
 
+/// States describing the result of a link -> popup conversion.
+enum class PopupState
+{
+    /// Conversion did not happen yet.
+    NONE,
+    /// The relative link was converted to a popup.
+    Consumed,
+    /// The absolute link was not handled.
+    NotConsumed,
+    /// The relative link is invalid and should be ignored.
+    Ignore
+};
+
 /// ODT export feeds this class to make librevenge calls.
 class XMLImport : public cppu::WeakImplHelper
     <
@@ -85,7 +98,7 @@ public:
     std::map<OUString, librevenge::RVNGPropertyList> &GetGraphicStyles();
     const librevenge::RVNGPropertyListVector &GetCoverImages();
     const librevenge::RVNGPropertyList &GetMetaData();
-    bool FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList);
+    PopupState FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList);
     const std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &GetPageMetafiles() const;
     const css::uno::Reference<css::uno::XComponentContext> &GetComponentContext() const;
 


More information about the Libreoffice-commits mailing list