desktop/qa/desktop_lib/test_desktop_lib.cxx      |    2 
 include/vcl/filter/PDFiumLibrary.hxx             |    4 +
 include/vcl/filter/pdfdocument.hxx               |    2 
 include/vcl/filter/pdfobjectcontainer.hxx        |    4 +
 sc/qa/extras/scpdfexport.cxx                     |    6 +-
 sd/qa/unit/SdrPdfImportTest.cxx                  |    5 +-
 svx/source/svdraw/svdpdf.cxx                     |    2 
 sw/qa/core/text/text.cxx                         |    2 
 sw/qa/extras/uiwriter/uiwriter2.cxx              |    2 
 sw/qa/extras/uiwriter/uiwriter3.cxx              |    2 
 vcl/inc/pdf/pdfwriter_impl.hxx                   |    4 -
 vcl/qa/cppunit/PDFiumLibraryTest.cxx             |   18 +++++--
 vcl/qa/cppunit/filter/ipdf/ipdf.cxx              |    2 
 vcl/qa/cppunit/pdfexport/data/rectangles.pdf     |   54 +++++++++++++++++++++++
 vcl/qa/cppunit/pdfexport/pdfexport.cxx           |   50 ++++++++++++++++++++-
 vcl/source/filter/ipdf/pdfread.cxx               |    8 ++-
 vcl/source/gdi/pdfobjectcopier.cxx               |   29 +++++++++---
 vcl/source/gdi/pdfwriter_impl.cxx                |   32 ++++++++++++-
 vcl/source/graphic/VectorGraphicSearch.cxx       |    3 -
 vcl/source/pdf/PDFiumLibrary.cxx                 |   13 ++++-
 xmlsecurity/qa/unit/signing/signing.cxx          |    2 
 xmlsecurity/source/helper/pdfsignaturehelper.cxx |    4 -
 22 files changed, 209 insertions(+), 41 deletions(-)

New commits:
commit e6e8ac76faa3a65bfc9fc59d5308d9eec5d3bf97
Author:     Miklos Vajna <[email protected]>
AuthorDate: Wed Jul 20 08:16:57 2022 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Mon Jul 25 13:39:33 2022 +0200

    tdf#127236 vcl: fix missing encryption of PDF images during export
    
    Regression from commit 78e25558e86188314b9b72048b8ddca18697cb86
    (tdf#106059 PDF export: create a reference XObject for JPG images with
    PDF data, 2017-02-23), once a PDF image was inserted to a document, an
    encrypted PDF export lost those images.
    
    The reason for this is that we started to preserve PDF images as vector
    data with the above commit, but this means we copied over PDF objects
    from PDF images to the export result as-is, so encryption was not
    performed for them.
    
    Fix this by separating the write of the PDF object headers, stream
    content and object footer and then calling
    checkAndEnableStreamEncryption() / disableStreamEncryption() for each
    object, even if it's not something our PDF export created but comes from
    a PDF image.
    
    Note that when existing PDF files are signed, PDF objects are also
    copied into a vcl::filter::PDFDocument, but such PDF images are never
    encrypted, so it's fine to have stub implementations in
    vcl::filter::PDFDocument.
    
    (cherry picked from commit 7d56dae3375dc0180aa6d20983b3f5f962302588)
    
    Conflicts:
            filter/qa/pdf.cxx
            svx/qa/unit/core.cxx
            vcl/qa/cppunit/pdfexport/pdfexport.cxx
    
    Change-Id: I2f74b9f51cd35b4319221532ca890e197bab9cf3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137358
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx 
b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 906fefac9466..ad0412251455 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -697,7 +697,7 @@ void DesktopLOKTest::testSaveAsJsonOptions()
     aMemory.WriteStream(aFile);
     std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     CPPUNIT_ASSERT(pPdfDocument);
     // Without the accompanying fix in place, this test would have failed with:
     // - Expected: 2
