2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-02 10:20:52 +00:00

Avoid modifying trailer when writing

When preparing the trailer for writing to the new file, trim a copy of
the trailer instead of the original file's trailer.
This commit is contained in:
Jay Berkenbilt 2012-12-31 05:50:43 -05:00
parent 0ea70e5dae
commit 9eb5982fa3
2 changed files with 16 additions and 10 deletions

View File

@ -322,6 +322,7 @@ class QPDFWriter
void setDataKey(int objid); void setDataKey(int objid);
int openObject(int objid = 0); int openObject(int objid = 0);
void closeObject(int objid); void closeObject(int objid);
QPDFObjectHandle getTrimmedTrailer();
void prepareFileForWrite(); void prepareFileForWrite();
void writeStandard(); void writeStandard();
void writeLinearized(); void writeLinearized();

View File

@ -1057,7 +1057,7 @@ void
QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream, QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
qpdf_offset_t prev) qpdf_offset_t prev)
{ {
QPDFObjectHandle trailer = pdf.getTrailer(); QPDFObjectHandle trailer = getTrimmedTrailer();
if (! xref_stream) if (! xref_stream)
{ {
writeString("trailer <<"); writeString("trailer <<");
@ -1932,20 +1932,19 @@ QPDFWriter::generateObjectStreams()
} }
} }
void QPDFObjectHandle
QPDFWriter::prepareFileForWrite() QPDFWriter::getTrimmedTrailer()
{ {
// Remove keys from the trailer that necessarily have to be // Remove keys from the trailer that necessarily have to be
// replaced when writing the file. // replaced when writing the file.
QPDFObjectHandle trailer = pdf.getTrailer(); QPDFObjectHandle trailer = pdf.getTrailer().shallowCopy();
// Note that removing the encryption dictionary does not interfere // Remove encryption keys
// with reading encrypted files. QPDF loads all the information
// it needs from the encryption dictionary at the beginning and
// never looks at it again.
trailer.removeKey("/ID"); trailer.removeKey("/ID");
trailer.removeKey("/Encrypt"); trailer.removeKey("/Encrypt");
// Remove modification information
trailer.removeKey("/Prev"); trailer.removeKey("/Prev");
// Remove all trailer keys that potentially come from a // Remove all trailer keys that potentially come from a
@ -1958,6 +1957,12 @@ QPDFWriter::prepareFileForWrite()
trailer.removeKey("/Type"); trailer.removeKey("/Type");
trailer.removeKey("/XRefStm"); trailer.removeKey("/XRefStm");
return trailer;
}
void
QPDFWriter::prepareFileForWrite()
{
// Do a traversal of the entire PDF file structure replacing all // Do a traversal of the entire PDF file structure replacing all
// indirect objects that QPDFWriter wants to be direct. This // indirect objects that QPDFWriter wants to be direct. This
// includes stream lengths, stream filtering parameters, and // includes stream lengths, stream filtering parameters, and
@ -1967,7 +1972,7 @@ QPDFWriter::prepareFileForWrite()
// holders. // holders.
std::list<QPDFObjectHandle> queue; std::list<QPDFObjectHandle> queue;
queue.push_back(pdf.getTrailer()); queue.push_back(getTrimmedTrailer());
std::set<int> visited; std::set<int> visited;
while (! queue.empty()) while (! queue.empty())
@ -2861,7 +2866,7 @@ QPDFWriter::writeStandard()
writeString(this->extra_header_text); writeString(this->extra_header_text);
// Put root first on queue. // Put root first on queue.
QPDFObjectHandle trailer = pdf.getTrailer(); QPDFObjectHandle trailer = getTrimmedTrailer();
enqueueObject(trailer.getKey("/Root")); enqueueObject(trailer.getKey("/Root"));
// Next place any other objects referenced from the trailer // Next place any other objects referenced from the trailer