diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-02-27 14:29:03 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-02-27 15:35:48 +0000 |
commit | 64bac5c0f005afd46bbf402c5d548e2ee6c9e5c4 (patch) | |
tree | bc5a09d557804b2d3a37f92bcaf50caa24a73f09 | |
parent | aee31a4e8fa6c6f49f70945c5675085d938651ef (diff) |
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@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | include/xmlsecurity/pdfio/pdfdocument.hxx | 33 | ||||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/tdf105093.odp | bin | 0 -> 211126 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 50 | ||||
-rw-r--r-- | xmlsecurity/source/pdfio/pdfdocument.cxx | 36 |
4 files changed, 88 insertions, 31 deletions
diff --git a/include/xmlsecurity/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx index 5a8ea6c2c71d..5f64b650ed17 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 Binary files differnew file mode 100644 index 000000000000..82ce29cda0c1 --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/tdf105093.odp diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 1c665b8d2174..af6e86b7d17e 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 6ffe711363c1..5dd2f0aeaa65 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()) |