From a8c93bd324d0362a26c1e6591eead5c52f865c0d Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Mon, 21 Aug 2017 21:33:44 -0400 Subject: Push QPDF member variables into a nested class Pushing member variables into a nested class enables addition of new member variables without breaking binary compatibility. --- libqpdf/QPDF.cc | 514 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 268 insertions(+), 246 deletions(-) (limited to 'libqpdf/QPDF.cc') diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 9c79fc3a..f6e62546 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -74,7 +74,7 @@ QPDF::QPDFVersion() return QPDF::qpdf_version; } -QPDF::QPDF() : +QPDF::Members::Members() : encrypted(false), encryption_initialized(false), ignore_xref_streams(false), @@ -98,6 +98,15 @@ QPDF::QPDF() : { } +QPDF::Members::~Members() +{ +} + +QPDF::QPDF() : + m(new Members()) +{ +} + QPDF::~QPDF() { // If two objects are mutually referential (through each object @@ -114,10 +123,10 @@ QPDF::~QPDF() // reference will reread the object from the file, which would // have the effect of undoing any modifications that may have been // made to any of the objects. - this->xref_table.clear(); + this->m->xref_table.clear(); for (std::map::iterator iter = - this->obj_cache.begin(); - iter != obj_cache.end(); ++iter) + this->m->obj_cache.begin(); + iter != this->m->obj_cache.end(); ++iter) { QPDFObject::ObjAccessor::releaseResolved( (*iter).second.object.getPointer()); @@ -158,7 +167,7 @@ void QPDF::processInputSource(PointerHolder source, char const* password) { - this->file = source; + this->m->file = source; parse(password); } @@ -171,41 +180,41 @@ QPDF::emptyPDF() void QPDF::setIgnoreXRefStreams(bool val) { - this->ignore_xref_streams = val; + this->m->ignore_xref_streams = val; } void QPDF::setOutputStreams(std::ostream* out, std::ostream* err) { - this->out_stream = out ? out : &std::cout; - this->err_stream = err ? err : &std::cerr; + this->m->out_stream = out ? out : &std::cout; + this->m->err_stream = err ? err : &std::cerr; } void QPDF::setSuppressWarnings(bool val) { - this->suppress_warnings = val; + this->m->suppress_warnings = val; } void QPDF::setAttemptRecovery(bool val) { - this->attempt_recovery = val; + this->m->attempt_recovery = val; } std::vector QPDF::getWarnings() { - std::vector result = this->warnings; - this->warnings.clear(); + std::vector result = this->m->warnings; + this->m->warnings.clear(); return result; } bool QPDF::findHeader() { - qpdf_offset_t global_offset = this->file->tell(); - std::string line = this->file->readLine(1024); + qpdf_offset_t global_offset = this->m->file->tell(); + std::string line = this->m->file->readLine(1024); char const* p = line.c_str(); if (strncmp(p, "%PDF-", 5) != 0) { @@ -239,7 +248,7 @@ QPDF::findHeader() } if (valid) { - this->pdf_version = version; + this->m->pdf_version = version; if (global_offset != 0) { // Empirical evidence strongly suggests that when there is @@ -247,7 +256,7 @@ QPDF::findHeader() // offsets in the file are such that 0 points to the // beginning of the header. QTC::TC("qpdf", "QPDF global offset"); - this->file = new OffsetInputSource(this->file, global_offset); + this->m->file = new OffsetInputSource(this->m->file, global_offset); } } return valid; @@ -256,14 +265,14 @@ QPDF::findHeader() bool QPDF::findStartxref() { - QPDFTokenizer::Token t = readToken(this->file, true); + QPDFTokenizer::Token t = readToken(this->m->file, true); if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "startxref")) { - t = readToken(this->file, true); + t = readToken(this->m->file, true); if (t.getType() == QPDFTokenizer::tt_integer) { // Position in front of offset token - this->file->seek(this->file->getLastOffset(), SEEK_SET); + this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET); return true; } } @@ -275,37 +284,37 @@ QPDF::parse(char const* password) { if (password) { - this->provided_password = password; + this->m->provided_password = password; } // Find the header anywhere in the first 1024 bytes of the file. PatternFinder hf(*this, &QPDF::findHeader); - if (! this->file->findFirst("%PDF-", 0, 1024, hf)) + if (! this->m->file->findFirst("%PDF-", 0, 1024, hf)) { QTC::TC("qpdf", "QPDF not a pdf file"); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "can't find PDF header")); // QPDFWriter writes files that usually require at least // version 1.2 for /FlateDecode - this->pdf_version = "1.2"; + this->m->pdf_version = "1.2"; } - if (atof(this->pdf_version.c_str()) < 1.2) + if (atof(this->m->pdf_version.c_str()) < 1.2) { - this->tokenizer.allowPoundAnywhereInName(); + this->m->tokenizer.allowPoundAnywhereInName(); } // PDF spec says %%EOF must be found within the last 1024 bytes of // the file. We add an extra 30 characters to leave room for the // startxref stuff. - this->file->seek(0, SEEK_END); - qpdf_offset_t end_offset = this->file->tell(); + this->m->file->seek(0, SEEK_END); + qpdf_offset_t end_offset = this->m->file->tell(); qpdf_offset_t start_offset = (end_offset > 1054 ? end_offset - 1054 : 0); PatternFinder sf(*this, &QPDF::findStartxref); qpdf_offset_t xref_offset = 0; - if (this->file->findLast("startxref", start_offset, 0, sf)) + if (this->m->file->findLast("startxref", start_offset, 0, sf)) { xref_offset = QUtil::string_to_ll( - readToken(this->file).getValue().c_str()); + readToken(this->m->file).getValue().c_str()); } try @@ -313,14 +322,14 @@ QPDF::parse(char const* password) if (xref_offset == 0) { QTC::TC("qpdf", "QPDF can't find startxref"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "can't find startxref"); } read_xref(xref_offset); } catch (QPDFExc& e) { - if (this->attempt_recovery) + if (this->m->attempt_recovery) { reconstruct_xref(e); QTC::TC("qpdf", "QPDF reconstructed xref table"); @@ -338,28 +347,29 @@ QPDF::parse(char const* password) void QPDF::warn(QPDFExc const& e) { - this->warnings.push_back(e); - if (! this->suppress_warnings) + this->m->warnings.push_back(e); + if (! this->m->suppress_warnings) { - *err_stream << "WARNING: " - << this->warnings.back().what() << std::endl; + *this->m->err_stream + << "WARNING: " + << this->m->warnings.back().what() << std::endl; } } void QPDF::setTrailer(QPDFObjectHandle obj) { - if (this->trailer.isInitialized()) + if (this->m->trailer.isInitialized()) { return; } - this->trailer = obj; + this->m->trailer = obj; } void QPDF::reconstruct_xref(QPDFExc& e) { - if (this->reconstructed_xref) + if (this->m->reconstructed_xref) { // Avoid xref reconstruction infinite loops. This is getting // very hard to reproduce because qpdf is throwing many fewer @@ -367,19 +377,19 @@ QPDF::reconstruct_xref(QPDFExc& e) throw e; } - this->reconstructed_xref = true; + this->m->reconstructed_xref = true; - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "file is damaged")); warn(e); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "Attempting to reconstruct cross-reference table")); // Delete all references to type 1 (uncompressed) objects std::set to_delete; for (std::map::iterator iter = - this->xref_table.begin(); - iter != this->xref_table.end(); ++iter) + this->m->xref_table.begin(); + iter != this->m->xref_table.end(); ++iter) { if (((*iter).second).getType() == 1) { @@ -389,21 +399,22 @@ QPDF::reconstruct_xref(QPDFExc& e) for (std::set::iterator iter = to_delete.begin(); iter != to_delete.end(); ++iter) { - this->xref_table.erase(*iter); + this->m->xref_table.erase(*iter); } - this->file->seek(0, SEEK_END); - qpdf_offset_t eof = this->file->tell(); - this->file->seek(0, SEEK_SET); + this->m->file->seek(0, SEEK_END); + qpdf_offset_t eof = this->m->file->tell(); + this->m->file->seek(0, SEEK_SET); bool in_obj = false; qpdf_offset_t line_start = 0; - while (this->file->tell() < eof) - { - this->file->findAndSkipNextEOL(); - qpdf_offset_t next_line_start = this->file->tell(); - this->file->seek(line_start, SEEK_SET); - QPDFTokenizer::Token t1 = readToken(this->file, true); - qpdf_offset_t token_start = this->file->tell() - t1.getValue().length(); + while (this->m->file->tell() < eof) + { + this->m->file->findAndSkipNextEOL(); + qpdf_offset_t next_line_start = this->m->file->tell(); + this->m->file->seek(line_start, SEEK_SET); + QPDFTokenizer::Token t1 = readToken(this->m->file, true); + qpdf_offset_t token_start = + this->m->file->tell() - t1.getValue().length(); if (token_start >= next_line_start) { // don't process yet @@ -419,8 +430,8 @@ QPDF::reconstruct_xref(QPDFExc& e) { if (t1.getType() == QPDFTokenizer::tt_integer) { - QPDFTokenizer::Token t2 = readToken(this->file, true); - QPDFTokenizer::Token t3 = readToken(this->file, true); + QPDFTokenizer::Token t2 = readToken(this->m->file, true); + QPDFTokenizer::Token t3 = readToken(this->m->file, true); if ((t2.getType() == QPDFTokenizer::tt_integer) && (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj"))) { @@ -430,11 +441,12 @@ QPDF::reconstruct_xref(QPDFExc& e) insertXrefEntry(obj, 1, token_start, gen, true); } } - else if ((! this->trailer.isInitialized()) && - (t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))) + else if ((! this->m->trailer.isInitialized()) && + (t1 == QPDFTokenizer::Token( + QPDFTokenizer::tt_word, "trailer"))) { QPDFObjectHandle t = - readObject(this->file, "trailer", 0, 0, false); + readObject(this->m->file, "trailer", 0, 0, false); if (! t.isDictionary()) { // Oh well. It was worth a try. @@ -445,11 +457,11 @@ QPDF::reconstruct_xref(QPDFExc& e) } } } - this->file->seek(next_line_start, SEEK_SET); + this->m->file->seek(next_line_start, SEEK_SET); line_start = next_line_start; } - if (! this->trailer.isInitialized()) + if (! this->m->trailer.isInitialized()) { // We could check the last encountered object to see if it was // an xref stream. If so, we could try to get the trailer @@ -457,7 +469,7 @@ QPDF::reconstruct_xref(QPDFExc& e) // with bad startxref pointers even when they have object // streams. - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "unable to find trailer " "dictionary while recovering damaged file"); } @@ -479,8 +491,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset) { char buf[7]; memset(buf, 0, sizeof(buf)); - this->file->seek(xref_offset, SEEK_SET); - this->file->read(buf, sizeof(buf) - 1); + this->m->file->seek(xref_offset, SEEK_SET); + this->m->file->read(buf, sizeof(buf) - 1); // The PDF spec says xref must be followed by a line // terminator, but files exist in the wild where it is // terminated by arbitrary whitespace. @@ -506,25 +518,25 @@ QPDF::read_xref(qpdf_offset_t xref_offset) } } - if (! this->trailer.isInitialized()) + if (! this->m->trailer.isInitialized()) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "unable to find trailer while reading xref"); } - int size = this->trailer.getKey("/Size").getIntValue(); + int size = this->m->trailer.getKey("/Size").getIntValue(); int max_obj = 0; - if (! xref_table.empty()) + if (! this->m->xref_table.empty()) { - max_obj = (*(xref_table.rbegin())).first.getObj(); + max_obj = (*(this->m->xref_table.rbegin())).first.getObj(); } - if (! this->deleted_objects.empty()) + if (! this->m->deleted_objects.empty()) { - max_obj = std::max(max_obj, *(this->deleted_objects.rbegin())); + max_obj = std::max(max_obj, *(this->m->deleted_objects.rbegin())); } if (size != max_obj + 1) { QTC::TC("qpdf", "QPDF xref size mismatch"); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, std::string("reported number of objects (") + QUtil::int_to_string(size) + ") inconsistent with actual number of objects (" + @@ -533,7 +545,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) // We no longer need the deleted_objects table, so go ahead and // clear it out to make sure we never depend on its being set. - this->deleted_objects.clear(); + this->m->deleted_objects.clear(); } bool @@ -677,9 +689,9 @@ QPDF::parse_xrefEntry(std::string const& line, if (invalid) { - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref table", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "accepting invalid xref table entry")); } @@ -694,13 +706,13 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) { std::vector deleted_items; - this->file->seek(xref_offset, SEEK_SET); + this->m->file->seek(xref_offset, SEEK_SET); bool done = false; while (! done) { char linebuf[51]; memset(linebuf, 0, sizeof(linebuf)); - this->file->read(linebuf, sizeof(linebuf) - 1); + this->m->file->read(linebuf, sizeof(linebuf) - 1); std::string line = linebuf; int obj = 0; int num = 0; @@ -708,19 +720,19 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) if (! parse_xrefFirst(line, obj, num, bytes)) { QTC::TC("qpdf", "QPDF invalid xref"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "xref table", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "xref table", this->m->file->getLastOffset(), "xref syntax invalid"); } - this->file->seek(this->file->getLastOffset() + bytes, SEEK_SET); + this->m->file->seek(this->m->file->getLastOffset() + bytes, SEEK_SET); for (int i = obj; i < obj + num; ++i) { if (i == 0) { // This is needed by checkLinearization() - this->first_xref_item_offset = this->file->tell(); + this->m->first_xref_item_offset = this->m->file->tell(); } - std::string xref_entry = this->file->readLine(30); + std::string xref_entry = this->m->file->readLine(30); // For xref_table, these will always be small enough to be ints qpdf_offset_t f1 = 0; int f2 = 0; @@ -729,8 +741,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) { QTC::TC("qpdf", "QPDF invalid xref entry"); throw QPDFExc( - qpdf_e_damaged_pdf, this->file->getName(), - "xref table", this->file->getLastOffset(), + qpdf_e_damaged_pdf, this->m->file->getName(), + "xref table", this->m->file->getLastOffset(), "invalid xref entry (obj=" + QUtil::int_to_string(i) + ")"); } @@ -745,45 +757,45 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) insertXrefEntry(i, 1, f1, f2); } } - qpdf_offset_t pos = this->file->tell(); - QPDFTokenizer::Token t = readToken(this->file); + qpdf_offset_t pos = this->m->file->tell(); + QPDFTokenizer::Token t = readToken(this->m->file); if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer")) { done = true; } else { - this->file->seek(pos, SEEK_SET); + this->m->file->seek(pos, SEEK_SET); } } // Set offset to previous xref table if any QPDFObjectHandle cur_trailer = - readObject(this->file, "trailer", 0, 0, false); + readObject(this->m->file, "trailer", 0, 0, false); if (! cur_trailer.isDictionary()) { QTC::TC("qpdf", "QPDF missing trailer"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "", this->m->file->getLastOffset(), "expected trailer dictionary"); } - if (! this->trailer.isInitialized()) + if (! this->m->trailer.isInitialized()) { setTrailer(cur_trailer); - if (! this->trailer.hasKey("/Size")) + if (! this->m->trailer.hasKey("/Size")) { QTC::TC("qpdf", "QPDF trailer lacks size"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "trailer", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "trailer", this->m->file->getLastOffset(), "trailer dictionary lacks /Size key"); } - if (! this->trailer.getKey("/Size").isInteger()) + if (! this->m->trailer.getKey("/Size").isInteger()) { QTC::TC("qpdf", "QPDF trailer size not integer"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "trailer", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "trailer", this->m->file->getLastOffset(), "/Size key in trailer dictionary is not " "an integer"); } @@ -791,7 +803,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) if (cur_trailer.hasKey("/XRefStm")) { - if (this->ignore_xref_streams) + if (this->m->ignore_xref_streams) { QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer"); } @@ -807,7 +819,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) } else { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "invalid /XRefStm"); } @@ -827,8 +839,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) if (! cur_trailer.getKey("/Prev").isInteger()) { QTC::TC("qpdf", "QPDF trailer prev not integer"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "trailer", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "trailer", this->m->file->getLastOffset(), "/Prev key in trailer dictionary is not " "an integer"); } @@ -847,7 +859,7 @@ qpdf_offset_t QPDF::read_xrefStream(qpdf_offset_t xref_offset) { bool found = false; - if (! this->ignore_xref_streams) + if (! this->m->ignore_xref_streams) { int xobj; int xgen; @@ -875,7 +887,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset) if (! found) { QTC::TC("qpdf", "QPDF can't find xref"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", xref_offset, "xref not found"); } @@ -896,7 +908,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) dict.getKey("/Size").isInteger() && (Index_obj.isArray() || Index_obj.isNull()))) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream does not have" " proper /W and /Index keys"); @@ -910,7 +922,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) W[i] = W_obj.getArrayItem(i).getIntValue(); if (W[i] > max_bytes) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream's /W contains" " impossibly large values"); @@ -919,7 +931,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) } if (entry_size == 0) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream's /W indicates" " entry size of 0"); @@ -933,7 +945,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) int n_index = Index_obj.getArrayNItems(); if ((n_index % 2) || (n_index < 2)) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream's /Index has an" " invalid number of values"); @@ -946,7 +958,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) } else { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream's /Index's item " + QUtil::int_to_string(i) + @@ -969,7 +981,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) { if (indx.at(i) > max_num_entries - num_entries) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream claims to contain" " too many entries: " + @@ -989,7 +1001,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) if (expected_size != actual_size) { - QPDFExc x(qpdf_e_damaged_pdf, this->file->getName(), + QPDFExc x(qpdf_e_damaged_pdf, this->m->file->getName(), "xref stream", xref_offset, "Cross-reference stream data has the wrong size;" " expected = " + QUtil::int_to_string(expected_size) + @@ -1050,7 +1062,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) { if (fields[0] != 2) { - this->uncompressed_after_compressed = true; + this->m->uncompressed_after_compressed = true; } } else if (fields[0] == 2) @@ -1060,13 +1072,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) if (obj == 0) { // This is needed by checkLinearization() - this->first_xref_item_offset = xref_offset; + this->m->first_xref_item_offset = xref_offset; } insertXrefEntry(obj, static_cast(fields[0]), fields[1], static_cast(fields[2])); } - if (! this->trailer.isInitialized()) + if (! this->m->trailer.isInitialized()) { setTrailer(dict); } @@ -1075,8 +1087,8 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) { if (! dict.getKey("/Prev").isInteger()) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "xref stream", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "xref stream", this->m->file->getLastOffset(), "/Prev key in xref stream dictionary is not " "an integer"); } @@ -1108,12 +1120,12 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) { // private scope int gen = (f0 == 2 ? 0 : f2); QPDFObjGen og(obj, gen); - if (this->xref_table.count(og)) + if (this->m->xref_table.count(og)) { if (overwrite) { QTC::TC("qpdf", "QPDF xref overwrite object"); - this->xref_table.erase(og); + this->m->xref_table.erase(og); } else { @@ -1121,7 +1133,7 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) return; } } - if (this->deleted_objects.count(obj)) + if (this->m->deleted_objects.count(obj)) { QTC::TC("qpdf", "QPDF xref deleted object"); return; @@ -1131,22 +1143,22 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) switch (f0) { case 0: - this->deleted_objects.insert(obj); + this->m->deleted_objects.insert(obj); break; case 1: // f2 is generation QTC::TC("qpdf", "QPDF xref gen > 0", ((f2 > 0) ? 1 : 0)); - this->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f0, f1, f2); + this->m->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f0, f1, f2); break; case 2: - this->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2); + this->m->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2); break; default: - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "xref stream", this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "xref stream", this->m->file->getLastOffset(), "unknown xref stream entry type " + QUtil::int_to_string(f0)); break; @@ -1157,21 +1169,24 @@ void QPDF::showXRefTable() { for (std::map::iterator iter = - this->xref_table.begin(); - iter != this->xref_table.end(); ++iter) + this->m->xref_table.begin(); + iter != this->m->xref_table.end(); ++iter) { QPDFObjGen const& og = (*iter).first; QPDFXRefEntry const& entry = (*iter).second; - *out_stream << og.getObj() << "/" << og.getGen() << ": "; + *this->m->out_stream << og.getObj() << "/" << og.getGen() << ": "; switch (entry.getType()) { case 1: - *out_stream << "uncompressed; offset = " << entry.getOffset(); + *this->m->out_stream + << "uncompressed; offset = " << entry.getOffset(); break; case 2: - *out_stream << "compressed; stream = " << entry.getObjStreamNumber() - << ", index = " << entry.getObjStreamIndex(); + *this->m->out_stream + << "compressed; stream = " + << entry.getObjStreamNumber() + << ", index = " << entry.getObjStreamIndex(); break; default: @@ -1179,7 +1194,7 @@ QPDF::showXRefTable() " showing xref_table"); break; } - *out_stream << std::endl; + *this->m->out_stream << std::endl; } } @@ -1188,8 +1203,8 @@ QPDF::getAllObjects() { std::vector result; for (std::map::iterator iter = - this->xref_table.begin(); - iter != this->xref_table.end(); ++iter) + this->m->xref_table.begin(); + iter != this->m->xref_table.end(); ++iter) { QPDFObjGen const& og = (*iter).first; @@ -1203,18 +1218,18 @@ void QPDF::setLastObjectDescription(std::string const& description, int objid, int generation) { - this->last_object_description.clear(); + this->m->last_object_description.clear(); if (! description.empty()) { - this->last_object_description += description; + this->m->last_object_description += description; if (objid > 0) { - this->last_object_description += ": "; + this->m->last_object_description += ": "; } } if (objid > 0) { - this->last_object_description += "object " + + this->m->last_object_description += "object " + QUtil::int_to_string(objid) + " " + QUtil::int_to_string(generation); } @@ -1231,20 +1246,20 @@ QPDF::readObject(PointerHolder input, bool empty = false; PointerHolder decrypter_ph; StringDecrypter* decrypter = 0; - if (this->encrypted && (! in_object_stream)) + if (this->m->encrypted && (! in_object_stream)) { decrypter_ph = new StringDecrypter(this, objid, generation); decrypter = decrypter_ph.getPointer(); } QPDFObjectHandle object = QPDFObjectHandle::parse( - input, description, this->tokenizer, empty, decrypter, this); + input, description, this->m->tokenizer, empty, decrypter, this); if (empty) { // Nothing in the PDF spec appears to allow empty objects, but // they have been encountered in actual PDF files and Adobe // Reader appears to ignore them. warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, + this->m->last_object_description, input->getLastOffset(), "empty object treated as null")); } @@ -1299,7 +1314,7 @@ QPDF::readObject(PointerHolder input, warn(QPDFExc( qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, + this->m->last_object_description, input->tell(), "stream keyword followed" " by carriage return only")); @@ -1315,7 +1330,7 @@ QPDF::readObject(PointerHolder input, input->unreadCh(ch); } warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, + this->m->last_object_description, input->tell(), "stream keyword not followed" " by proper line terminator")); @@ -1337,7 +1352,7 @@ QPDF::readObject(PointerHolder input, { QTC::TC("qpdf", "QPDF stream without length"); throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, offset, + this->m->last_object_description, offset, "stream dictionary lacks /Length key"); } @@ -1346,7 +1361,7 @@ QPDF::readObject(PointerHolder input, { QTC::TC("qpdf", "QPDF stream length not integer"); throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, offset, + this->m->last_object_description, offset, "/Length key in stream dictionary is not " "an integer"); } @@ -1359,14 +1374,14 @@ QPDF::readObject(PointerHolder input, { QTC::TC("qpdf", "QPDF missing endstream"); throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, + this->m->last_object_description, input->getLastOffset(), "expected endstream"); } } catch (QPDFExc& e) { - if (this->attempt_recovery) + if (this->m->attempt_recovery) { warn(e); length = recoverStreamLength( @@ -1396,12 +1411,12 @@ bool QPDF::findEndstream() { // Find endstream or endobj. Position the input at that token. - QPDFTokenizer::Token t = readToken(this->file, true); + QPDFTokenizer::Token t = readToken(this->m->file, true); if ((t.getType() == QPDFTokenizer::tt_word) && ((t.getValue() == "endobj") || (t.getValue() == "endstream"))); { - this->file->seek(this->file->getLastOffset(), SEEK_SET); + this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET); return true; } return false; @@ -1415,19 +1430,19 @@ QPDF::recoverStreamLength(PointerHolder input, // Try to reconstruct stream length by looking for // endstream or endobj warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, stream_offset, + this->m->last_object_description, stream_offset, "attempting to recover stream length")); PatternFinder ef(*this, &QPDF::findEndstream); size_t length = 0; - if (this->file->findFirst("end", stream_offset, 0, ef)) + if (this->m->file->findFirst("end", stream_offset, 0, ef)) { - length = this->file->tell() - stream_offset; + length = this->m->file->tell() - stream_offset; // Reread endstream but, if it was endobj, don't skip that. - QPDFTokenizer::Token t = readToken(this->file); + QPDFTokenizer::Token t = readToken(this->m->file); if (t.getValue() == "endobj") { - this->file->seek(this->file->getLastOffset(), SEEK_SET); + this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET); } } @@ -1438,8 +1453,8 @@ QPDF::recoverStreamLength(PointerHolder input, // Make sure this is inside this object for (std::map::iterator iter = - this->xref_table.begin(); - iter != this->xref_table.end(); ++iter) + this->m->xref_table.begin(); + iter != this->m->xref_table.end(); ++iter) { QPDFObjGen const& og = (*iter).first; QPDFXRefEntry const& entry = (*iter).second; @@ -1472,13 +1487,14 @@ QPDF::recoverStreamLength(PointerHolder input, if (length == 0) { warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, stream_offset, - "unable to recover stream data; treating stream as empty")); + this->m->last_object_description, stream_offset, + "unable to recover stream data;" + " treating stream as empty")); } else { warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, stream_offset, + this->m->last_object_description, stream_offset, "recovered stream length: " + QUtil::int_to_string(length))); } @@ -1490,8 +1506,8 @@ QPDF::recoverStreamLength(PointerHolder input, QPDFTokenizer::Token QPDF::readToken(PointerHolder input, bool allow_bad) { - return this->tokenizer.readToken( - input, this->last_object_description, allow_bad); + return this->m->tokenizer.readToken( + input, this->m->last_object_description, allow_bad); } QPDFObjectHandle @@ -1500,7 +1516,7 @@ QPDF::readObjectAtOffset(bool try_recovery, int exp_objid, int exp_generation, int& objid, int& generation) { - if (! this->attempt_recovery) + if (! this->m->attempt_recovery) { try_recovery = false; } @@ -1514,17 +1530,17 @@ QPDF::readObjectAtOffset(bool try_recovery, if (offset == 0) { QTC::TC("qpdf", "QPDF bogus 0 offset", 0); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, 0, + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, 0, "object has offset 0")); return QPDFObjectHandle::newNull(); } - this->file->seek(offset, SEEK_SET); + this->m->file->seek(offset, SEEK_SET); - QPDFTokenizer::Token tobjid = readToken(this->file); - QPDFTokenizer::Token tgen = readToken(this->file); - QPDFTokenizer::Token tobj = readToken(this->file); + QPDFTokenizer::Token tobjid = readToken(this->m->file); + QPDFTokenizer::Token tgen = readToken(this->m->file); + QPDFTokenizer::Token tobj = readToken(this->m->file); bool objidok = (tobjid.getType() == QPDFTokenizer::tt_integer); int genok = (tgen.getType() == QPDFTokenizer::tt_integer); @@ -1539,8 +1555,8 @@ QPDF::readObjectAtOffset(bool try_recovery, if (! (objidok && genok && objok)) { QTC::TC("qpdf", "QPDF expected n n obj"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, offset, + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, offset, "expected n n obj"); } objid = atoi(tobjid.getValue().c_str()); @@ -1549,8 +1565,8 @@ QPDF::readObjectAtOffset(bool try_recovery, if (objid == 0) { QTC::TC("qpdf", "QPDF object id 0"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, offset, + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, offset, "object with ID 0"); } @@ -1558,8 +1574,8 @@ QPDF::readObjectAtOffset(bool try_recovery, (! ((objid == exp_objid) && (generation == exp_generation)))) { QTC::TC("qpdf", "QPDF err wrong objid/generation"); - QPDFExc e(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, offset, + QPDFExc e(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, offset, std::string("expected ") + QUtil::int_to_string(exp_objid) + " " + QUtil::int_to_string(exp_generation) + " obj"); @@ -1583,10 +1599,10 @@ QPDF::readObjectAtOffset(bool try_recovery, // Try again after reconstructing xref table reconstruct_xref(e); QPDFObjGen og(exp_objid, exp_generation); - if (this->xref_table.count(og) && - (this->xref_table[og].getType() == 1)) + if (this->m->xref_table.count(og) && + (this->m->xref_table[og].getType() == 1)) { - qpdf_offset_t new_offset = this->xref_table[og].getOffset(); + qpdf_offset_t new_offset = this->m->xref_table[og].getOffset(); QPDFObjectHandle result = readObjectAtOffset( false, new_offset, description, exp_objid, exp_generation, objid, generation); @@ -1597,7 +1613,7 @@ QPDF::readObjectAtOffset(bool try_recovery, { QTC::TC("qpdf", "QPDF object gone after xref reconstruction"); warn(QPDFExc( - qpdf_e_damaged_pdf, this->file->getName(), + qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, std::string( "object " + @@ -1616,19 +1632,20 @@ QPDF::readObjectAtOffset(bool try_recovery, } QPDFObjectHandle oh = readObject( - this->file, description, objid, generation, false); + this->m->file, description, objid, generation, false); - if (! (readToken(this->file) == + if (! (readToken(this->m->file) == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) { QTC::TC("qpdf", "QPDF err expected endobj"); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, this->file->getLastOffset(), + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, + this->m->file->getLastOffset(), "expected endobj")); } QPDFObjGen og(objid, generation); - if (! this->obj_cache.count(og)) + if (! this->m->obj_cache.count(og)) { // Store the object in the cache here so it gets cached // whether we first know the offset or whether we first know @@ -1640,30 +1657,30 @@ QPDF::readObjectAtOffset(bool try_recovery, // linearization hint tables. Offsets and lengths of objects // may imply the end of an object to be anywhere between these // values. - qpdf_offset_t end_before_space = this->file->tell(); + qpdf_offset_t end_before_space = this->m->file->tell(); // skip over spaces while (true) { char ch; - if (this->file->read(&ch, 1)) + if (this->m->file->read(&ch, 1)) { if (! isspace(static_cast(ch))) { - this->file->seek(-1, SEEK_CUR); + this->m->file->seek(-1, SEEK_CUR); break; } } else { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, offset, + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, offset, "EOF after endobj"); } } - qpdf_offset_t end_after_space = this->file->tell(); + qpdf_offset_t end_after_space = this->m->file->tell(); - this->obj_cache[og] = + this->m->obj_cache[og] = ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), end_before_space, end_after_space); } @@ -1678,14 +1695,14 @@ QPDF::resolve(int objid, int generation) // to insert things into the object cache that don't actually // exist in the file. QPDFObjGen og(objid, generation); - if (this->resolving.count(og)) + if (this->m->resolving.count(og)) { // This can happen if an object references itself directly or // indirectly in some key that has to be resolved during // object parsing, such as stream length. QTC::TC("qpdf", "QPDF recursion loop in resolve"); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "", this->file->getLastOffset(), + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "", this->m->file->getLastOffset(), "loop detected resolving object " + QUtil::int_to_string(objid) + " " + QUtil::int_to_string(generation))); @@ -1693,15 +1710,15 @@ QPDF::resolve(int objid, int generation) } ResolveRecorder rr(this, og); - if (! this->obj_cache.count(og)) + if (! this->m->obj_cache.count(og)) { - if (! this->xref_table.count(og)) + if (! this->m->xref_table.count(og)) { // PDF spec says unknown objects resolve to the null object. return new QPDF_Null; } - QPDFXRefEntry const& entry = this->xref_table[og]; + QPDFXRefEntry const& entry = this->m->xref_table[og]; bool success = false; try { @@ -1724,7 +1741,8 @@ QPDF::resolve(int objid, int generation) break; default: - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + throw QPDFExc(qpdf_e_damaged_pdf, + this->m->file->getName(), "", 0, "object " + QUtil::int_to_string(objid) + "/" + QUtil::int_to_string(generation) + @@ -1738,7 +1756,7 @@ QPDF::resolve(int objid, int generation) } catch (std::exception& e) { - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0, "object " + QUtil::int_to_string(objid) + "/" + QUtil::int_to_string(generation) + @@ -1748,12 +1766,12 @@ QPDF::resolve(int objid, int generation) { QTC::TC("qpdf", "QPDF resolve failure to null"); QPDFObjectHandle oh = QPDFObjectHandle::newNull(); - this->obj_cache[og] = + this->m->obj_cache[og] = ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); } } - return this->obj_cache[og].object; + return this->m->obj_cache[og].object; } void @@ -1763,9 +1781,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number) QPDFObjectHandle obj_stream = getObjectByID(obj_stream_number, 0); if (! obj_stream.isStream()) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, - this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, + this->m->file->getLastOffset(), "supposed object stream " + QUtil::int_to_string(obj_stream_number) + " is not a stream"); @@ -1775,18 +1793,18 @@ QPDF::resolveObjectsInStream(int obj_stream_number) // object stream for the objects in the stream. QPDFObjGen stream_og(obj_stream_number, 0); qpdf_offset_t end_before_space = - this->obj_cache[stream_og].end_before_space; + this->m->obj_cache[stream_og].end_before_space; qpdf_offset_t end_after_space = - this->obj_cache[stream_og].end_after_space; + this->m->obj_cache[stream_og].end_after_space; QPDFObjectHandle dict = obj_stream.getDict(); if (! (dict.getKey("/Type").isName() && dict.getKey("/Type").getName() == "/ObjStm")) { QTC::TC("qpdf", "QPDF ERR object stream with wrong type"); - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, - this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, + this->m->file->getLastOffset(), "supposed object stream " + QUtil::int_to_string(obj_stream_number) + " has wrong type"); @@ -1795,9 +1813,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number) if (! (dict.getKey("/N").isInteger() && dict.getKey("/First").isInteger())) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - this->last_object_description, - this->file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + this->m->last_object_description, + this->m->file->getLastOffset(), "object stream " + QUtil::int_to_string(obj_stream_number) + " has incorrect keys"); @@ -1821,7 +1839,8 @@ QPDF::resolveObjectsInStream(int obj_stream_number) (toffset.getType() == QPDFTokenizer::tt_integer))) { throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), - this->last_object_description, input->getLastOffset(), + this->m->last_object_description, + input->getLastOffset(), "expected integer in object stream header"); } @@ -1840,14 +1859,14 @@ QPDF::resolveObjectsInStream(int obj_stream_number) { int obj = (*iter).first; QPDFObjGen og(obj, 0); - QPDFXRefEntry const& entry = this->xref_table[og]; + QPDFXRefEntry const& entry = this->m->xref_table[og]; if ((entry.getType() == 2) && (entry.getObjStreamNumber() == obj_stream_number)) { int offset = (*iter).second; input->seek(offset, SEEK_SET); QPDFObjectHandle oh = readObject(input, "", obj, 0, true); - this->obj_cache[og] = + this->m->obj_cache[og] = ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), end_before_space, end_after_space); } @@ -1862,16 +1881,16 @@ QPDFObjectHandle QPDF::makeIndirectObject(QPDFObjectHandle oh) { QPDFObjGen o1(0, 0); - if (! this->obj_cache.empty()) + if (! this->m->obj_cache.empty()) { - o1 = (*(this->obj_cache.rbegin())).first; + o1 = (*(this->m->obj_cache.rbegin())).first; } - QPDFObjGen o2 = (*(this->xref_table.rbegin())).first; + QPDFObjGen o2 = (*(this->m->xref_table.rbegin())).first; QTC::TC("qpdf", "QPDF indirect last obj from xref", (o2.getObj() > o1.getObj()) ? 1 : 0); int max_objid = std::max(o1.getObj(), o2.getObj()); QPDFObjGen next(max_objid + 1, 0); - this->obj_cache[next] = + this->m->obj_cache[next] = ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); return QPDFObjectHandle::Factory::newIndirect( this, next.getObj(), next.getGen()); @@ -1910,7 +1929,7 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) // Replace the object in the object cache QPDFObjGen og(objid, generation); - this->obj_cache[og] = + this->m->obj_cache[og] = ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); } @@ -1946,7 +1965,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign, bool allow_page) "QPDF::copyForeign called with object from this QPDF"); } - ObjCopier& obj_copier = this->object_copiers[other]; + ObjCopier& obj_copier = this->m->object_copiers[other]; if (! obj_copier.visiting.empty()) { throw std::logic_error("obj_copier.visiting is not empty" @@ -2016,7 +2035,8 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, QTC::TC("qpdf", "QPDF loop reserving objects"); return; } - if (obj_copier.object_map.find(foreign_og) != obj_copier.object_map.end()) + if (obj_copier.object_map.find(foreign_og) != + obj_copier.object_map.end()) { QTC::TC("qpdf", "QPDF already reserved object"); return; @@ -2139,15 +2159,16 @@ QPDF::replaceForeignIndirectObjects( replaceForeignIndirectObjects( old_dict.getKey(*iter), obj_copier, false)); } - if (this->copied_stream_data_provider == 0) + if (this->m->copied_stream_data_provider == 0) { - this->copied_stream_data_provider = new CopiedStreamDataProvider(); - this->copied_streams = this->copied_stream_data_provider; + this->m->copied_stream_data_provider = + new CopiedStreamDataProvider(); + this->m->copied_streams = this->m->copied_stream_data_provider; } QPDFObjGen local_og(result.getObjGen()); - this->copied_stream_data_provider->registerForeignStream( + this->m->copied_stream_data_provider->registerForeignStream( local_og, foreign); - result.replaceStreamData(this->copied_streams, + result.replaceStreamData(this->m->copied_streams, dict.getKey("/Filter"), dict.getKey("/DecodeParms")); } @@ -2181,21 +2202,21 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2) resolve(objid2, generation2); QPDFObjGen og1(objid1, generation1); QPDFObjGen og2(objid2, generation2); - ObjCache t = this->obj_cache[og1]; - this->obj_cache[og1] = this->obj_cache[og2]; - this->obj_cache[og2] = t; + ObjCache t = this->m->obj_cache[og1]; + this->m->obj_cache[og1] = this->m->obj_cache[og2]; + this->m->obj_cache[og2] = t; } std::string QPDF::getFilename() const { - return this->file->getName(); + return this->m->file->getName(); } std::string QPDF::getPDFVersion() const { - return this->pdf_version; + return this->m->pdf_version; } int @@ -2225,17 +2246,17 @@ QPDF::getExtensionLevel() QPDFObjectHandle QPDF::getTrailer() { - return this->trailer; + return this->m->trailer; } QPDFObjectHandle QPDF::getRoot() { - QPDFObjectHandle root = this->trailer.getKey("/Root"); + QPDFObjectHandle root = this->m->trailer.getKey("/Root"); if (! root.isDictionary()) { - throw QPDFExc(qpdf_e_damaged_pdf, file->getName(), - "", file->getLastOffset(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "", this->m->file->getLastOffset(), "unable to find /Root dictionary"); } return root; @@ -2245,8 +2266,8 @@ void QPDF::getObjectStreamData(std::map& omap) { for (std::map::iterator iter = - this->xref_table.begin(); - iter != this->xref_table.end(); ++iter) + this->m->xref_table.begin(); + iter != this->m->xref_table.end(); ++iter) { QPDFObjGen const& og = (*iter).first; QPDFXRefEntry const& entry = (*iter).second; @@ -2270,12 +2291,13 @@ QPDF::getCompressibleObjGens() // orphaned items. // Exclude encryption dictionary, if any - QPDFObjectHandle encryption_dict = trailer.getKey("/Encrypt"); + QPDFObjectHandle encryption_dict = + this->m->trailer.getKey("/Encrypt"); QPDFObjGen encryption_dict_og = encryption_dict.getObjGen(); std::set visited; std::list queue; - queue.push_front(this->trailer); + queue.push_front(this->m->trailer); std::vector result; while (! queue.empty()) { @@ -2353,25 +2375,25 @@ QPDF::pipeStreamData(int objid, int generation, { bool success = false; std::vector > to_delete; - if (this->encrypted) + if (this->m->encrypted) { decryptStream(pipeline, objid, generation, stream_dict, to_delete); } try { - this->file->seek(offset, SEEK_SET); + this->m->file->seek(offset, SEEK_SET); char buf[10240]; while (length > 0) { size_t to_read = (sizeof(buf) < length ? sizeof(buf) : length); - size_t len = this->file->read(buf, to_read); + size_t len = this->m->file->read(buf, to_read); if (len == 0) { throw QPDFExc(qpdf_e_damaged_pdf, - this->file->getName(), - this->last_object_description, - this->file->getLastOffset(), + this->m->file->getName(), + this->m->last_object_description, + this->m->file->getLastOffset(), "unexpected EOF reading stream data"); } length -= len; @@ -2392,8 +2414,8 @@ QPDF::pipeStreamData(int objid, int generation, if (! suppress_warnings) { QTC::TC("qpdf", "QPDF decoding error warning"); - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), - "", this->file->getLastOffset(), + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), + "", this->m->file->getLastOffset(), "error decoding stream data for object " + QUtil::int_to_string(objid) + " " + QUtil::int_to_string(generation) + ": " + e.what())); @@ -2442,7 +2464,7 @@ QPDF::findAttachmentStreams() item.getKey("/EF").getKey("/F").isStream()) { QPDFObjectHandle stream = item.getKey("/EF").getKey("/F"); - this->attachment_streams.insert(stream.getObjGen()); + this->m->attachment_streams.insert(stream.getObjGen()); } } } -- cgit v1.2.3-54-g00ecf