diff --git a/include/vcl/filter/PDFiumLibrary.hxx 
b/include/vcl/filter/PDFiumLibrary.hxx
index c5f1766f60c0..3a4d0d83faf6 100644
--- a/include/vcl/filter/PDFiumLibrary.hxx
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -55,7 +55,9 @@ public:
 
     virtual const OUString& getLastError() const = 0;
 
-    virtual std::unique_ptr<PDFiumDocument> openDocument(const void* pData, 
int nSize) = 0;
+    virtual std::unique_ptr<PDFiumDocument> openDocument(const void* pData, 
int nSize,
+                                                         const OString& 
rPassword)
+        = 0;
     virtual PDFErrorType getLastErrorCode() = 0;
     virtual std::unique_ptr<PDFiumBitmap> createBitmap(int nWidth, int 
nHeight, int nAlpha) = 0;
 };
diff --git a/include/vcl/filter/pdfdocument.hxx 
b/include/vcl/filter/pdfdocument.hxx
index aa0e8c67ea66..dd03029227d2 100644
--- a/include/vcl/filter/pdfdocument.hxx
+++ b/include/vcl/filter/pdfdocument.hxx
@@ -595,6 +595,8 @@ public:
     bool updateObject(sal_Int32 n) override;
     /// See vcl::PDFObjectContainer::writeBuffer().
     bool writeBuffer(const void* pBuffer, sal_uInt64 nBytes) override;
+    void checkAndEnableStreamEncryption(sal_Int32 /*nObject*/) override {}
+    void disableStreamEncryption() override {}
 };
 
 /// The trailer singleton is at the end of the doc.
diff --git a/include/vcl/filter/pdfobjectcontainer.hxx 
b/include/vcl/filter/pdfobjectcontainer.hxx
index ca4898737e10..f6614f09ea3d 100644
--- a/include/vcl/filter/pdfobjectcontainer.hxx
+++ b/include/vcl/filter/pdfobjectcontainer.hxx
@@ -28,6 +28,10 @@ public:
     // Write pBuffer to the end of the output.
     virtual bool writeBuffer(const void* pBuffer, sal_uInt64 nBytes) = 0;
 
+    virtual void checkAndEnableStreamEncryption(sal_Int32 nObject) = 0;
+
+    virtual void disableStreamEncryption() = 0;
+
 protected:
     ~PDFObjectContainer() noexcept = default;
 };
diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx
index a0613de74e9a..8af237856260 100644
--- a/sc/qa/extras/scpdfexport.cxx
+++ b/sc/qa/extras/scpdfexport.cxx
@@ -481,7 +481,7 @@ void ScPDFExportTest::testTdf143978()
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     CPPUNIT_ASSERT(pPdfDocument);
     CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
 
@@ -528,7 +528,7 @@ void ScPDFExportTest::testTdf84012()
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     CPPUNIT_ASSERT(pPdfDocument);
     CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
 
@@ -569,7 +569,7 @@ void ScPDFExportTest::testTdf78897()
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     CPPUNIT_ASSERT(pPdfDocument);
     CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
 
diff --git a/sd/qa/unit/SdrPdfImportTest.cxx b/sd/qa/unit/SdrPdfImportTest.cxx
index e35b83b82373..ba3c42e92d46 100644
--- a/sd/qa/unit/SdrPdfImportTest.cxx
+++ b/sd/qa/unit/SdrPdfImportTest.cxx
@@ -216,7 +216,7 @@ CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, 
testAnnotationsImportExport)
         CPPUNIT_ASSERT_EQUAL(false, aContainer.isEmpty());
 
         auto pPDFDocument
-            = pPdfiumLibrary->openDocument(aContainer.getData(), 
aContainer.getSize());
+            = pPdfiumLibrary->openDocument(aContainer.getData(), 
aContainer.getSize(), OString());
         auto pPDFPage = pPDFDocument->openPage(0);
 
         CPPUNIT_ASSERT_EQUAL(2, pPDFPage->getAnnotationCount());
@@ -248,7 +248,8 @@ CPPUNIT_TEST_FIXTURE(SdrPdfImportTest, 
testAnnotationsImportExport)
         aMemory.WriteStream(aFile);
 
         // Check PDF for annotations
