[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 2 commits - RepositoryExternal.mk vcl/source xmlsecurity/CppunitTest_xmlsecurity_signing.mk xmlsecurity/qa

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Jun 29 07:10:49 UTC 2020


 RepositoryExternal.mk                                      |    1 
 vcl/source/filter/ipdf/pdfdocument.cxx                     |   55 ++++++++-
 xmlsecurity/CppunitTest_xmlsecurity_signing.mk             |    3 
 xmlsecurity/qa/unit/signing/data/add-visible-signature.pdf |binary
 xmlsecurity/qa/unit/signing/signing.cxx                    |   76 +++++++++++++
 5 files changed, 131 insertions(+), 4 deletions(-)

New commits:
commit 5b7b7731a2d1941d39cd10c0b12dab427d2cea07
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jun 19 17:21:58 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Jun 29 09:10:30 2020 +0200

    sd signature line: add testcase
    
    Fails with commit 9b7a890fd59744459692d7f66402c6bdd25acec4 (sd signature
    line: include shape in the appearance widget, 2020-06-19) reverted.
    
    (cherry picked from commit fb8f0ef26d57986bd27c6c5088939c32453e6b06)
    
    Change-Id: Ib237774374553af5d37c9deaffdea6fae65a28f4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97252
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index f6003fc22aba..92dca6d4d04e 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -4135,6 +4135,7 @@ endef
 ifneq ($(ENABLE_PDFIUM),)
 define gb_LinkTarget__use_pdfium
 $(call gb_LinkTarget_set_include,$(1),\
+       -I$(call gb_UnpackedTarball_get_dir,pdfium) \
        -I$(call gb_UnpackedTarball_get_dir,pdfium)/public \
        $$(INCLUDE) \
 )
diff --git a/xmlsecurity/CppunitTest_xmlsecurity_signing.mk b/xmlsecurity/CppunitTest_xmlsecurity_signing.mk
index 84e7a76c043b..3554b3eaa468 100644
--- a/xmlsecurity/CppunitTest_xmlsecurity_signing.mk
+++ b/xmlsecurity/CppunitTest_xmlsecurity_signing.mk
@@ -22,16 +22,19 @@ $(eval $(call gb_CppunitTest_use_libraries,xmlsecurity_signing, \
 	sal \
 	sax \
 	sfx \
+	svx \
 	test \
 	tl \
 	unotest \
 	utl \
+	vcl \
 	xmlsecurity \
 ))
 
 $(eval $(call gb_CppunitTest_use_externals,xmlsecurity_signing,\
     boost_headers \
     libxml2 \
+    $(if $(filter PDFIUM,$(BUILD_TYPE)),pdfium) \
 ))
 
 $(eval $(call gb_CppunitTest_set_include,xmlsecurity_signing,\
diff --git a/xmlsecurity/qa/unit/signing/data/add-visible-signature.pdf b/xmlsecurity/qa/unit/signing/data/add-visible-signature.pdf
new file mode 100644
index 000000000000..8dedb6998b23
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/add-visible-signature.pdf differ
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index f2039b609e7e..04eb91e8822b 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -27,6 +27,8 @@
 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
 
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertysequence.hxx>
@@ -51,6 +53,16 @@
 #include <sfx2/docfilt.hxx>
 #include <officecfg/Office/Common.hxx>
 #include <comphelper/configuration.hxx>
+#include <svx/signaturelinehelper.hxx>
+#include <sfx2/viewsh.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/filter/PDFiumLibrary.hxx>
+
+#if HAVE_FEATURE_PDFIUM
+#include <fpdf_annot.h>
+#include <fpdfview.h>
+#include <cpp/fpdf_scopers.h>
+#endif
 
 using namespace com::sun::star;
 
@@ -629,6 +641,70 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testPDFNo)
                          static_cast<int>(pObjectShell->GetDocumentSignatureState()));
 }
 
+#if HAVE_FEATURE_PDFIUM
+CPPUNIT_TEST_FIXTURE(SigningTest, testPDFAddVisibleSignature)
+{
+    // 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.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) };
+    mxComponent = loadFromDesktop(aURL, "com.sun.star.drawing.DrawingDocument", aArgs);
+    SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+    CPPUNIT_ASSERT(pBaseModel);
+    SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+    CPPUNIT_ASSERT(pObjectShell);
+
+    // Add a signature line.
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, 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(mxComponent, uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPages> xDrawPages = xSupplier->getDrawPages();
+    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY);
+    xDrawPage->add(xShape);
+
+    // Select it and assign a certificate.
+    uno::Reference<view::XSelectionSupplier> xSelectionSupplier(pBaseModel->getCurrentController(),
+                                                                uno::UNO_QUERY);
+    xSelectionSupplier->select(uno::makeAny(xShape));
+    uno::Sequence<uno::Reference<security::XCertificate>> aCertificates
+        = mxSecurityContext->getSecurityEnvironment()->getPersonalCertificates();
+    if (!aCertificates.hasElements())
+    {
+        return;
+    }
+    SdrView* pView = SfxViewShell::Current()->GetDrawView();
+    svx::SignatureLineHelper::setShapeCertificate(pView, aCertificates[0]);
+
+    // When: do the actual signing.
+    pObjectShell->SignDocumentContentUsingCertificate(aCertificates[0]);
+
+    // Then: count the # of shapes on the signature widget/annotation.
+    std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+    SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ);
+    SvMemoryStream aMemory;
+    aMemory.WriteStream(aFile);
+    ScopedFPDFDocument pPdfDocument(
+        FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr));
+    ScopedFPDFPage pPdfPage(FPDF_LoadPage(pPdfDocument.get(), /*page_index=*/0));
+    CPPUNIT_ASSERT_EQUAL(1, FPDFPage_GetAnnotCount(pPdfPage.get()));
+    ScopedFPDFAnnotation pAnnot(FPDFPage_GetAnnot(pPdfPage.get(), 0));
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 4
+    // - Actual  : 0
+    // i.e. the signature was there, but it was empty / not visible.
+    CPPUNIT_ASSERT_EQUAL(4, FPDFAnnot_GetObjectCount(pAnnot.get()));
+}
+#endif
+
 #endif
 
 CPPUNIT_TEST_FIXTURE(SigningTest, test96097Calc)
commit e9ee1289b2307af3d0a6023f5c0fa01c92f3b26f
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jun 19 14:08:44 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Jun 29 09:10:16 2020 +0200

    sd signature line: include shape in the appearance widget
    
    With this, finally the following works:
    
    1) file -> digital signatures -> sign existing pdf
    
    2) file -> digital signatures -> signature line
    
    3) draw a rectangle
    
    4) popup appears, select signing certificate
    
    5) click on the "finish signing" button on the infobar
    
    The resulting pdf will have a signature on it, together with the pdf
    export of the signature line shape.
    
    (cherry picked from commit 9b7a890fd59744459692d7f66402c6bdd25acec4)
    
    Change-Id: Icef701aaa6fd4a625acb37094ad34b88283caf42
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97251
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index 85a5d19ca52f..401ea9ff1844 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -28,6 +28,8 @@
 #include <vcl/pdfwriter.hxx>
 #include <o3tl/safeint.hxx>
 
+#include <pdf/objectcopier.hxx>
+
 using namespace com::sun::star;
 
 namespace vcl
@@ -265,6 +267,10 @@ sal_Int32 PDFDocument::WriteSignatureObject(const OUString& rDescription, bool b
 
 sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectangle)
 {
+    PDFDocument aPDFDocument;
+    filter::PDFObjectElement* pPage = nullptr;
+    std::vector<filter::PDFObjectElement*> aContentStreams;
+
     if (!m_aSignatureLine.empty())
     {
         // Parse the PDF data of signature line: we can set the signature rectangle to non-empty
@@ -272,7 +278,6 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang
         SvMemoryStream aPDFStream;
         aPDFStream.WriteBytes(m_aSignatureLine.data(), m_aSignatureLine.size());
         aPDFStream.Seek(0);
-        filter::PDFDocument aPDFDocument;
         if (!aPDFDocument.Read(aPDFStream))
         {
             SAL_WARN("vcl.filter",
@@ -287,7 +292,7 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang
             return -1;
         }
 
-        filter::PDFObjectElement* pPage = aPages[0];
+        pPage = aPages[0];
         if (!pPage)
         {
             SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: no page");
@@ -318,6 +323,17 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang
             return -1;
         }
         rSignatureRectangle.setHeight(pHeight->GetValue());
+
+        if (PDFObjectElement* pContentStream = pPage->LookupObject("Contents"))
+        {
+            aContentStreams.push_back(pContentStream);
+        }
+
+        if (aContentStreams.empty())
+        {
+            SAL_WARN("vcl.filter", "PDFDocument::WriteAppearanceObject: no content stream");
+            return -1;
+        }
     }
     m_aSignatureLine.clear();
 
@@ -330,14 +346,45 @@ sal_Int32 PDFDocument::WriteAppearanceObject(tools::Rectangle& rSignatureRectang
     aEditBuffer.WriteUInt32AsString(nAppearanceId);
     aEditBuffer.WriteCharPtr(" 0 obj\n");
     aEditBuffer.WriteCharPtr("<</Type/XObject\n/Subtype/Form\n");
+
+    PDFObjectCopier aCopier(*this);
+    if (!aContentStreams.empty())
+    {
+        OStringBuffer aBuffer;
+        aCopier.copyPageResources(pPage, aBuffer);
+        aEditBuffer.WriteOString(aBuffer.makeStringAndClear());
+    }
+
     aEditBuffer.WriteCharPtr("/BBox[0 0 ");
     aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getWidth()));
     aEditBuffer.WriteCharPtr(" ");
     aEditBuffer.WriteOString(OString::number(rSignatureRectangle.getHeight()));
-    aEditBuffer.WriteCharPtr("]\n/Length 0\n>>\n");
-    aEditBuffer.WriteCharPtr("stream\n\nendstream\nendobj\n\n");
+    aEditBuffer.WriteCharPtr("]\n/Length ");
 
     // Add the object to the doc-level edit buffer and update the offset.
+    SvMemoryStream aStream;
+    bool bCompressed = false;
+    sal_Int32 nLength = 0;
+    if (!aContentStreams.empty())
+    {
+        nLength = PDFObjectCopier::copyPageStreams(aContentStreams, aStream, bCompressed);
+    }
+    aEditBuffer.WriteOString(OString::number(nLength));
+    if (bCompressed)
+    {
+        aEditBuffer.WriteOString(" /Filter/FlateDecode");
+    }
+
+    aEditBuffer.WriteCharPtr("\n>>\n");
+
+    aEditBuffer.WriteCharPtr("stream\n");
+
+    // Copy the original page streams to the form XObject stream.
+    aStream.Seek(0);
+    aEditBuffer.WriteStream(aStream);
+
+    aEditBuffer.WriteCharPtr("\nendstream\nendobj\n\n");
+
     aEditBuffer.Seek(0);
     XRefEntry aAppearanceEntry;
     aAppearanceEntry.SetOffset(m_aEditBuffer.Tell());


More information about the Libreoffice-commits mailing list