include/xmlsecurity/pdfio/pdfdocument.hxx | 278 +++++++++++++++++++++++ include/xmlsecurity/xmlsecuritydllapi.h | 23 + vcl/CppunitTest_vcl_pdfexport.mk | 42 +++ vcl/Module_vcl.mk | 1 vcl/qa/cppunit/pdfexport/data/tdf106059.odt |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 103 ++++++++ xmlsecurity/inc/documentsignaturehelper.hxx | 2 xmlsecurity/inc/documentsignaturemanager.hxx | 2 xmlsecurity/inc/pdfio/pdfdocument.hxx | 250 -------------------- xmlsecurity/inc/pdfsignaturehelper.hxx | 2 xmlsecurity/inc/xmlsecuritydllapi.h | 23 - xmlsecurity/inc/xmlsignaturehelper.hxx | 2 xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx | 2 xmlsecurity/source/helper/pdfsignaturehelper.cxx | 2 xmlsecurity/source/pdfio/pdfdocument.cxx | 41 +-- xmlsecurity/workben/pdfverify.cxx | 4 16 files changed, 471 insertions(+), 306 deletions(-)
New commits: commit 58eac1105f8504bd5320911fc6fe967ccaa3d469 Author: Miklos Vajna <[email protected]> Date: Fri Feb 24 13:46:52 2017 +0100 vcl: add initial CppunitTest_vcl_pdfexport Invoke the PDF export filter and then use the PDF tokenizer from xmlsecurity to assert the contents of created PDF file. The testcase fails with commit 6db0f1feb1d9931d2726dd11a889c58815710ce0 (tdf#106059 PDF export: create a reference XObject for PDF images, 2017-02-22) reverted. Change-Id: I90526fef41d9560ae447f586df766bc50a491c43 Reviewed-on: https://gerrit.libreoffice.org/34609 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins <[email protected]> diff --git a/xmlsecurity/inc/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx similarity index 85% rename from xmlsecurity/inc/pdfio/pdfdocument.hxx rename to include/xmlsecurity/pdfio/pdfdocument.hxx index acf873c..0b27014 100644 --- a/xmlsecurity/inc/pdfio/pdfdocument.hxx +++ b/include/xmlsecurity/pdfio/pdfdocument.hxx @@ -8,8 +8,8 @@ * */ -#ifndef INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX -#define INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX +#ifndef INCLUDED_XMLSECURITY_PDFIO_PDFDOCUMENT_HXX +#define INCLUDED_XMLSECURITY_PDFIO_PDFDOCUMENT_HXX #include <map> #include <vector> @@ -18,8 +18,9 @@ #include <tools/stream.hxx> -#include <xmlsecuritydllapi.h> -#include <sigstruct.hxx> +#include <xmlsecurity/xmlsecuritydllapi.h> + +struct SignatureInformation; namespace xmlsecurity { @@ -103,6 +104,33 @@ public: sal_uInt64 GetLength() const; }; +/// Dictionary object: a set key-value pairs. +class XMLSECURITY_DLLPUBLIC PDFDictionaryElement : public PDFElement +{ + /// Key-value pairs when the dictionary is a nested value. + std::map<OString, PDFElement*> m_aItems; + /// Offset after the '<<' token. + sal_uInt64 m_nLocation = 0; + /// Position after the '/' token. + std::map<OString, sal_uInt64> m_aDictionaryKeyOffset; + /// Length of the dictionary key and value, till (before) the next token. + std::map<OString, sal_uInt64> m_aDictionaryKeyValueLength; + +public: + PDFDictionaryElement(); + bool Read(SvStream& rStream) override; + + static size_t Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary); + static PDFElement* Lookup(const std::map<OString, PDFElement*>& rDictionary, const OString& rKey); + void SetKeyOffset(const OString& rKey, sal_uInt64 nOffset); + sal_uInt64 GetKeyOffset(const OString& rKey) const; + void SetKeyValueLength(const OString& rKey, sal_uInt64 nLength); + sal_uInt64 GetKeyValueLength(const OString& rKey) const; + const std::map<OString, PDFElement*>& GetItems() const; + /// Looks up an object which is only referenced in this dictionary. + PDFObjectElement* LookupObject(const OString& rDictionaryKey); +}; + enum class TokenizeMode { /// Full file. @@ -245,6 +273,6 @@ public: } // namespace pdfio } // namespace xmlsecurity -#endif // INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX +#endif // INCLUDED_XMLSECURITY_PDFIO_PDFDOCUMENT_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/inc/xmlsecuritydllapi.h b/include/xmlsecurity/xmlsecuritydllapi.h similarity index 79% rename from xmlsecurity/inc/xmlsecuritydllapi.h rename to include/xmlsecurity/xmlsecuritydllapi.h index 2349d23..48da546 100644 --- a/xmlsecurity/inc/xmlsecuritydllapi.h +++ b/include/xmlsecurity/xmlsecuritydllapi.h @@ -7,8 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_XMLSECURITY_INCDLLAPI_H -#define INCLUDED_XMLSECURITY_INCDLLAPI_H +#ifndef INCLUDED_XMLSECURITY_XMLSECURITYDLLAPI_H +#define INCLUDED_XMLSECURITY_XMLSECURITYDLLAPI_H #include <sal/types.h> @@ -18,6 +18,6 @@ #define XMLSECURITY_DLLPUBLIC SAL_DLLPUBLIC_IMPORT #endif -#endif // INCLUDED_XMLSECURITY_INCDLLAPI_H +#endif // INCLUDED_XMLSECURITY_XMLSECURITYDLLAPI_H /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/CppunitTest_vcl_pdfexport.mk b/vcl/CppunitTest_vcl_pdfexport.mk new file mode 100644 index 0000000..8f0cbcd --- /dev/null +++ b/vcl/CppunitTest_vcl_pdfexport.mk @@ -0,0 +1,42 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,vcl_pdfexport)) + +$(eval $(call gb_CppunitTest_add_exception_objects,vcl_pdfexport, \ + vcl/qa/cppunit/pdfexport/pdfexport \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfexport)) + +$(eval $(call gb_CppunitTest_use_libraries,vcl_pdfexport, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + test \ + unotest \ + utl \ + tl \ + xmlsecurity \ + $(gb_UWINAPI) \ +)) + +$(eval $(call gb_CppunitTest_use_external,vcl_pdfexport,boost_headers)) + +$(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfexport)) + +$(eval $(call gb_CppunitTest_use_ure,vcl_pdfexport)) +$(eval $(call gb_CppunitTest_use_vcl,vcl_pdfexport)) + +$(eval $(call gb_CppunitTest_use_rdb,vcl_pdfexport,services)) + +$(eval $(call gb_CppunitTest_use_configuration,vcl_pdfexport)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 2180084..730a3b0 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -143,6 +143,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\ $(if $(MERGELIBS),,CppunitTest_vcl_wmf_test) \ CppunitTest_vcl_jpeg_read_write_test \ CppunitTest_vcl_svm_test \ + CppunitTest_vcl_pdfexport \ )) diff --git a/vcl/qa/cppunit/pdfexport/data/tdf106059.odt b/vcl/qa/cppunit/pdfexport/data/tdf106059.odt new file mode 100644 index 0000000..a2c1803 Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf106059.odt differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx new file mode 100644 index 0000000..bcc3345 --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/XStorable.hpp> + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/implbase.hxx> +#include <test/bootstrapfixture.hxx> +#include <unotest/macros_test.hxx> +#include <unotools/mediadescriptor.hxx> +#include <unotools/tempfile.hxx> +#include <xmlsecurity/pdfio/pdfdocument.hxx> + +using namespace ::com::sun::star; + +namespace +{ + +const char* const DATA_DIRECTORY = "/vcl/qa/cppunit/pdfexport/data/"; + +/// Tests the PDF export filter. +class PdfExportTest : public test::BootstrapFixture, public unotest::MacrosTest +{ + uno::Reference<uno::XComponentContext> mxComponentContext; + uno::Reference<lang::XComponent> mxComponent; + +public: + virtual void setUp() override; + virtual void tearDown() override; + /// Tests that a pdf image is roundtripped back to PDF as a vector format. + void testTdf106059(); + + CPPUNIT_TEST_SUITE(PdfExportTest); + CPPUNIT_TEST(testTdf106059); + CPPUNIT_TEST_SUITE_END(); +}; + +void PdfExportTest::setUp() +{ + test::BootstrapFixture::setUp(); + + mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory())); + mxDesktop.set(frame::Desktop::create(mxComponentContext)); +} + +void PdfExportTest::tearDown() +{ + if (mxComponent.is()) + mxComponent->dispose(); + + test::BootstrapFixture::tearDown(); +} + +void PdfExportTest::testTdf106059() +{ + // Import the bugdoc and export as PDF. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf106059.odt"; + 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("writer_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)); + + // Assert that the XObject in the page resources dictionary is a reference XObject. + std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages(); + // The document has one page. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size()); + xmlsecurity::pdfio::PDFObjectElement* pResources = aPages[0]->LookupObject("Resources"); + CPPUNIT_ASSERT(pResources); + auto pXObjects = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pResources->Lookup("XObject")); + CPPUNIT_ASSERT(pXObjects); + // The page has one image. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pXObjects->GetItems().size()); + xmlsecurity::pdfio::PDFObjectElement* pReferenceXObject = pXObjects->LookupObject(pXObjects->GetItems().begin()->first); + CPPUNIT_ASSERT(pReferenceXObject); + // The image is a reference XObject. + // This dictionary key was missing, so the XObject wasn't a reference one. + CPPUNIT_ASSERT(pReferenceXObject->Lookup("Ref")); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest); + +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/inc/documentsignaturehelper.hxx b/xmlsecurity/inc/documentsignaturehelper.hxx index 10268e7..c2b5b85 100644 --- a/xmlsecurity/inc/documentsignaturehelper.hxx +++ b/xmlsecurity/inc/documentsignaturehelper.hxx @@ -24,7 +24,7 @@ #include <com/sun/star/xml/sax/XDocumentHandler.hpp> #include <rtl/ustring.hxx> #include "sigstruct.hxx" -#include "xmlsecuritydllapi.h" +#include "xmlsecurity/xmlsecuritydllapi.h" #include <vector> diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx index fe9f9a4..af34654 100644 --- a/xmlsecurity/inc/documentsignaturemanager.hxx +++ b/xmlsecurity/inc/documentsignaturemanager.hxx @@ -20,7 +20,7 @@ #ifndef INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREMANAGER_HXX #define INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREMANAGER_HXX -#include "xmlsecuritydllapi.h" +#include "xmlsecurity/xmlsecuritydllapi.h" #include <memory> diff --git a/xmlsecurity/inc/pdfsignaturehelper.hxx b/xmlsecurity/inc/pdfsignaturehelper.hxx index 463961a..74b89fe 100644 --- a/xmlsecurity/inc/pdfsignaturehelper.hxx +++ b/xmlsecurity/inc/pdfsignaturehelper.hxx @@ -11,7 +11,7 @@ #ifndef INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX #define INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX -#include <xmlsecuritydllapi.h> +#include <xmlsecurity/xmlsecuritydllapi.h> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/security/DocumentSignatureInformation.hpp> diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx index edc09d0..eb44e52 100644 --- a/xmlsecurity/inc/xmlsignaturehelper.hxx +++ b/xmlsecurity/inc/xmlsignaturehelper.hxx @@ -27,7 +27,7 @@ #include <rtl/ref.hxx> #include <sigstruct.hxx> #include <xsecctl.hxx> -#include <xmlsecuritydllapi.h> +#include <xmlsecurity/xmlsecuritydllapi.h> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/xml/sax/XWriter.hpp> diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx index 748780a..ca17aa2 100644 --- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx +++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx @@ -17,7 +17,7 @@ #include <unotools/ucbstreamhelper.hxx> #include <documentsignaturemanager.hxx> -#include <pdfio/pdfdocument.hxx> +#include <xmlsecurity/pdfio/pdfdocument.hxx> using namespace com::sun::star; diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx index 4b8859f..18bf89e 100644 --- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx +++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx @@ -20,7 +20,7 @@ #include <tools/stream.hxx> #include <unotools/ucbstreamhelper.hxx> -#include <pdfio/pdfdocument.hxx> +#include <xmlsecurity/pdfio/pdfdocument.hxx> using namespace ::com::sun::star; diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx index 0d6c7e1..50e00d7 100644 --- a/xmlsecurity/source/pdfio/pdfdocument.cxx +++ b/xmlsecurity/source/pdfio/pdfdocument.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <pdfio/pdfdocument.hxx> +#include <xmlsecurity/pdfio/pdfdocument.hxx> #include <map> #include <memory> @@ -31,6 +31,8 @@ #include <xmloff/xmluconv.hxx> #include <o3tl/make_unique.hxx> +#include <sigstruct.hxx> + #ifdef XMLSEC_CRYPTO_NSS #include <cert.h> #include <cms.h> @@ -87,31 +89,6 @@ public: class PDFReferenceElement; -/// Dictionary object: a set key-value pairs. -class PDFDictionaryElement : public PDFElement -{ - /// Key-value pairs when the dictionary is a nested value. - std::map<OString, PDFElement*> m_aItems; - /// Offset after the '<<' token. - sal_uInt64 m_nLocation = 0; - /// Position after the '/' token. - std::map<OString, sal_uInt64> m_aDictionaryKeyOffset; - /// Length of the dictionary key and value, till (before) the next token. - std::map<OString, sal_uInt64> m_aDictionaryKeyValueLength; - -public: - PDFDictionaryElement(); - bool Read(SvStream& rStream) override; - - static size_t Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary); - static PDFElement* Lookup(const std::map<OString, PDFElement*>& rDictionary, const OString& rKey); - void SetKeyOffset(const OString& rKey, sal_uInt64 nOffset); - sal_uInt64 GetKeyOffset(const OString& rKey) const; - void SetKeyValueLength(const OString& rKey, sal_uInt64 nLength); - sal_uInt64 GetKeyValueLength(const OString& rKey) const; - const std::map<OString, PDFElement*>& GetItems() const; -}; - /// End of a dictionary: '>>'. class PDFEndDictionaryElement : public PDFElement { @@ -3182,6 +3159,18 @@ PDFElement* PDFDictionaryElement::Lookup(const std::map<OString, PDFElement*>& r return it->second; } +PDFObjectElement* PDFDictionaryElement::LookupObject(const OString& rDictionaryKey) +{ + auto pKey = dynamic_cast<PDFReferenceElement*>(PDFDictionaryElement::Lookup(m_aItems, rDictionaryKey)); + if (!pKey) + { + SAL_WARN("xmlsecurity.pdfio", "PDFDictionaryElement::LookupObject: no such key with reference value: " << rDictionaryKey); + return nullptr; + } + + return pKey->LookupObject(); +} + PDFElement* PDFObjectElement::Lookup(const OString& rDictionaryKey) { if (m_aDictionary.empty()) diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx index d481d15..5e19601 100644 --- a/xmlsecurity/workben/pdfverify.cxx +++ b/xmlsecurity/workben/pdfverify.cxx @@ -31,7 +31,9 @@ #include <vcl/pngwrite.hxx> #include <vcl/svapp.hxx> -#include <pdfio/pdfdocument.hxx> +#include <xmlsecurity/pdfio/pdfdocument.hxx> + +#include <sigstruct.hxx> using namespace com::sun::star; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
