summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/pdf/pdfwriter_impl.hxx4
-rw-r--r--vcl/qa/cppunit/PDFiumLibraryTest.cxx18
-rw-r--r--vcl/qa/cppunit/filter/ipdf/ipdf.cxx2
-rw-r--r--vcl/qa/cppunit/pdfexport/data/rectangles.pdf54
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx50
-rw-r--r--vcl/source/filter/ipdf/pdfread.cxx8
-rw-r--r--vcl/source/gdi/pdfobjectcopier.cxx29
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx32
-rw-r--r--vcl/source/graphic/VectorGraphicSearch.cxx3
-rw-r--r--vcl/source/pdf/PDFiumLibrary.cxx13
10 files changed, 186 insertions, 27 deletions
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index 228df387fb6d..d718529476b9 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -807,9 +807,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 ca5460e63b48..b57ead0f6702 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 2531dab1a3f4..d77cc4a4b00d 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -68,7 +68,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:
@@ -81,13 +81,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;
}
@@ -3407,6 +3407,50 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfImageAnnots)
// i.e. not only the hyperlink but also the 2 comments were exported, leading to duplication.
CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getAnnotationCount());
}
+
+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 112aa411a67d..8510b0a0c207 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -79,7 +79,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;
@@ -441,7 +442,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 ae78eda251e5..f16bdc090f03 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -8659,16 +8659,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;
@@ -8747,7 +8765,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 d02e2a0bab49..b02358d43a9c 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -425,7 +425,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;
};
@@ -443,12 +444,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)
{