diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /vcl/qa/cppunit/filter/ipdf | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/data/add-visible-signature-last-page.pdf | 111 | ||||
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/data/comment-end.pdf | 69 | ||||
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/data/dict-array-dict.pdf | 55 | ||||
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/data/real-numbers.pdf | 55 | ||||
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/ipdf.cxx | 208 |
5 files changed, 498 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/filter/ipdf/data/add-visible-signature-last-page.pdf b/vcl/qa/cppunit/filter/ipdf/data/add-visible-signature-last-page.pdf new file mode 100644 index 000000000..c321abd09 --- /dev/null +++ b/vcl/qa/cppunit/filter/ipdf/data/add-visible-signature-last-page.pdf @@ -0,0 +1,111 @@ +%PDF-1.6 +%äüöß +2 0 obj +<</Length 3 0 R/Filter/FlateDecode>> +stream +xTn1]K/I8Mg\\PԐnf2eڨpBIB2~#QwDɶƿ#gzKkMkRؼ7妁 ++Rw2Q#XQ˲sv`7Vܸ$}dFڜTXI+8+]HN+kC"Tta@+"]9ZYRq a!O<ҫ +d\)WiKO.H/\$ώga-/w- !9cDc +ΩPqe:/ tqi08{{N10\N9UҸAoݵӏZ/_b7F߾_a_t{!J@ACjl4#}ԍH뭷Gc;2?cQ@ +endstream +endobj + +3 0 obj +426 +endobj + +5 0 obj +<</Length 6 0 R/Filter/FlateDecode>> +stream +x;1D{qr$ZfO#Q#+r&x #Y Z}>a;zg6 +xn:d8
aQ^D,;7#M3qĵ1Ɛ$}5+'pΏ5y^qYW]ٶuL#>"B +endstream +endobj + +6 0 obj +167 +endobj + +8 0 obj +<< +>> +endobj + +9 0 obj +<</Font 8 0 R +/ProcSet[/PDF/Text] +>> +endobj + +1 0 obj +<</Type/Page/Parent 7 0 R/Resources 9 0 R/MediaBox[0 0 612 792]/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R>> +endobj + +4 0 obj +<</Type/Page/Parent 7 0 R/Resources 9 0 R/MediaBox[0 0 612 792]/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 5 0 R>> +endobj + +10 0 obj +<</Count 2/First 11 0 R/Last 12 0 R +>> +endobj + +11 0 obj +<</Count 0/Title<FEFF005000610067006500200031> +/Dest[1 0 R/XYZ 0 792 0]/Parent 10 0 R/Next 12 0 R>> +endobj + +12 0 obj +<</Count 0/Title<FEFF005000610067006500200032> +/Dest[4 0 R/XYZ 0 792 0]/Parent 10 0 R/Prev 11 0 R>> +endobj + +7 0 obj +<</Type/Pages +/Resources 9 0 R +/MediaBox[ 0 0 612 792 ] +/Kids[ 1 0 R 4 0 R ] +/Count 2>> +endobj + +13 0 obj +<</Type/Catalog/Pages 7 0 R +/OpenAction[1 0 R /XYZ null null 0] +/Outlines 10 0 R +>> +endobj + +14 0 obj +<</Author<FEFF004D0069006B006C006F0073002000560061006A006E0061> +/Creator<FEFF0044007200610077> +/Producer<FEFF004C0069006200720065004F0066006600690063006500440065007600200037002E0031> +/CreationDate(D:20200624113559+02'00')>> +endobj + +xref +0 15 +0000000000 65535 f +0000000869 00000 n +0000000019 00000 n +0000000516 00000 n +0000001011 00000 n +0000000536 00000 n +0000000774 00000 n +0000001443 00000 n +0000000794 00000 n +0000000816 00000 n +0000001153 00000 n +0000001209 00000 n +0000001326 00000 n +0000001547 00000 n +0000001648 00000 n +trailer +<</Size 15/Root 13 0 R +/Info 14 0 R +/ID [ <F52D3902B7388C216897409EFCC78884> +<F52D3902B7388C216897409EFCC78884> ] +/DocChecksum /67E881EB92900640250E0931504CE95E +>> +startxref +1889 +%%EOF diff --git a/vcl/qa/cppunit/filter/ipdf/data/comment-end.pdf b/vcl/qa/cppunit/filter/ipdf/data/comment-end.pdf new file mode 100644 index 000000000..6f1ad86f5 --- /dev/null +++ b/vcl/qa/cppunit/filter/ipdf/data/comment-end.pdf @@ -0,0 +1,69 @@ +%PDF-1.7 +% +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [0 0 200 300] + /Count 1 + /Kids [3 0 R] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Contents 4 0 R +>> +endobj +4 0 obj << + /Length 4 +>> +stream +q +Q +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000157 00000 n +0000000226 00000 n +trailer << + /Root 1 0 R + /Size 5 + /Prev 541 +>> +startxref +280 +%%EOF
%%TEST +4 0 obj << + /Length 5 0 R +>> +stream +q +Q +endstream +endobj +5 0 obj +4 +endobj +xref +0 6 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000157 00000 n +0000000466 00000 n +0000000524 00000 n +trailer << + /Root 1 0 R + /Size 6 +>> +startxref +280 +%%EOF diff --git a/vcl/qa/cppunit/filter/ipdf/data/dict-array-dict.pdf b/vcl/qa/cppunit/filter/ipdf/data/dict-array-dict.pdf new file mode 100644 index 000000000..73de3117b --- /dev/null +++ b/vcl/qa/cppunit/filter/ipdf/data/dict-array-dict.pdf @@ -0,0 +1,55 @@ +%PDF-1.7 +% +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [0 0 200 300] + /Count 1 + /Kids [3 0 R] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Contents 4 0 R + /Key[<</InnerKey 42>>] +>> +endobj +4 0 obj << + /Length 188 +>> +stream +q +0 0 0 rg +0 290 10 10 re B* +10 150 50 30 re B* +0 0 1 rg +190 290 10 10 re B* +70 232 50 30 re B* +0 1 0 rg +190 0 10 10 re B* +130 150 50 30 re B* +1 0 0 rg +0 0 10 10 re B* +70 67 50 30 re B* +Q +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000157 00000 n +0000000251 00000 n +trailer << + /Root 1 0 R + /Size 5 +>> +startxref +491 +%%EOF diff --git a/vcl/qa/cppunit/filter/ipdf/data/real-numbers.pdf b/vcl/qa/cppunit/filter/ipdf/data/real-numbers.pdf new file mode 100644 index 000000000..409360c54 --- /dev/null +++ b/vcl/qa/cppunit/filter/ipdf/data/real-numbers.pdf @@ -0,0 +1,55 @@ +%PDF-1.7 +% +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [0 0 200 300] + /Count 1 + /Kids [3 0 R] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Contents 4 0 R +>> +endobj +4 0 obj << + /Length 188 + /Test [.00 1.00 .00 1.00 .00 1.00] +>> +stream +q +0 0 0 rg +0 290 10 10 re B* +10 150 50 30 re B* +0 0 1 rg +190 290 10 10 re B* +70 232 50 30 re B* +0 1 0 rg +190 0 10 10 re B* +130 150 50 30 re B* +1 0 0 rg +0 0 10 10 re B* +70 67 50 30 re B* +Q +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000157 00000 n +0000000226 00000 n +trailer << + /Root 1 0 R + /Size 5 +>> +startxref +503 +%%EOF diff --git a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx new file mode 100644 index 000000000..c34bb4794 --- /dev/null +++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx @@ -0,0 +1,208 @@ +/* -*- 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 <test/bootstrapfixture.hxx> +#include <unotest/macros_test.hxx> + +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/security/XCertificate.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/xml/crypto/SEInitializer.hpp> + +#include <comphelper/propertyvalue.hxx> +#include <osl/file.hxx> +#include <unotools/tempfile.hxx> +#include <sfx2/sfxbasemodel.hxx> +#include <svx/svdview.hxx> +#include <sfx2/viewsh.hxx> +#include <svx/signaturelinehelper.hxx> +#include <sfx2/objsh.hxx> +#include <vcl/filter/PDFiumLibrary.hxx> +#include <vcl/filter/pdfdocument.hxx> + +using namespace ::com::sun::star; + +namespace +{ +constexpr OUStringLiteral DATA_DIRECTORY = u"/vcl/qa/cppunit/filter/ipdf/data/"; +} + +/// Covers vcl/source/filter/ipdf/ fixes. +class VclFilterIpdfTest : public test::BootstrapFixture, public unotest::MacrosTest +{ +private: + uno::Reference<lang::XComponent> mxComponent; + uno::Reference<xml::crypto::XSEInitializer> mxSEInitializer; + uno::Reference<xml::crypto::XXMLSecurityContext> mxSecurityContext; + +public: + void setUp() override; + void tearDown() override; + uno::Reference<lang::XComponent>& getComponent() { return mxComponent; } + uno::Reference<xml::crypto::XXMLSecurityContext>& getSecurityContext() + { + return mxSecurityContext; + } +}; + +void VclFilterIpdfTest::setUp() +{ + test::BootstrapFixture::setUp(); + MacrosTest::setUpNssGpg(m_directories, "vcl_filter_ipdf"); + + mxDesktop.set(frame::Desktop::create(mxComponentContext)); + mxSEInitializer = xml::crypto::SEInitializer::create(mxComponentContext); + mxSecurityContext = mxSEInitializer->createSecurityContext(OUString()); +} + +void VclFilterIpdfTest::tearDown() +{ + if (mxComponent.is()) + mxComponent->dispose(); + + MacrosTest::tearDownNssGpg(); + test::BootstrapFixture::tearDown(); +} + +CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testPDFAddVisibleSignatureLastPage) +{ + // FIXME: the DPI check should be removed when either (1) the test is fixed to work with + // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin. + if (!IsDefaultDPI()) + return; + // Given: copy the test document to a temporary file, as it'll be modified. + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + OUString aSourceURL + = m_directories.getURLFromSrc(DATA_DIRECTORY) + "add-visible-signature-last-page.pdf"; + OUString aURL = aTempFile.GetURL(); + osl::File::RC eRet = osl::File::copy(aSourceURL, aURL); + CPPUNIT_ASSERT_EQUAL(osl::File::RC::E_None, eRet); + + // Open it. + uno::Sequence<beans::PropertyValue> aArgs = { comphelper::makePropertyValue("ReadOnly", true) }; + getComponent() = loadFromDesktop(aURL, "com.sun.star.drawing.DrawingDocument", aArgs); + SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(getComponent().get()); + CPPUNIT_ASSERT(pBaseModel); + SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell(); + CPPUNIT_ASSERT(pObjectShell); + + // Add a signature line to the 2nd page. + uno::Reference<lang::XMultiServiceFactory> xFactory(getComponent(), uno::UNO_QUERY); + uno::Reference<drawing::XShape> xShape( + xFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY); + xShape->setPosition(awt::Point(1000, 15000)); + xShape->setSize(awt::Size(10000, 10000)); + uno::Reference<drawing::XDrawPagesSupplier> xSupplier(getComponent(), uno::UNO_QUERY); + uno::Reference<drawing::XDrawPages> xDrawPages = xSupplier->getDrawPages(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xDrawPages->getCount()); + + uno::Reference<frame::XModel> xModel(getComponent(), uno::UNO_QUERY); + uno::Reference<drawing::XDrawView> xController(xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(1), uno::UNO_QUERY); + xController->setCurrentPage(xDrawPage); + xDrawPage->add(xShape); + + // Select it and assign a certificate. + uno::Reference<view::XSelectionSupplier> xSelectionSupplier(pBaseModel->getCurrentController(), + uno::UNO_QUERY); + xSelectionSupplier->select(uno::Any(xShape)); + auto xCert = GetValidCertificate( + getSecurityContext()->getSecurityEnvironment()->getPersonalCertificates()); + if (!xCert) + { + return; + } + SdrView* pView = SfxViewShell::Current()->GetDrawView(); + svx::SignatureLineHelper::setShapeCertificate(pView, xCert); + + // When: do the actual signing. + pObjectShell->SignDocumentContentUsingCertificate(xCert); + + // Then: count the # of shapes on the signature widget/annotation. + std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); + if (!pPDFium) + return; + SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ); + SvMemoryStream aMemory; + aMemory.WriteStream(aFile); + // Last page. + std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument + = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), OString()); + std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/1); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // i.e. the signature was there, but it was on the first page. + CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getAnnotationCount()); + std::unique_ptr<vcl::pdf::PDFiumAnnotation> pAnnot = pPdfPage->getAnnotation(0); + CPPUNIT_ASSERT_EQUAL(4, pAnnot->getObjectCount()); +} + +CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testDictArrayDict) +{ + // Load a file that has markup like this: + // 3 0 obj << + // /Key[<</InnerKey 42>>] + // >> + OUString aSourceURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "dict-array-dict.pdf"; + SvFileStream aFile(aSourceURL, StreamMode::READ); + vcl::filter::PDFDocument aDocument; + CPPUNIT_ASSERT(aDocument.Read(aFile)); + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT(!aPages.empty()); + vcl::filter::PDFObjectElement* pPage = aPages[0]; + auto pKey = dynamic_cast<vcl::filter::PDFArrayElement*>(pPage->Lookup("Key")); + + // Without the accompanying fix in place, this test would have failed, because the value of Key + // was a dictionary element, not an array element. + CPPUNIT_ASSERT(pKey); +} + +CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testRealNumbers) +{ + // Load a file that has markup like this: + // 4 0 obj << + // /Test [.00 1.00 .00 1.00 .00 1.00] + // >> + OUString aSourceURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "real-numbers.pdf"; + SvFileStream aFile(aSourceURL, StreamMode::READ); + vcl::filter::PDFDocument aDocument; + + // Without the accompanying fix in place, this test would have failed, because the parser + // stopped when it saw an unexpected "." character. + CPPUNIT_ASSERT(aDocument.Read(aFile)); + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT(!aPages.empty()); +} + +CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testCommentEnd) +{ + // Load the test document: + // - it has two xrefs + // - second xref has an updated page content object with an indirect length + // - last startxref refers to the first xref + // - first xref has a /Prev to the second xref + // - first xref is terminated by a \r, which is not followed by a newline + // this means that if reading doesn't stop at the end of the first xref, then we'll try to look + // up the offset of the length object, which we don't yet have + OUString aSourceURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "comment-end.pdf"; + SvFileStream aFile(aSourceURL, StreamMode::READ); + vcl::filter::PDFDocument aDocument; + + // Without the accompanying fix in place, this test would have failed, because Tokenize() didn't + // stop at the end of the first xref. + CPPUNIT_ASSERT(aDocument.Read(aFile)); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |