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 <vmik...@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; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits