[Libreoffice-commits] core.git: include/xmlsecurity vcl/qa xmlsecurity/source

Miklos Vajna vmiklos at collabora.co.uk
Mon Feb 27 15:36:20 UTC 2017


 include/xmlsecurity/pdfio/pdfdocument.hxx   |   33 ++++++++++++++++++
 vcl/qa/cppunit/pdfexport/data/tdf105093.odp |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx      |   50 ++++++++++++++++++++++++++++
 xmlsecurity/source/pdfio/pdfdocument.cxx    |   36 ++------------------
 4 files changed, 88 insertions(+), 31 deletions(-)

New commits:
commit 64bac5c0f005afd46bbf402c5d548e2ee6c9e5c4
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 27 14:29:03 2017 +0100

    tdf#105093 vcl PDF export: add embedded video testcase
    
    Fails with commit 4ad249af88d15f2c8a09f0721a59d82718fcc201 (tdf#105093
    sd PDF export: handle embedded videos, 2017-01-04) reverted.
    
    Change-Id: I413ec9a5da3c0783541dcd28fb9a62dd896f955b
    Reviewed-on: https://gerrit.libreoffice.org/34681
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/xmlsecurity/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx
index 5a8ea6c..5f64b65 100644
--- a/include/xmlsecurity/pdfio/pdfdocument.hxx
+++ b/include/xmlsecurity/pdfio/pdfdocument.hxx
@@ -90,6 +90,37 @@ public:
     void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer);
 };
 
+/// Array object: a list.
+class XMLSECURITY_DLLPUBLIC PDFArrayElement : public PDFElement
+{
+    /// Location after the '[' token.
+    sal_uInt64 m_nOffset = 0;
+    std::vector<PDFElement*> m_aElements;
+public:
+    PDFArrayElement();
+    bool Read(SvStream& rStream) override;
+    void PushBack(PDFElement* pElement);
+    const std::vector<PDFElement*>& GetElements();
+};
+
+/// Reference object: something with a unique ID.
+class XMLSECURITY_DLLPUBLIC PDFReferenceElement : public PDFElement
+{
+    PDFDocument& m_rDoc;
+    int m_fObjectValue;
+    int m_fGenerationValue;
+
+public:
+    PDFReferenceElement(PDFDocument& rDoc, int fObjectValue, int fGenerationValue);
+    bool Read(SvStream& rStream) override;
+    /// Assuming the reference points to a number object, return its value.
+    double LookupNumber(SvStream& rStream) const;
+    /// Lookup referenced object, without assuming anything about its contents.
+    PDFObjectElement* LookupObject();
+    int GetObjectValue() const;
+    int GetGenerationValue() const;
+};
+
 /// Stream object: a byte array with a known length.
 class XMLSECURITY_DLLPUBLIC PDFStreamElement : public PDFElement
 {
@@ -146,6 +177,8 @@ public:
     const std::map<OString, PDFElement*>& GetItems() const;
     /// Looks up an object which is only referenced in this dictionary.
     PDFObjectElement* LookupObject(const OString& rDictionaryKey);
+    /// Looks up an element which is contained in this dictionary.
+    PDFElement* LookupElement(const OString& rDictionaryKey);
 };
 
 enum class TokenizeMode
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf105093.odp b/vcl/qa/cppunit/pdfexport/data/tdf105093.odp
new file mode 100644
index 0000000..82ce29c
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf105093.odp differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 1c665b8..af6e86b 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -42,12 +42,15 @@ public:
     void testTdf106059();
     /// Tests that text highlight from Impress is not lost.
     void testTdf105461();
+    /// Tests that embedded video from Impress is not exported as a linked one.
+    void testTdf105093();
 #endif
 
     CPPUNIT_TEST_SUITE(PdfExportTest);
 #if HAVE_FEATURE_PDFIUM
     CPPUNIT_TEST(testTdf106059);
     CPPUNIT_TEST(testTdf105461);
+    CPPUNIT_TEST(testTdf105093);
 #endif
     CPPUNIT_TEST_SUITE_END();
 };
@@ -150,6 +153,53 @@ void PdfExportTest::testTdf105461()
     // This failed, stream contained no filled rectangle.
     CPPUNIT_ASSERT(it != pEnd);
 }
