[poppler] poppler/PDFDoc.cc poppler/PDFDoc.h qt4/src qt5/src utils/pdfunite.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Aug 31 15:16:16 PDT 2015


 poppler/PDFDoc.cc                |   33 +++++++++++++++++++--------------
 poppler/PDFDoc.h                 |   11 ++++++-----
 qt4/src/poppler-pdf-converter.cc |   14 +++++++++++++-
 qt4/src/poppler-qt4.h            |    4 +++-
 qt5/src/poppler-pdf-converter.cc |   14 +++++++++++++-
 qt5/src/poppler-qt5.h            |    4 +++-
 utils/pdfunite.cc                |    3 ++-
 7 files changed, 59 insertions(+), 24 deletions(-)

New commits:
commit a42614284c94c6742b2343abd797657fffa80e0e
Author: Adam Reichold <adam.reichold at t-online.de>
Date:   Tue Sep 1 00:15:46 2015 +0200

    Add option to strip encryption
    
    Adds a PDF write mode that forces a complete rewrite that ignores the original
    encryption parameters of the document and also removes the encryption entry
    from the trailer dictionary.

diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 46c4544..153dc75 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -29,7 +29,7 @@
 // Copyright (C) 2011-2015 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso at hotmail.it>
 // Copyright (C) 2013, 2014 Adrian Johnson <ajohnson at redneon.com>
-// Copyright (C) 2013 Adam Reichold <adamreichold at myopera.com>
+// Copyright (C) 2013, 2015 Adam Reichold <adamreichold at myopera.com>
 // Copyright (C) 2014 Bogdan Cristea <cristeab at gmail.com>
 // Copyright (C) 2015 Li Junling <lijunling at sina.com>
 //
@@ -763,7 +763,7 @@ int PDFDoc::savePageAs(GooString *name, int pageNo)
   Ref ref;
   ref.num = rootNum;
   ref.gen = 0;
-  Dict *trailerDict = createTrailerDict(rootNum + 3, gFalse, 0, &ref, getXRef(),
+  Dict *trailerDict = createTrailerDict(rootNum + 3, gFalse, gFalse, 0, &ref, getXRef(),
                                         name->getCString(), uxrefOffset);
   writeXRefTableTrailer(trailerDict, yRef, gFalse /* do not write unnecessary entries */,
                         uxrefOffset, outStr, getXRef());
@@ -809,7 +809,10 @@ int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) {
     // simply copy the original file
     saveWithoutChangesAs (outStr);
   } else if (mode == writeForceRewrite) {
-    saveCompleteRewrite(outStr);
+    saveCompleteRewrite(outStr, false);
+  } else if (mode == writeStripEncryption) {
+    // do a complete rewrite ignoring the original encryption parameters
+    saveCompleteRewrite(outStr, true);
   } else {
     saveIncrementalUpdate(outStr);
   }
@@ -916,7 +919,7 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr)
     uxref->add(uxrefStreamRef.num, uxrefStreamRef.gen, uxrefOffset, gTrue);
   }
 
-  Dict *trailerDict = createTrailerDict(numobjects, gTrue, getStartXRef(), &rootRef, getXRef(), fileNameA, uxrefOffset);
+  Dict *trailerDict = createTrailerDict(numobjects, gTrue, gFalse, getStartXRef(), &rootRef, getXRef(), fileNameA, uxrefOffset);
   if (xRefStream) {
     writeXRefStreamTrailer(trailerDict, uxref, &uxrefStreamRef, uxrefOffset, outStr, getXRef());
   } else {
@@ -927,16 +930,18 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr)
   delete uxref;
 }
 
-void PDFDoc::saveCompleteRewrite (OutStream* outStr)
+void PDFDoc::saveCompleteRewrite (OutStream* outStr, GBool stripEncryption)
 {
   // Make sure that special flags are set, because we are going to read
   // all objects, including Unencrypted ones.
   xref->scanSpecialFlags();
 
-  Guchar *fileKey;
-  CryptAlgorithm encAlgorithm;
-  int keyLength;
-  xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
+  Guchar *fileKey = NULL;
+  CryptAlgorithm encAlgorithm = cryptRC4;
+  int keyLength = 0;
+
+  if (!stripEncryption)
+    xref->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
 
   outStr->printf("%%PDF-%d.%d\r\n",pdfMajorVersion,pdfMinorVersion);
   XRef *uxref = new XRef();
@@ -986,7 +991,7 @@ void PDFDoc::saveCompleteRewrite (OutStream* outStr)
   xref->unlock();
   Goffset uxrefOffset = outStr->getPos();
   writeXRefTableTrailer(uxrefOffset, uxref, gTrue /* write all entries */,
-                        uxref->getNumObjects(), outStr, gFalse /* complete rewrite */);
+                        uxref->getNumObjects(), outStr, gFalse /* complete rewrite */, stripEncryption);
   delete uxref;
 }
 
@@ -1269,7 +1274,7 @@ void PDFDoc::writeObjectFooter (OutStream* outStr)
   outStr->printf("endobj\r\n");
 }
 
-Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxRef,
+Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, GBool stripEncryption, Goffset startxRef,
                                 Ref *root, XRef *xRef, const char *fileName, Goffset fileSize)
 {
   Dict *trailerDict = new Dict(xRef);
@@ -1308,7 +1313,7 @@ Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxR
   obj1.free();
 
   GBool hasEncrypt = gFalse;
-  if (!xRef->getTrailerDict()->isNone()) {
+  if (!stripEncryption && !xRef->getTrailerDict()->isNone()) {
     Object obj2;
     xRef->getTrailerDict()->dictLookupNF("Encrypt", &obj2);
     if (!obj2.isNull()) {
@@ -1401,7 +1406,7 @@ void PDFDoc::writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefS
 }
 
 void PDFDoc::writeXRefTableTrailer(Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries,
-                                   int uxrefSize, OutStream* outStr, GBool incrUpdate)
+                                   int uxrefSize, OutStream* outStr, GBool incrUpdate, GBool stripEncryption)
 {
   const char *fileNameA = fileName ? fileName->getCString() : NULL;
   // file size (doesn't include the trailer)
@@ -1415,7 +1420,7 @@ void PDFDoc::writeXRefTableTrailer(Goffset uxrefOffset, XRef *uxref, GBool write
   Ref ref;
   ref.num = getXRef()->getRootNum();
   ref.gen = getXRef()->getRootGen();
-  Dict * trailerDict = createTrailerDict(uxrefSize, incrUpdate, getStartXRef(), &ref,
+  Dict * trailerDict = createTrailerDict(uxrefSize, incrUpdate, stripEncryption, getStartXRef(), &ref,
                                          getXRef(), fileNameA, fileSize);
   writeXRefTableTrailer(trailerDict, uxref, writeAllEntries, uxrefOffset, outStr, getXRef());
   delete trailerDict;
diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h
index 6c40f7b..d4a8b5e 100644
--- a/poppler/PDFDoc.h
+++ b/poppler/PDFDoc.h
@@ -25,7 +25,7 @@
 // Copyright (C) 2011, 2013, 2014 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2012 Fabio D'Urso <fabiodurso at hotmail.it>
 // Copyright (C) 2013 Adrian Johnson <ajohnson at redneon.com>
-// Copyright (C) 2013 Adam Reichold <adamreichold at myopera.com>
+// Copyright (C) 2013, 2015 Adam Reichold <adamreichold at myopera.com>
 // Copyright (C) 2013 Adrian Perez de Castro <aperez at igalia.com>
 //
 // To see a description of the changes please see the Changelog file that
@@ -66,7 +66,8 @@ class StructTreeRoot;
 enum PDFWriteMode {
   writeStandard,
   writeForceRewrite,
-  writeForceIncremental
+  writeForceIncremental,
+  writeStripEncryption
 };
 
 //------------------------------------------------------------------------
@@ -258,7 +259,7 @@ public:
   static void writeHeader(OutStream *outStr, int major, int minor);
 
   // Ownership goes to the caller
-  static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef,
+  static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, GBool stripEncryption, Goffset startxRef,
                                   Ref *root, XRef *xRef, const char *fileName, Goffset fileSize);
   static void writeXRefTableTrailer (Dict *trailerDict, XRef *uxref, GBool writeAllEntries,
                                      Goffset uxrefOffset, OutStream* outStr, XRef *xRef);
@@ -285,11 +286,11 @@ private:
   static void writeStream (Stream* str, OutStream* outStr);
   static void writeRawStream (Stream* str, OutStream* outStr);
   void writeXRefTableTrailer (Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries,
-                              int uxrefSize, OutStream* outStr, GBool incrUpdate);
+                              int uxrefSize, OutStream* outStr, GBool incrUpdate, GBool stripEncryption);
   static void writeString (GooString* s, OutStream* outStr, Guchar *fileKey,
                            CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
   void saveIncrementalUpdate (OutStream* outStr);
-  void saveCompleteRewrite (OutStream* outStr);
+  void saveCompleteRewrite (OutStream* outStr, GBool stripEncryption);
 
   Page *parsePage(int page);
 
diff --git a/qt4/src/poppler-pdf-converter.cc b/qt4/src/poppler-pdf-converter.cc
index 9699b75..362d56c 100644
--- a/qt4/src/poppler-pdf-converter.cc
+++ b/qt4/src/poppler-pdf-converter.cc
@@ -1,6 +1,7 @@
 /* poppler-pdf-converter.cc: qt4 interface to poppler
  * Copyright (C) 2008, Pino Toscano <pino at kde.org>
  * Copyright (C) 2008, 2009, Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2015 Adam Reichold <adamreichold at myopera.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -92,7 +93,18 @@ bool PDFConverter::convert()
 	QIODeviceOutStream stream(dev);
 	if (d->opts & WithChanges)
 	{
-		errorCode = d->document->doc->saveAs(&stream);
+		PDFWriteMode mode = writeStandard;
+
+		if (d->opts & StripEncryption)
+		{
+			mode = writeStripEncryption;
+		}
+		else if (d->opts & ForceRewrite)
+		{
+			mode = writeForceRewrite;
+		}
+
+		errorCode = d->document->doc->saveAs(&stream, mode);
 	}
 	else
 	{
diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h
index c0340a4..bf7d05c 100644
--- a/qt4/src/poppler-qt4.h
+++ b/qt4/src/poppler-qt4.h
@@ -1668,7 +1668,9 @@ height = dummy.height();
               Options for the PDF export.
              */
             enum PDFOption {
-                WithChanges = 0x00000001        ///< The changes done to the document are saved as well
+                WithChanges = 0x00000001,       ///< The changes done to the document are saved as well
+                ForceRewrite = 0x00000002,      ///< The document is rewritten instead of update incrementally (only applicable if WithChanges is also set) \since 0.36
+                StripEncryption = 0x00000004    ///< The document is saved without encryption (only applicable if WithChanges is also set and implies ForceRewrite) \since 0.36
             };
             Q_DECLARE_FLAGS( PDFOptions, PDFOption )
 
diff --git a/qt5/src/poppler-pdf-converter.cc b/qt5/src/poppler-pdf-converter.cc
index 557a9f8..0a8588c 100644
--- a/qt5/src/poppler-pdf-converter.cc
+++ b/qt5/src/poppler-pdf-converter.cc
@@ -1,6 +1,7 @@
 /* poppler-pdf-converter.cc: qt interface to poppler
  * Copyright (C) 2008, Pino Toscano <pino at kde.org>
  * Copyright (C) 2008, 2009, Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2015 Adam Reichold <adamreichold at myopera.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -92,7 +93,18 @@ bool PDFConverter::convert()
 	QIODeviceOutStream stream(dev);
 	if (d->opts & WithChanges)
 	{
-		errorCode = d->document->doc->saveAs(&stream);
+		PDFWriteMode mode = writeStandard;
+
+		if (d->opts & StripEncryption)
+		{
+			mode = writeStripEncryption;
+		}
+		else if (d->opts & ForceRewrite)
+		{
+			mode = writeForceRewrite;
+		}
+
+		errorCode = d->document->doc->saveAs(&stream, mode);
 	}
 	else
 	{
diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h
index b159477..53fcf51 100644
--- a/qt5/src/poppler-qt5.h
+++ b/qt5/src/poppler-qt5.h
@@ -1629,7 +1629,9 @@ height = dummy.height();
               Options for the PDF export.
              */
             enum PDFOption {
-                WithChanges = 0x00000001        ///< The changes done to the document are saved as well
+                WithChanges = 0x00000001,       ///< The changes done to the document are saved as well
+                ForceRewrite = 0x00000002,      ///< The document is rewritten instead of update incrementally (only applicable if WithChanges is also set) \since 0.36
+                StripEncryption = 0x00000004    ///< The document is saved without encryption (only applicable if WithChanges is also set and implies ForceRewrite) \since 0.36
             };
             Q_DECLARE_FLAGS( PDFOptions, PDFOption )
 
diff --git a/utils/pdfunite.cc b/utils/pdfunite.cc
index 19a1eb5..9aa80be 100644
--- a/utils/pdfunite.cc
+++ b/utils/pdfunite.cc
@@ -11,6 +11,7 @@
 // Copyright (C) 2013 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2013 Hib Eris <hib at hiberis.nl>
 // Copyright (C) 2015 Arthur Stavisky <vovodroid at gmail.com>
+// Copyright (C) 2015 Adam Reichold <adamreichold at myopera.com>
 //
 //========================================================================
 
@@ -450,7 +451,7 @@ int main (int argc, char *argv[])
   Ref ref;
   ref.num = rootNum;
   ref.gen = 0;
-  Dict *trailerDict = PDFDoc::createTrailerDict(objectsCount, gFalse, 0, &ref, yRef,
+  Dict *trailerDict = PDFDoc::createTrailerDict(objectsCount, gFalse, gFalse, 0, &ref, yRef,
                                                 fileName, outStr->getPos());
   PDFDoc::writeXRefTableTrailer(trailerDict, yRef, gTrue, // write all entries according to ISO 32000-1, 7.5.4 Cross-Reference Table: "For a file that has never been incrementally updated, the cross-reference section shall contain only one subsection, whose object numbering begins at 0."
                                 uxrefOffset, outStr, yRef);


More information about the poppler mailing list