vcl/inc/pdf/pdfwriter_impl.hxx    |    2 
 vcl/source/gdi/pdfwriter_impl.cxx |  122 +++++++++++++++++++++++++++++---------
 2 files changed, 97 insertions(+), 27 deletions(-)

New commits:
commit b39ed7a2c9da9163343482579c79fe4217e88b75
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Oct 31 23:40:35 2024 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri Nov 8 08:31:48 2024 +0100

    pdf: move encrypt code into emitEncrypt, add PDFStructureWriter
    
    Move the encryption code into emitEncrypt and rewrite that with
    the newly introduced PDFStructureWriter, which is now responsible
    to write the PDF basic structure elements into a string buffer.
    
    The PDFStructureWriter will be extended with new features when
    there is demand.
    
    Change-Id: I4f4099886860b72b4f1866b19a8afb7cc8fb4ea4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175923
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index 525d600183b2..2d528af29d87 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -1010,6 +1010,8 @@ i12626
     // creates a PKCS7 object using the ByteRange and overwrite /Contents
     // of the signature dictionary
     bool finalizeSignature();
+    //writes encrypt
+    sal_Int32 emitEncrypt();
     // writes xref and trailer
     bool emitTrailer();
     // emits info dict (if applicable)
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 7a91cadd3ed1..c44ad77acd47 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -275,6 +275,67 @@ void appendDestinationName( const OUString& rString, 
OStringBuffer& rBuffer )
     }
 }
 
+/** Writes the PDF structure to the string buffer.
+ *
+ * Structure elements like: objects, IDs, dictionaries, key/values, ...
+ *
+ */
+class PDFStructureWriter
+{
+    OStringBuffer maLine;
+public:
+    PDFStructureWriter()
+        : maLine(1024)
+    {
+    }
+
+    void startObject(sal_Int32 nID)
+    {
+        appendObjectID(nID, maLine);
+    }
+
+    void endObject()
+    {
+        maLine.append("endobj

");
+    }
+
+    OStringBuffer& getLine()
+    {
+        return maLine;
+    }
+
+    void startDict()
+    {
+        maLine.append("<<");
+    }
+
+    void endDict()
+    {
+        maLine.append(">>
");
+    }
+
+    void write(std::string_view key, std::string_view value)
+    {
+        maLine.append(key);
+        maLine.append(value);
+    }
+
+    void write(std::string_view key, sal_Int32 value)
+    {
+        maLine.append(key);
+        maLine.append(" ");
+        maLine.append(value);
+    }
+
+    void writeString(std::string_view key, char* pString, sal_Int32 nSize)
+    {
+        maLine.append(key);
+        maLine.append(" (");
+        appendLiteralString(pString, nSize, maLine);
+        maLine.append(")");
+    }
+};
+
 } // end anonymous namespace
 
 namespace vcl
@@ -6031,6 +6092,39 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata()
     return nObject;
 }
 
+sal_Int32 PDFWriterImpl::emitEncrypt()
+{
+    //emit the security information
+    //must be emitted as indirect dictionary object, since
+    //Acrobat Reader 5 works only with this kind of implementation
+
+    sal_Int32 nObject = createObject();
+
+    if (updateObject(nObject))
+    {
+        PDFStructureWriter aWriter;
+        aWriter.startObject(nObject);
+        aWriter.startDict();
+        aWriter.write("/Filter", "/Standard");
+        aWriter.write("/V", 2);
+        aWriter.write("/Length", 128);
+        aWriter.write("/R", 3);
+        // emit the owner password, must not be encrypted
+        aWriter.writeString("/O", 
reinterpret_cast<char*>(m_aContext.Encryption.OValue.data()), 
sal_Int32(m_aContext.Encryption.OValue.size()));
+        aWriter.writeString("/U", 
reinterpret_cast<char*>(m_aContext.Encryption.UValue.data()), 
sal_Int32(m_aContext.Encryption.UValue.size()));
+        aWriter.write("/P", m_nAccessPermissions);
+        aWriter.endDict();
+        aWriter.endObject();
+
+        if (!writeBuffer(aWriter.getLine()))
+            nObject = 0;
+    }
+    else
+        nObject = 0;
+
+    return nObject;
+}
+
 bool PDFWriterImpl::emitTrailer()
 {
     // emit doc info
@@ -6040,33 +6134,7 @@ bool PDFWriterImpl::emitTrailer()
 
     if( m_aContext.Encryption.Encrypt() )
     {
-        //emit the security information
-        //must be emitted as indirect dictionary object, since
-        //Acrobat Reader 5 works only with this kind of implementation
-        nSecObject = createObject();
-
-        if( updateObject( nSecObject ) )
-        {
-            OStringBuffer aLineS( 1024 );
-            aLineS.append( nSecObject );
-            aLineS.append( " 0 obj
"
-                           "<</Filter/Standard/V " );
-            // check the version
-            aLineS.append( "2/Length 128/R 3" );
-
-            // emit the owner password, must not be encrypted
-            aLineS.append( "/O(" );
-            appendLiteralString( 
reinterpret_cast<char*>(m_aContext.Encryption.OValue.data()), 
sal_Int32(m_aContext.Encryption.OValue.size()), aLineS );
-            aLineS.append( ")/U(" );
-            appendLiteralString( 
reinterpret_cast<char*>(m_aContext.Encryption.UValue.data()), 
sal_Int32(m_aContext.Encryption.UValue.size()), aLineS );
-            aLineS.append( ")/P " );// the permission set
-            aLineS.append( m_nAccessPermissions );
-            aLineS.append( ">>
endobj

" );
-            if( !writeBuffer( aLineS ) )
-                nSecObject = 0;
-        }
-        else
-            nSecObject = 0;
+        nSecObject = emitEncrypt();
     }
     // emit xref table
     // remember start

Reply via email to