-        auto pPDFDocument = pPdfiumLibrary->openDocument(aMemory.GetData(), 
aMemory.GetSize());
+        auto pPDFDocument
+            = pPdfiumLibrary->openDocument(aMemory.GetData(), 
aMemory.GetSize(), OString());
         CPPUNIT_ASSERT(pPDFDocument);
         CPPUNIT_ASSERT_EQUAL(1, pPDFDocument->getPageCount());
 
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 4fcfb21fca7a..c497ea63ef6f 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -120,7 +120,7 @@ ImpSdrPdfImport::ImpSdrPdfImport(SdrModel& rModel, 
SdrLayerID nLay, const tools:
     auto const& rVectorGraphicData = rGraphic.getVectorGraphicData();
     auto* pData = rVectorGraphicData->getBinaryDataContainer().getData();
     sal_Int32 nSize = rVectorGraphicData->getBinaryDataContainer().getSize();
-    mpPdfDocument = mpPDFium->openDocument(pData, nSize);
+    mpPdfDocument = mpPDFium->openDocument(pData, nSize, OString());
     if (!mpPdfDocument)
         return;
 
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index f43727ed5f3f..68a8230a7bfc 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -124,7 +124,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, 
testBibliographyUrlPdfExport)
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     CPPUNIT_ASSERT(pPdfDocument);
     std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = 
pPdfDocument->openPage(/*nIndex=*/0);
     // Without the accompanying fix in place, this test would have failed, the 
field was not
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 6db1b70051fc..c85e8e707a70 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -6101,7 +6101,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, 
testConditionalHiddenSectionIssue)
     SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
-    auto pPdfDocument = pPDFium->openDocument(aMemory.GetData(), 
aMemory.GetSize());
+    auto pPdfDocument = pPDFium->openDocument(aMemory.GetData(), 
aMemory.GetSize(), OString());
     CPPUNIT_ASSERT(pPdfDocument);
     auto pPdfPage = pPdfDocument->openPage(0);
     CPPUNIT_ASSERT(pPdfPage);
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx 
b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 068a14113a0b..ce5d10e67f08 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -2471,7 +2471,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf145584)
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     CPPUNIT_ASSERT(pPdfDocument);
     CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
     std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = 
pPdfDocument->openPage(/*nIndex=*/0);
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index f6a9bba96f6a..5fc1e34863ba 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -794,9 +794,9 @@ i12626
     void addRoleMap(OString aAlias, PDFWriter::StructElement eType);
 
     /* this function implements part of the PDF spec algorithm 3.1 in 
encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */
-    void checkAndEnableStreamEncryption( sal_Int32 nObject );
+    void checkAndEnableStreamEncryption( sal_Int32 nObject ) override;
 
-    void disableStreamEncryption() { m_bEncryptThisStream = false; };
+    void disableStreamEncryption() override { m_bEncryptThisStream = false; };
 
     /* */
     void enableStringEncryption( sal_Int32 nObject );
diff --git a/vcl/qa/cppunit/PDFiumLibraryTest.cxx 
b/vcl/qa/cppunit/PDFiumLibraryTest.cxx
index 9ba40c438f50..1f82f24acccf 100644
--- a/vcl/qa/cppunit/PDFiumLibraryTest.cxx
+++ b/vcl/qa/cppunit/PDFiumLibraryTest.cxx
@@ -70,7 +70,8 @@ void PDFiumLibraryTest::testDocument()
 
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
     CPPUNIT_ASSERT(pPdfium);
-    auto pDocument = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize());
+    auto pDocument
+        = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize(), OString());
     CPPUNIT_ASSERT(pDocument);
 
     CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
@@ -95,7 +96,8 @@ void PDFiumLibraryTest::testPages()
     auto& rDataContainer = pVectorGraphicData->getBinaryDataContainer();
 
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
-    auto pDocument = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize());
+    auto pDocument
+        = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize(), OString());
     CPPUNIT_ASSERT(pDocument);
 
     CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
@@ -119,7 +121,8 @@ void PDFiumLibraryTest::testPageObjects()
     auto& rDataContainer = pVectorGraphicData->getBinaryDataContainer();
 
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
-    auto pDocument = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize());
+    auto pDocument
+        = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize(), OString());
     CPPUNIT_ASSERT(pDocument);
 
     CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
@@ -171,7 +174,8 @@ void PDFiumLibraryTest::testAnnotationsMadeInEvince()
     auto& rDataContainer = pVectorGraphicData->getBinaryDataContainer();
 
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
-    auto pDocument = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize());
+    auto pDocument
+        = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize(), OString());
     CPPUNIT_ASSERT(pDocument);
 
     CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
@@ -226,7 +230,8 @@ void PDFiumLibraryTest::testAnnotationsMadeInAcrobat()
     auto& rDataContainer = pVectorGraphicData->getBinaryDataContainer();
 
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
-    auto pDocument = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize());
+    auto pDocument
+        = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize(), OString());
     CPPUNIT_ASSERT(pDocument);
 
     CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
@@ -337,7 +342,8 @@ void PDFiumLibraryTest::testAnnotationsDifferentTypes()
     auto& rDataContainer = pVectorGraphicData->getBinaryDataContainer();
 
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
-    auto pDocument = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize());
+    auto pDocument
+        = pPdfium->openDocument(rDataContainer.getData(), 
rDataContainer.getSize(), OString());
     CPPUNIT_ASSERT(pDocument);
 
     CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount());
diff --git a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx 
b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx
index 8ed49813e88b..2de6cd4889d5 100644
--- a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx
+++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx
@@ -134,7 +134,7 @@ CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, 
testPDFAddVisibleSignatureLastPage)
     aMemory.WriteStream(aFile);
     // Last page.
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = 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
diff --git a/vcl/qa/cppunit/pdfexport/data/rectangles.pdf 
b/vcl/qa/cppunit/pdfexport/data/rectangles.pdf
new file mode 100644
index 000000000000..6911d229aa06
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/rectangles.pdf
@@ -0,0 +1,54 @@
+%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
+>>
+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
+466
+%%EOF
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 24c482b5389c..89f23d338acf 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -66,7 +66,7 @@ protected:
     utl::TempFile maTempFile;
     SvMemoryStream maMemory;
     utl::MediaDescriptor aMediaDescriptor;
-    std::unique_ptr<vcl::pdf::PDFiumDocument> parseExport();
+    std::unique_ptr<vcl::pdf::PDFiumDocument> parseExport(const OString& 
rPassword = OString());
     std::shared_ptr<vcl::pdf::PDFium> mpPDFium;
 
 public:
@@ -79,13 +79,13 @@ public:
 
 PdfExportTest::PdfExportTest() { maTempFile.EnableKillingFile(); }
 
-std::unique_ptr<vcl::pdf::PDFiumDocument> PdfExportTest::parseExport()
+std::unique_ptr<vcl::pdf::PDFiumDocument> PdfExportTest::parseExport(const 
OString& rPassword)
 {
     SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
     maMemory.WriteStream(aFile);
     std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(maMemory.GetData(), maMemory.GetSize());
+        = pPDFium->openDocument(maMemory.GetData(), maMemory.GetSize(), 
rPassword);
     CPPUNIT_ASSERT(pPdfDocument);
     return pPdfDocument;
 }
@@ -3202,6 +3202,50 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testURIs)
         CPPUNIT_ASSERT_EQUAL(URIs[i].out, pURIElem->GetValue());
     }
 }