+
+void PdfExportTest::testTdf105093()
+{
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf105093.odp";
+    mxComponent = loadFromDesktop(aURL);
+    CPPUNIT_ASSERT(mxComponent.is());
+
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("impress_pdf_Export");
+    xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+    // Parse the export result.
+    xmlsecurity::pdfio::PDFDocument aDocument;
+    SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    // The document has one page.
+    std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    // Get page annotations.
+    auto pAnnots = dynamic_cast<xmlsecurity::pdfio::PDFArrayElement*>(aPages[0]->Lookup("Annots"));
+    CPPUNIT_ASSERT(pAnnots);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnnots->GetElements().size());
+    auto pAnnotReference = dynamic_cast<xmlsecurity::pdfio::PDFReferenceElement*>(pAnnots->GetElements()[0]);
+    CPPUNIT_ASSERT(pAnnotReference);
+    xmlsecurity::pdfio::PDFObjectElement* pAnnot = pAnnotReference->LookupObject();
+    CPPUNIT_ASSERT(pAnnot);
+    CPPUNIT_ASSERT_EQUAL(OString("Annot"), static_cast<xmlsecurity::pdfio::PDFNameElement*>(pAnnot->Lookup("Type"))->GetValue());
+
+    // Get the Action -> Rendition -> MediaClip -> FileSpec.
+    auto pAction = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pAnnot->Lookup("A"));
+    CPPUNIT_ASSERT(pAction);
+    auto pRendition = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pAction->LookupElement("R"));
+    CPPUNIT_ASSERT(pRendition);
+    auto pMediaClip = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pRendition->LookupElement("C"));
+    CPPUNIT_ASSERT(pMediaClip);
+    auto pFileSpec = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pMediaClip->LookupElement("D"));
+    CPPUNIT_ASSERT(pFileSpec);
+    // Make sure the filespec refers to an embedded file.
+    // This key was missing, the embedded video was handled as a linked one.
+    CPPUNIT_ASSERT(pFileSpec->LookupElement("EF"));
+}
 #endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 6ffe711..5dd2f0a 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -100,24 +100,6 @@ public:
     sal_uInt64 GetLocation() const;
 };
 
-/// Reference object: something with a unique ID.
-class PDFReferenceElement : public PDFElement
-{
-    PDFDocument& m_rDoc;
-    int m_fObjectValue;
-    int m_fGenerationValue;
-
-public:
-    PDFReferenceElement(PDFDocument& rDoc, int fObjectValue, int fGenerationValue);
-    bool Read(SvStream& rStream) override;
-    /// Assuming the reference points to a number object, return its value.
-    double LookupNumber(SvStream& rStream) const;
-    /// Lookup referenced object, without assuming anything about its contents.
-    PDFObjectElement* LookupObject();
-    int GetObjectValue() const;
-    int GetGenerationValue() const;
-};
-
 /// End of a stream: 'endstream' keyword.
 class PDFEndStreamElement : public PDFElement
 {
@@ -132,19 +114,6 @@ public:
     bool Read(SvStream& rStream) override;
 };
 
-/// Array object: a list.
-class PDFArrayElement : public PDFElement
-{
-    /// Location after the '[' token.
-    sal_uInt64 m_nOffset = 0;
-    std::vector<PDFElement*> m_aElements;
-public:
-    PDFArrayElement();
-    bool Read(SvStream& rStream) override;
-    void PushBack(PDFElement* pElement);
-    const std::vector<PDFElement*>& GetElements();
-};
-
 /// End of an array: ']'.
 class PDFEndArrayElement : public PDFElement
 {
@@ -3159,6 +3128,11 @@ PDFObjectElement* PDFDictionaryElement::LookupObject(const OString& rDictionaryK
     return pKey->LookupObject();
 }
 
+PDFElement* PDFDictionaryElement::LookupElement(const OString& rDictionaryKey)
+{
+    return PDFDictionaryElement::Lookup(m_aItems, rDictionaryKey);
+}
+
 PDFElement* PDFObjectElement::Lookup(const OString& rDictionaryKey)
 {
     if (m_aDictionary.empty())


More information about the Libreoffice-commits mailing list