+
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfImageEncryption)
+{
+    // Given an empty document, with an inserted PDF image:
+    mxComponent = loadFromDesktop("private:factory/swriter");
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xTextDocument->getText();
+    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xGraphicObject(
+        xFactory->createInstance("com.sun.star.text.TextGraphicObject"), 
uno::UNO_QUERY);
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"rectangles.pdf";
+    xGraphicObject->setPropertyValue("GraphicURL", uno::Any(aURL));
+    uno::Reference<drawing::XShape> xShape(xGraphicObject, uno::UNO_QUERY);
+    xShape->setSize(awt::Size(1000, 1000));
+    uno::Reference<text::XTextContent> xTextContent(xGraphicObject, 
uno::UNO_QUERY);
+    xText->insertTextContent(xCursor->getStart(), xTextContent, 
/*bAbsorb=*/false);
+
+    // When saving as encrypted PDF:
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+    uno::Sequence<beans::PropertyValue> aFilterData = {
+        comphelper::makePropertyValue("EncryptFile", true),
+        comphelper::makePropertyValue("DocumentOpenPassword", 
OUString("secret")),
+    };
+    aMediaDescriptor["FilterData"] <<= aFilterData;
+    xStorable->storeToURL(maTempFile.GetURL(), 
aMediaDescriptor.getAsConstPropertyValueList());
+
+    // Then make sure that the image is not lost:
+    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = 
parseExport("secret");
+    CPPUNIT_ASSERT(pPdfDocument);
+    CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
+    std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = 
pPdfDocument->openPage(/*nIndex=*/0);
+    CPPUNIT_ASSERT(pPdfPage);
+    CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getObjectCount());
+    std::unique_ptr<vcl::pdf::PDFiumPageObject> pPageObject = 
pPdfPage->getObject(0);
+    CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFPageObjectType::Form, 
pPageObject->getType());
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2
+    // - Actual  : 0
+    // i.e. instead of the white background and the actual form child, the 
image was lost due to
+    // missing encryption.
+    CPPUNIT_ASSERT_EQUAL(2, pPageObject->getFormObjectCount());
+}
 } // end anonymous namespace
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/vcl/source/filter/ipdf/pdfread.cxx 
b/vcl/source/filter/ipdf/pdfread.cxx
index a69d10c7cafc..339ff5dac7fa 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -78,7 +78,7 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& 
rOutStream)
         {
             // Load the buffer using pdfium.
             std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-                = pPdfium->openDocument(aInBuffer.GetData(), 
aInBuffer.GetSize());
+                = pPdfium->openDocument(aInBuffer.GetData(), 
aInBuffer.GetSize(), OString());
             if (!pPdfDocument)
                 return false;
 
@@ -128,7 +128,8 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, 
std::vector<BitmapEx>& r
     }
 
     // Load the buffer using pdfium.
-    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = 
pPdfium->openDocument(pBuffer, nSize);
+    std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
+        = pPdfium->openDocument(pBuffer, nSize, OString());
     if (!pPdfDocument)
         return 0;
 
@@ -436,7 +437,8 @@ size_t ImportPDFUnloaded(const OUString& rURL, 
std::vector<PDFGraphicResult>& rG
     }
 
     // Load the buffer using pdfium.
-    auto pPdfDocument = pPdfium->openDocument(pGfxLink->GetData(), 
pGfxLink->GetDataSize());
+    auto pPdfDocument
+        = pPdfium->openDocument(pGfxLink->GetData(), pGfxLink->GetDataSize(), 
OString());
 
     if (!pPdfDocument)
         return 0;
diff --git a/vcl/source/gdi/pdfobjectcopier.cxx 
b/vcl/source/gdi/pdfobjectcopier.cxx
index 1cb6c209d699..93b7b4989710 100644
--- a/vcl/source/gdi/pdfobjectcopier.cxx
+++ b/vcl/source/gdi/pdfobjectcopier.cxx
@@ -113,12 +113,10 @@ sal_Int32 
PDFObjectCopier::copyExternalResource(SvMemoryStream& rDocBuffer,
         aLine.append(" >>\n");
     }
 
-    if (filter::PDFStreamElement* pStream = rObject.GetStream())
+    filter::PDFStreamElement* pStream = rObject.GetStream();
+    if (pStream)
     {
         aLine.append("stream\n");
-        SvMemoryStream& rStream = pStream->GetMemory();
-        aLine.append(static_cast<const char*>(rStream.GetData()), 
rStream.GetSize());
-        aLine.append("\nendstream\n");
     }
 
     if (filter::PDFArrayElement* pArray = rObject.GetArray())
@@ -146,13 +144,32 @@ sal_Int32 
PDFObjectCopier::copyExternalResource(SvMemoryStream& rDocBuffer,
         aLine.append("\n");
     }
 
-    aLine.append("endobj\n\n");
-
     // We have the whole object, now write it to the output.
     if (!m_rContainer.updateObject(nObject))
         return -1;
     if (!m_rContainer.writeBuffer(aLine.getStr(), aLine.getLength()))
         return -1;
+    aLine.setLength(0);
+
+    if (pStream)
+    {
+        SvMemoryStream& rStream = pStream->GetMemory();
+        m_rContainer.checkAndEnableStreamEncryption(nObject);
+        aLine.append(static_cast<const char*>(rStream.GetData()), 
rStream.GetSize());
+        if (!m_rContainer.writeBuffer(aLine.getStr(), aLine.getLength()))
+            return -1;
+        aLine.setLength(0);
+        m_rContainer.disableStreamEncryption();
+
+        aLine.append("\nendstream\n");
+        if (!m_rContainer.writeBuffer(aLine.getStr(), aLine.getLength()))
+            return -1;
+        aLine.setLength(0);
+    }
+
+    aLine.append("endobj\n\n");
+    if (!m_rContainer.writeBuffer(aLine.getStr(), aLine.getLength()))
+        return -1;
 
     return nObject;
 }
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 06daee9efadc..d38328855ce2 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -8596,16 +8596,34 @@ void PDFWriterImpl::writeReferenceXObject(const 
ReferenceXObjectEmit& rEmit)
         aLine.append(nLength);
 
         aLine.append(">>\nstream\n");
+        if (g_bDebugDisableCompression)
+        {
+            emitComment("PDFWriterImpl::writeReferenceXObject, 
WrappedFormObject");
+        }
+        if (!updateObject(nWrappedFormObject))
+            return;
+        if (!writeBuffer(aLine.getStr(), aLine.getLength()))
+            return;
+        aLine.setLength(0);
+
+        checkAndEnableStreamEncryption(nWrappedFormObject);
         // Copy the original page streams to the form XObject stream.
         aLine.append(static_cast<const char*>(aStream.GetData()), 
aStream.GetSize());
-        aLine.append("\nendstream\nendobj\n\n");
-        if (!updateObject(nWrappedFormObject))
+        if (!writeBuffer(aLine.getStr(), aLine.getLength()))
             return;
+        aLine.setLength(0);
+        disableStreamEncryption();
+
+        aLine.append("\nendstream\nendobj\n\n");
         if (!writeBuffer(aLine.getStr(), aLine.getLength()))
             return;
     }
 
     OStringBuffer aLine;
+    if (g_bDebugDisableCompression)
+    {
+        emitComment("PDFWriterImpl::writeReferenceXObject, FormObject");
+    }
     if (!updateObject(rEmit.m_nFormObject))
         return;
 
@@ -8684,7 +8702,17 @@ void PDFWriterImpl::writeReferenceXObject(const 
ReferenceXObjectEmit& rEmit)
     aLine.append(aStream.getLength());
 
     aLine.append(">>\nstream\n");
+    if (!writeBuffer(aLine.getStr(), aLine.getLength()))
+        return;
+    aLine.setLength(0);
+
+    checkAndEnableStreamEncryption(rEmit.m_nFormObject);
     aLine.append(aStream.getStr());
+    if (!writeBuffer(aLine.getStr(), aLine.getLength()))
+        return;
+    aLine.setLength(0);
+    disableStreamEncryption();
+
     aLine.append("\nendstream\nendobj\n\n");
     CHECK_RETURN2(writeBuffer(aLine.getStr(), aLine.getLength()));
 }
diff --git a/vcl/source/graphic/VectorGraphicSearch.cxx 
b/vcl/source/graphic/VectorGraphicSearch.cxx
index 710c6e5f52e6..63dae6e5277d 100644
--- a/vcl/source/graphic/VectorGraphicSearch.cxx
+++ b/vcl/source/graphic/VectorGraphicSearch.cxx
@@ -231,7 +231,8 @@ bool 
VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& rD
     }
 
     mpImplementation->mpPdfDocument = mpImplementation->mpPDFium->openDocument(
-        rData->getBinaryDataContainer().getData(), 
rData->getBinaryDataContainer().getSize());
+        rData->getBinaryDataContainer().getData(), 
rData->getBinaryDataContainer().getSize(),
+        OString());
 
     if (!mpImplementation->mpPdfDocument)
     {
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index e6abb40ccb89..643039f2359f 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -424,7 +424,8 @@ public:
 
     const OUString& getLastError() const override { return maLastError; }
 
-    std::unique_ptr<PDFiumDocument> openDocument(const void* pData, int nSize) 
override;
+    std::unique_ptr<PDFiumDocument> openDocument(const void* pData, int nSize,
+                                                 const OString& rPassword) 
override;
     PDFErrorType getLastErrorCode() override;
     std::unique_ptr<PDFiumBitmap> createBitmap(int nWidth, int nHeight, int 
nAlpha) override;
 };
@@ -442,12 +443,18 @@ PDFiumImpl::PDFiumImpl()
 
 PDFiumImpl::~PDFiumImpl() { FPDF_DestroyLibrary(); }
 
-std::unique_ptr<PDFiumDocument> PDFiumImpl::openDocument(const void* pData, 
int nSize)
+std::unique_ptr<PDFiumDocument> PDFiumImpl::openDocument(const void* pData, 
int nSize,
+                                                         const OString& 
rPassword)
 {
     maLastError = OUString();
     std::unique_ptr<PDFiumDocument> pPDFiumDocument;
 
-    FPDF_DOCUMENT pDocument = FPDF_LoadMemDocument(pData, nSize, 
/*password=*/nullptr);
+    FPDF_BYTESTRING pPassword = nullptr;
+    if (!rPassword.isEmpty())
+    {
+        pPassword = rPassword.getStr();
+    }
+    FPDF_DOCUMENT pDocument = FPDF_LoadMemDocument(pData, nSize, pPassword);
 
     if (!pDocument)
     {
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx 
b/xmlsecurity/qa/unit/signing/signing.cxx
index 38643a0b3098..aa5f77a72637 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -845,7 +845,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, 
testPDFAddVisibleSignature)
     SvMemoryStream aMemory;
     aMemory.WriteStream(aFile);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize());
+        = pPDFium->openDocument(aMemory.GetData(), aMemory.GetSize(), 
OString());
     std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = 
pPdfDocument->openPage(/*nIndex=*/0);
     CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getAnnotationCount());
     std::unique_ptr<vcl::pdf::PDFiumAnnotation> pAnnot = 
pPdfPage->getAnnotation(/*nIndex=*/0);
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx 
b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
index 5aa2088ea7fd..48d5c7f2db3a 100644
--- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
@@ -255,7 +255,7 @@ void AnalyizeSignatureStream(SvMemoryStream& rStream, 
std::vector<PageChecksum>&
 {
     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPdfium->openDocument(rStream.GetData(), rStream.GetSize());
+        = pPdfium->openDocument(rStream.GetData(), rStream.GetSize(), 
OString());
     if (!pPdfDocument)
     {
         return;
@@ -435,7 +435,7 @@ bool 
PDFSignatureHelper::ReadAndVerifySignatureSvStream(SvStream& rStream)
     aStream.WriteStream(rStream);
     rStream.Seek(nPos);
     std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
-        = pPdfium->openDocument(aStream.GetData(), aStream.GetSize());
+        = pPdfium->openDocument(aStream.GetData(), aStream.GetSize(), 
OString());
     if (!pPdfDocument)
     {
         SAL_WARN("xmlsecurity.helper", "failed to read the document");

Reply via email to