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

QPDFObjGen : tidy QPDF private methods

Change method signatures to use QPDFObjGen.
Use QPDFObjGen methods where possible.
Remove redundant QPDF::objGenToIndirect.
This commit is contained in:
m-holger 2022-07-23 16:48:28 +01:00
parent 3404ca8ac8
commit f7978db1f6
9 changed files with 103 additions and 165 deletions

View File

@ -815,9 +815,9 @@ class QPDF
private: private:
static std::shared_ptr<QPDFObject> static std::shared_ptr<QPDFObject>
resolve(QPDF* qpdf, int objid, int generation) resolve(QPDF* qpdf, QPDFObjGen const& og)
{ {
return qpdf->resolve(objid, generation); return qpdf->resolve(og);
} }
static bool static bool
objectChanged( objectChanged(
@ -879,8 +879,7 @@ class QPDF
static bool static bool
pipeStreamData( pipeStreamData(
QPDF* qpdf, QPDF* qpdf,
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle dict, QPDFObjectHandle dict,
@ -889,8 +888,7 @@ class QPDF
bool will_retry) bool will_retry)
{ {
return qpdf->pipeStreamData( return qpdf->pipeStreamData(
objid, og,
generation,
offset, offset,
length, length,
dict, dict,
@ -959,8 +957,7 @@ class QPDF
std::string user_password; std::string user_password;
std::string encryption_key; std::string encryption_key;
std::string cached_object_encryption_key; std::string cached_object_encryption_key;
int cached_key_objid; QPDFObjGen cached_key_og;
int cached_key_generation;
bool user_password_matched; bool user_password_matched;
bool owner_password_matched; bool owner_password_matched;
}; };
@ -973,8 +970,7 @@ class QPDF
ForeignStreamData( ForeignStreamData(
std::shared_ptr<EncryptionParameters> encp, std::shared_ptr<EncryptionParameters> encp,
std::shared_ptr<InputSource> file, std::shared_ptr<InputSource> file,
int foreign_objid, QPDFObjGen const& foreign_og,
int foreign_generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle local_dict); QPDFObjectHandle local_dict);
@ -982,8 +978,7 @@ class QPDF
private: private:
std::shared_ptr<EncryptionParameters> encp; std::shared_ptr<EncryptionParameters> encp;
std::shared_ptr<InputSource> file; std::shared_ptr<InputSource> file;
int foreign_objid; QPDFObjGen foreign_og;
int foreign_generation;
qpdf_offset_t offset; qpdf_offset_t offset;
size_t length; size_t length;
QPDFObjectHandle local_dict; QPDFObjectHandle local_dict;
@ -1017,14 +1012,13 @@ class QPDF
friend class QPDF; friend class QPDF;
public: public:
StringDecrypter(QPDF* qpdf, int objid, int gen); StringDecrypter(QPDF* qpdf, QPDFObjGen const& og);
virtual ~StringDecrypter() = default; virtual ~StringDecrypter() = default;
virtual void decryptString(std::string& val); virtual void decryptString(std::string& val);
private: private:
QPDF* qpdf; QPDF* qpdf;
int objid; QPDFObjGen og;
int gen;
}; };
class ResolveRecorder class ResolveRecorder
@ -1127,17 +1121,15 @@ class QPDF
void insertXrefEntry( void insertXrefEntry(
int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite = false); int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite = false);
void setLastObjectDescription( void setLastObjectDescription(
std::string const& description, int objid, int generation); std::string const& description, QPDFObjGen const& og);
QPDFObjectHandle readObject( QPDFObjectHandle readObject(
std::shared_ptr<InputSource>, std::shared_ptr<InputSource>,
std::string const& description, std::string const& description,
int objid, QPDFObjGen const& og,
int generation,
bool in_object_stream); bool in_object_stream);
size_t recoverStreamLength( size_t recoverStreamLength(
std::shared_ptr<InputSource> input, std::shared_ptr<InputSource> input,
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t stream_offset); qpdf_offset_t stream_offset);
QPDFTokenizer::Token QPDFTokenizer::Token
readToken(std::shared_ptr<InputSource>, size_t max_len = 0); readToken(std::shared_ptr<InputSource>, size_t max_len = 0);
@ -1149,16 +1141,15 @@ class QPDF
QPDFObjGen const& exp_og, QPDFObjGen const& exp_og,
QPDFObjGen& og); QPDFObjGen& og);
bool objectChanged(QPDFObjGen const& og, std::shared_ptr<QPDFObject>& oph); bool objectChanged(QPDFObjGen const& og, std::shared_ptr<QPDFObject>& oph);
std::shared_ptr<QPDFObject> resolve(int objid, int generation); std::shared_ptr<QPDFObject> resolve(QPDFObjGen const& og);
void resolveObjectsInStream(int obj_stream_number); void resolveObjectsInStream(int obj_stream_number);
void stopOnError(std::string const& message); void stopOnError(std::string const& message);
QPDFObjectHandle reserveObjectIfNotExists(int objid, int gen); QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og);
QPDFObjectHandle reserveStream(int objid, int gen); QPDFObjectHandle reserveStream(QPDFObjGen const& og);
// Calls finish() on the pipeline when done but does not delete it // Calls finish() on the pipeline when done but does not delete it
bool pipeStreamData( bool pipeStreamData(
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle dict, QPDFObjectHandle dict,
@ -1174,8 +1165,7 @@ class QPDF
std::shared_ptr<QPDF::EncryptionParameters> encp, std::shared_ptr<QPDF::EncryptionParameters> encp,
std::shared_ptr<InputSource> file, std::shared_ptr<InputSource> file,
QPDF& qpdf_for_warning, QPDF& qpdf_for_warning,
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle dict, QPDFObjectHandle dict,
@ -1228,10 +1218,9 @@ class QPDF
void initializeEncryption(); void initializeEncryption();
static std::string getKeyForObject( static std::string getKeyForObject(
std::shared_ptr<EncryptionParameters> encp, std::shared_ptr<EncryptionParameters> encp,
int objid, QPDFObjGen const& og,
int generation,
bool use_aes); bool use_aes);
void decryptString(std::string&, int objid, int generation); void decryptString(std::string&, QPDFObjGen const& og);
static std::string compute_encryption_key_from_password( static std::string compute_encryption_key_from_password(
std::string const& password, EncryptionData const& data); std::string const& password, EncryptionData const& data);
static std::string recover_encryption_key_with_password( static std::string recover_encryption_key_with_password(
@ -1245,8 +1234,7 @@ class QPDF
std::shared_ptr<InputSource> file, std::shared_ptr<InputSource> file,
QPDF& qpdf_for_warning, QPDF& qpdf_for_warning,
Pipeline*& pipeline, Pipeline*& pipeline,
int objid, QPDFObjGen const& og,
int generation,
QPDFObjectHandle& stream_dict, QPDFObjectHandle& stream_dict,
std::vector<std::shared_ptr<Pipeline>>& heap); std::vector<std::shared_ptr<Pipeline>>& heap);
@ -1569,7 +1557,6 @@ class QPDF
void dumpHSharedObject(); void dumpHSharedObject();
void dumpHGeneric(HGeneric&); void dumpHGeneric(HGeneric&);
qpdf_offset_t adjusted_offset(qpdf_offset_t offset); qpdf_offset_t adjusted_offset(qpdf_offset_t offset);
QPDFObjectHandle objGenToIndirect(QPDFObjGen const&);
void void
calculateLinearizationData(std::map<int, int> const& object_stream_data); calculateLinearizationData(std::map<int, int> const& object_stream_data);
void pushOutlinesToPart( void pushOutlinesToPart(

View File

@ -113,15 +113,13 @@ namespace
QPDF::ForeignStreamData::ForeignStreamData( QPDF::ForeignStreamData::ForeignStreamData(
std::shared_ptr<EncryptionParameters> encp, std::shared_ptr<EncryptionParameters> encp,
std::shared_ptr<InputSource> file, std::shared_ptr<InputSource> file,
int foreign_objid, QPDFObjGen const& foreign_og,
int foreign_generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle local_dict) : QPDFObjectHandle local_dict) :
encp(encp), encp(encp),
file(file), file(file),
foreign_objid(foreign_objid), foreign_og(foreign_og),
foreign_generation(foreign_generation),
offset(offset), offset(offset),
length(length), length(length),
local_dict(local_dict) local_dict(local_dict)
@ -176,17 +174,16 @@ QPDF::CopiedStreamDataProvider::registerForeignStream(
this->foreign_stream_data[local_og] = foreign_stream; this->foreign_stream_data[local_og] = foreign_stream;
} }
QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, int objid, int gen) : QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, QPDFObjGen const& og) :
qpdf(qpdf), qpdf(qpdf),
objid(objid), og(og)
gen(gen)
{ {
} }
void void
QPDF::StringDecrypter::decryptString(std::string& val) QPDF::StringDecrypter::decryptString(std::string& val)
{ {
qpdf->decryptString(val, objid, gen); qpdf->decryptString(val, og);
} }
std::string const& std::string const&
@ -205,8 +202,6 @@ QPDF::EncryptionParameters::EncryptionParameters() :
cf_stream(e_none), cf_stream(e_none),
cf_string(e_none), cf_string(e_none),
cf_file(e_none), cf_file(e_none),
cached_key_objid(0),
cached_key_generation(0),
user_password_matched(false), user_password_matched(false),
owner_password_matched(false) owner_password_matched(false)
{ {
@ -631,7 +626,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
(!this->m->trailer.isInitialized()) && (!this->m->trailer.isInitialized()) &&
(t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))) { (t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))) {
QPDFObjectHandle t = QPDFObjectHandle t =
readObject(this->m->file, "trailer", 0, 0, false); readObject(this->m->file, "trailer", QPDFObjGen(), false);
if (!t.isDictionary()) { if (!t.isDictionary()) {
// Oh well. It was worth a try. // Oh well. It was worth a try.
} else { } else {
@ -969,7 +964,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
// Set offset to previous xref table if any // Set offset to previous xref table if any
QPDFObjectHandle cur_trailer = QPDFObjectHandle cur_trailer =
readObject(this->m->file, "trailer", 0, 0, false); readObject(this->m->file, "trailer", QPDFObjGen(), false);
if (!cur_trailer.isDictionary()) { if (!cur_trailer.isDictionary()) {
QTC::TC("qpdf", "QPDF missing trailer"); QTC::TC("qpdf", "QPDF missing trailer");
throw QPDFExc( throw QPDFExc(
@ -1341,7 +1336,7 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
break; break;
case 2: case 2:
this->m->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2); this->m->xref_table[QPDFObjGen(obj)] = QPDFXRefEntry(f0, f1, f2);
break; break;
default: default:
@ -1362,7 +1357,7 @@ QPDF::showXRefTable()
for (auto const& iter: this->m->xref_table) { for (auto const& iter: this->m->xref_table) {
QPDFObjGen const& og = iter.first; QPDFObjGen const& og = iter.first;
QPDFXRefEntry const& entry = iter.second; QPDFXRefEntry const& entry = iter.second;
cout << og.getObj() << "/" << og.getGen() << ": "; cout << og.unparse('/') << ": ";
switch (entry.getType()) { switch (entry.getType()) {
case 1: case 1:
cout << "uncompressed; offset = " << entry.getOffset(); cout << "uncompressed; offset = " << entry.getOffset();
@ -1478,18 +1473,17 @@ QPDF::getAllObjects()
void void
QPDF::setLastObjectDescription( QPDF::setLastObjectDescription(
std::string const& description, int objid, int generation) std::string const& description, QPDFObjGen const& og)
{ {
this->m->last_object_description.clear(); this->m->last_object_description.clear();
if (!description.empty()) { if (!description.empty()) {
this->m->last_object_description += description; this->m->last_object_description += description;
if (objid > 0) { if (og.isIndirect()) {
this->m->last_object_description += ": "; this->m->last_object_description += ": ";
} }
} }
if (objid > 0) { if (og.isIndirect()) {
this->m->last_object_description += this->m->last_object_description += "object " + og.unparse(' ');
"object " + QPDFObjGen(objid, generation).unparse(' ');
} }
} }
@ -1497,19 +1491,17 @@ QPDFObjectHandle
QPDF::readObject( QPDF::readObject(
std::shared_ptr<InputSource> input, std::shared_ptr<InputSource> input,
std::string const& description, std::string const& description,
int objid, QPDFObjGen const& og,
int generation,
bool in_object_stream) bool in_object_stream)
{ {
setLastObjectDescription(description, objid, generation); setLastObjectDescription(description, og);
qpdf_offset_t offset = input->tell(); qpdf_offset_t offset = input->tell();
bool empty = false; bool empty = false;
std::shared_ptr<StringDecrypter> decrypter_ph; std::shared_ptr<StringDecrypter> decrypter_ph;
StringDecrypter* decrypter = 0; StringDecrypter* decrypter = 0;
if (this->m->encp->encrypted && (!in_object_stream)) { if (this->m->encp->encrypted && (!in_object_stream)) {
decrypter_ph = decrypter_ph = std::make_shared<StringDecrypter>(this, og);
std::make_shared<StringDecrypter>(this, objid, generation);
decrypter = decrypter_ph.get(); decrypter = decrypter_ph.get();
} }
QPDFObjectHandle object = QPDFObjectHandle::parse( QPDFObjectHandle object = QPDFObjectHandle::parse(
@ -1651,18 +1643,13 @@ QPDF::readObject(
} catch (QPDFExc& e) { } catch (QPDFExc& e) {
if (this->m->attempt_recovery) { if (this->m->attempt_recovery) {
warn(e); warn(e);
length = recoverStreamLength( length = recoverStreamLength(input, og, stream_offset);
input, objid, generation, stream_offset);
} else { } else {
throw e; throw e;
} }
} }
object = QPDFObjectHandle::Factory::newStream( object = QPDFObjectHandle::Factory::newStream(
this, this, og, object, stream_offset, length);
QPDFObjGen(objid, generation),
object,
stream_offset,
length);
} else { } else {
input->seek(cur_offset, SEEK_SET); input->seek(cur_offset, SEEK_SET);
} }
@ -1690,8 +1677,7 @@ QPDF::findEndstream()
size_t size_t
QPDF::recoverStreamLength( QPDF::recoverStreamLength(
std::shared_ptr<InputSource> input, std::shared_ptr<InputSource> input,
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t stream_offset) qpdf_offset_t stream_offset)
{ {
// Try to reconstruct stream length by looking for // Try to reconstruct stream length by looking for
@ -1716,11 +1702,10 @@ QPDF::recoverStreamLength(
if (length) { if (length) {
qpdf_offset_t this_obj_offset = 0; qpdf_offset_t this_obj_offset = 0;
QPDFObjGen this_obj(0, 0); QPDFObjGen this_og;
// Make sure this is inside this object // Make sure this is inside this object
for (auto const& iter: this->m->xref_table) { for (auto const& iter: this->m->xref_table) {
QPDFObjGen const& og = iter.first;
QPDFXRefEntry const& entry = iter.second; QPDFXRefEntry const& entry = iter.second;
if (entry.getType() == 1) { if (entry.getType() == 1) {
qpdf_offset_t obj_offset = entry.getOffset(); qpdf_offset_t obj_offset = entry.getOffset();
@ -1728,12 +1713,11 @@ QPDF::recoverStreamLength(
((this_obj_offset == 0) || ((this_obj_offset == 0) ||
(this_obj_offset > obj_offset))) { (this_obj_offset > obj_offset))) {
this_obj_offset = obj_offset; this_obj_offset = obj_offset;
this_obj = og; this_og = iter.first;
} }
} }
} }
if (this_obj_offset && (this_obj.getObj() == objid) && if (this_obj_offset && (this_og == og)) {
(this_obj.getGen() == generation)) {
// Well, we found endstream\nendobj within the space // Well, we found endstream\nendobj within the space
// allowed for this object, so we're probably in good // allowed for this object, so we're probably in good
// shape. // shape.
@ -1791,7 +1775,7 @@ QPDF::readObjectAtOffset(
check_og = false; check_og = false;
try_recovery = false; try_recovery = false;
} else { } else {
setLastObjectDescription(description, exp_og.getObj(), exp_og.getGen()); setLastObjectDescription(description, exp_og);
} }
if (!this->m->attempt_recovery) { if (!this->m->attempt_recovery) {
@ -1895,8 +1879,7 @@ QPDF::readObjectAtOffset(
} }
} }
QPDFObjectHandle oh = QPDFObjectHandle oh = readObject(this->m->file, description, og, false);
readObject(this->m->file, description, og.getObj(), og.getGen(), false);
if (!(readToken(this->m->file) == if (!(readToken(this->m->file) ==
QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) { QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) {
@ -1972,12 +1955,11 @@ QPDF::objectChanged(QPDFObjGen const& og, std::shared_ptr<QPDFObject>& oph)
} }
std::shared_ptr<QPDFObject> std::shared_ptr<QPDFObject>
QPDF::resolve(int objid, int generation) QPDF::resolve(QPDFObjGen const& og)
{ {
// Check object cache before checking xref table. This allows us // Check object cache before checking xref table. This allows us
// to insert things into the object cache that don't actually // to insert things into the object cache that don't actually
// exist in the file. // exist in the file.
QPDFObjGen og(objid, generation);
if (this->m->resolving.count(og)) { if (this->m->resolving.count(og)) {
// This can happen if an object references itself directly or // This can happen if an object references itself directly or
// indirectly in some key that has to be resolved during // indirectly in some key that has to be resolved during
@ -2131,13 +2113,13 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
// xref table and only cache what would actually be resolved here. // xref table and only cache what would actually be resolved here.
for (auto const& iter: offsets) { for (auto const& iter: offsets) {
int obj = iter.first; int obj = iter.first;
QPDFObjGen og(obj, 0); QPDFObjGen og(obj);
QPDFXRefEntry const& entry = this->m->xref_table[og]; QPDFXRefEntry const& entry = this->m->xref_table[og];
if ((entry.getType() == 2) && if ((entry.getType() == 2) &&
(entry.getObjStreamNumber() == obj_stream_number)) { (entry.getObjStreamNumber() == obj_stream_number)) {
int offset = iter.second; int offset = iter.second;
input->seek(offset, SEEK_SET); input->seek(offset, SEEK_SET);
QPDFObjectHandle oh = readObject(input, "", obj, 0, true); QPDFObjectHandle oh = readObject(input, "", og, true);
this->m->obj_cache[og] = ObjCache( this->m->obj_cache[og] = ObjCache(
QPDFObjectHandle::ObjAccessor::getObject(oh), QPDFObjectHandle::ObjAccessor::getObject(oh),
end_before_space, end_before_space,
@ -2163,21 +2145,20 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh)
} }
QPDFObjectHandle QPDFObjectHandle
QPDF::reserveObjectIfNotExists(int objid, int gen) QPDF::reserveObjectIfNotExists(QPDFObjGen const& og)
{ {
QPDFObjGen og(objid, gen);
if ((!this->m->obj_cache.count(og)) && (!this->m->xref_table.count(og))) { if ((!this->m->obj_cache.count(og)) && (!this->m->xref_table.count(og))) {
resolve(objid, gen); resolve(og);
replaceObject(objid, gen, QPDFObjectHandle::Factory::makeReserved()); replaceObject(og, QPDFObjectHandle::Factory::makeReserved());
} }
return getObjectByID(objid, gen); return getObjectByObjGen(og);
} }
QPDFObjectHandle QPDFObjectHandle
QPDF::reserveStream(int objid, int gen) QPDF::reserveStream(QPDFObjGen const& og)
{ {
return QPDFObjectHandle::Factory::newStream( return QPDFObjectHandle::Factory::newStream(
this, QPDFObjGen(objid, gen), QPDFObjectHandle::newDictionary(), 0, 0); this, og, QPDFObjectHandle::newDictionary(), 0, 0);
} }
QPDFObjectHandle QPDFObjectHandle
@ -2193,13 +2174,13 @@ QPDF::getObjectByID(int objid, int generation)
} }
void void
QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh) QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
{ {
replaceObject(og.getObj(), og.getGen(), oh); replaceObject(QPDFObjGen(objid, generation), oh);
} }
void void
QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh)
{ {
if (oh.isIndirect()) { if (oh.isIndirect()) {
QTC::TC("qpdf", "QPDF replaceObject called with indirect object"); QTC::TC("qpdf", "QPDF replaceObject called with indirect object");
@ -2208,10 +2189,9 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
} }
// Force new object to appear in the cache // Force new object to appear in the cache
resolve(objid, generation); resolve(og);
// Replace the object in the object cache // Replace the object in the object cache
QPDFObjGen og(objid, generation);
this->m->ever_replaced_objects = true; this->m->ever_replaced_objects = true;
this->m->obj_cache[og] = this->m->obj_cache[og] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
@ -2511,8 +2491,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
auto foreign_stream_data = std::make_shared<ForeignStreamData>( auto foreign_stream_data = std::make_shared<ForeignStreamData>(
foreign_stream_qpdf->m->encp, foreign_stream_qpdf->m->encp,
foreign_stream_qpdf->m->file, foreign_stream_qpdf->m->file,
foreign.getObjectID(), foreign.getObjGen(),
foreign.getGeneration(),
stream->getOffset(), stream->getOffset(),
stream->getLength(), stream->getLength(),
dict); dict);
@ -2526,20 +2505,19 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
} }
void void
QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2) QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
{ {
swapObjects(og1.getObj(), og1.getGen(), og2.getObj(), og2.getGen()); swapObjects(
QPDFObjGen(objid1, generation1), QPDFObjGen(objid2, generation2));
} }
void void
QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2) QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2)
{ {
// Force objects to be loaded into cache; then swap them in the // Force objects to be loaded into cache; then swap them in the
// cache. // cache.
resolve(objid1, generation1); resolve(og1);
resolve(objid2, generation2); resolve(og2);
QPDFObjGen og1(objid1, generation1);
QPDFObjGen og2(objid2, generation2);
ObjCache t = this->m->obj_cache[og1]; ObjCache t = this->m->obj_cache[og1];
this->m->ever_replaced_objects = true; this->m->ever_replaced_objects = true;
this->m->obj_cache[og1] = this->m->obj_cache[og2]; this->m->obj_cache[og1] = this->m->obj_cache[og2];
@ -2723,8 +2701,7 @@ QPDF::pipeStreamData(
std::shared_ptr<EncryptionParameters> encp, std::shared_ptr<EncryptionParameters> encp,
std::shared_ptr<InputSource> file, std::shared_ptr<InputSource> file,
QPDF& qpdf_for_warning, QPDF& qpdf_for_warning,
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle stream_dict, QPDFObjectHandle stream_dict,
@ -2735,14 +2712,7 @@ QPDF::pipeStreamData(
std::vector<std::shared_ptr<Pipeline>> to_delete; std::vector<std::shared_ptr<Pipeline>> to_delete;
if (encp->encrypted) { if (encp->encrypted) {
decryptStream( decryptStream(
encp, encp, file, qpdf_for_warning, pipeline, og, stream_dict, to_delete);
file,
qpdf_for_warning,
pipeline,
objid,
generation,
stream_dict,
to_delete);
} }
bool success = false; bool success = false;
@ -2780,8 +2750,7 @@ QPDF::pipeStreamData(
"", "",
file->getLastOffset(), file->getLastOffset(),
("error decoding stream data for object " + ("error decoding stream data for object " +
QPDFObjGen(objid, generation).unparse(' ') + ": " + og.unparse(' ') + ": " + e.what())));
e.what())));
if (will_retry) { if (will_retry) {
qpdf_for_warning.warn( qpdf_for_warning.warn(
// line-break // line-break
@ -2807,8 +2776,7 @@ QPDF::pipeStreamData(
bool bool
QPDF::pipeStreamData( QPDF::pipeStreamData(
int objid, QPDFObjGen const& og,
int generation,
qpdf_offset_t offset, qpdf_offset_t offset,
size_t length, size_t length,
QPDFObjectHandle stream_dict, QPDFObjectHandle stream_dict,
@ -2820,8 +2788,7 @@ QPDF::pipeStreamData(
this->m->encp, this->m->encp,
this->m->file, this->m->file,
*this, *this,
objid, og,
generation,
offset, offset,
length, length,
stream_dict, stream_dict,
@ -2844,8 +2811,7 @@ QPDF::pipeForeignStreamData(
foreign->encp, foreign->encp,
foreign->file, foreign->file,
*this, *this,
foreign->foreign_objid, foreign->foreign_og,
foreign->foreign_generation,
foreign->offset, foreign->offset,
foreign->length, foreign->length,
foreign->local_dict, foreign->local_dict,

View File

@ -3098,7 +3098,7 @@ QPDFObjectHandle::dereference()
} }
if (this->obj.get() == 0) { if (this->obj.get() == 0) {
std::shared_ptr<QPDFObject> obj = std::shared_ptr<QPDFObject> obj =
QPDF::Resolver::resolve(this->qpdf, getObjectID(), getGeneration()); QPDF::Resolver::resolve(this->qpdf, getObjGen());
if (obj.get() == 0) { if (obj.get() == 0) {
// QPDF::resolve never returns an uninitialized object, but // QPDF::resolve never returns an uninitialized object, but
// check just in case. // check just in case.

View File

@ -658,8 +658,7 @@ QPDF_Stream::pipeStreamData(
QTC::TC("qpdf", "QPDF_Stream pipe original stream data"); QTC::TC("qpdf", "QPDF_Stream pipe original stream data");
if (!QPDF::Pipe::pipeStreamData( if (!QPDF::Pipe::pipeStreamData(
this->qpdf, this->qpdf,
this->objid, QPDFObjGen(this->objid, this->generation),
this->generation,
this->offset, this->offset,
this->length, this->length,
this->stream_dict, this->stream_dict,

View File

@ -1075,8 +1075,7 @@ QPDF::initializeEncryption()
std::string std::string
QPDF::getKeyForObject( QPDF::getKeyForObject(
std::shared_ptr<EncryptionParameters> encp, std::shared_ptr<EncryptionParameters> encp,
int objid, QPDFObjGen const& og,
int generation,
bool use_aes) bool use_aes)
{ {
if (!encp->encrypted) { if (!encp->encrypted) {
@ -1084,26 +1083,24 @@ QPDF::getKeyForObject(
"request for encryption key in non-encrypted PDF"); "request for encryption key in non-encrypted PDF");
} }
if (!((objid == encp->cached_key_objid) && if (og != encp->cached_key_og) {
(generation == encp->cached_key_generation))) {
encp->cached_object_encryption_key = compute_data_key( encp->cached_object_encryption_key = compute_data_key(
encp->encryption_key, encp->encryption_key,
objid, og.getObj(),
generation, og.getGen(),
use_aes, use_aes,
encp->encryption_V, encp->encryption_V,
encp->encryption_R); encp->encryption_R);
encp->cached_key_objid = objid; encp->cached_key_og = og;
encp->cached_key_generation = generation;
} }
return encp->cached_object_encryption_key; return encp->cached_object_encryption_key;
} }
void void
QPDF::decryptString(std::string& str, int objid, int generation) QPDF::decryptString(std::string& str, QPDFObjGen const& og)
{ {
if (objid == 0) { if (!og.isIndirect()) {
return; return;
} }
bool use_aes = false; bool use_aes = false;
@ -1139,8 +1136,7 @@ QPDF::decryptString(std::string& str, int objid, int generation)
} }
} }
std::string key = std::string key = getKeyForObject(this->m->encp, og, use_aes);
getKeyForObject(this->m->encp, objid, generation, use_aes);
try { try {
if (use_aes) { if (use_aes) {
QTC::TC("qpdf", "QPDF_encryption aes decode string"); QTC::TC("qpdf", "QPDF_encryption aes decode string");
@ -1175,8 +1171,8 @@ QPDF::decryptString(std::string& str, int objid, int generation)
this->m->file->getName(), this->m->file->getName(),
this->m->last_object_description, this->m->last_object_description,
this->m->file->getLastOffset(), this->m->file->getLastOffset(),
"error decrypting string for object " + "error decrypting string for object " + og.unparse() + ": " +
QPDFObjGen(objid, generation).unparse() + ": " + e.what()); e.what());
} }
} }
@ -1186,8 +1182,7 @@ QPDF::decryptStream(
std::shared_ptr<InputSource> file, std::shared_ptr<InputSource> file,
QPDF& qpdf_for_warning, QPDF& qpdf_for_warning,
Pipeline*& pipeline, Pipeline*& pipeline,
int objid, QPDFObjGen const& og,
int generation,
QPDFObjectHandle& stream_dict, QPDFObjectHandle& stream_dict,
std::vector<std::shared_ptr<Pipeline>>& heap) std::vector<std::shared_ptr<Pipeline>>& heap)
{ {
@ -1282,7 +1277,7 @@ QPDF::decryptStream(
break; break;
} }
} }
std::string key = getKeyForObject(encp, objid, generation, use_aes); std::string key = getKeyForObject(encp, og, use_aes);
std::shared_ptr<Pipeline> new_pipeline; std::shared_ptr<Pipeline> new_pipeline;
if (use_aes) { if (use_aes) {
QTC::TC("qpdf", "QPDF_encryption aes decode stream"); QTC::TC("qpdf", "QPDF_encryption aes decode stream");

View File

@ -371,9 +371,10 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
QPDFObjectHandle QPDFObjectHandle
QPDF::JSONReactor::reserveObject(int obj, int gen) QPDF::JSONReactor::reserveObject(int obj, int gen)
{ {
auto oh = pdf.reserveObjectIfNotExists(obj, gen); QPDFObjGen og(obj, gen);
auto oh = pdf.reserveObjectIfNotExists(og);
if (oh.isReserved()) { if (oh.isReserved()) {
this->reserved.insert(QPDFObjGen(obj, gen)); this->reserved.insert(og);
} }
return oh; return oh;
} }
@ -495,8 +496,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
QTC::TC("qpdf", "QPDF_json updating existing stream"); QTC::TC("qpdf", "QPDF_json updating existing stream");
} else { } else {
this->this_stream_needs_data = true; this->this_stream_needs_data = true;
replacement = replacement = pdf.reserveStream(tos.getObjGen());
pdf.reserveStream(tos.getObjectID(), tos.getGeneration());
replaceObject(tos, replacement, value); replaceObject(tos, replacement, value);
} }
} else { } else {

View File

@ -706,7 +706,7 @@ QPDF::getUncompressedObject(
return obj; return obj;
} else { } else {
int repl = (*(object_stream_data.find(obj.getObjectID()))).second; int repl = (*(object_stream_data.find(obj.getObjectID()))).second;
return objGenToIndirect(QPDFObjGen(repl, 0)); return getObjectByObjGen(QPDFObjGen(repl));
} }
} }
@ -1143,12 +1143,6 @@ QPDF::dumpHGeneric(HGeneric& t)
<< "group_length: " << t.group_length << "\n"; << "group_length: " << t.group_length << "\n";
} }
QPDFObjectHandle
QPDF::objGenToIndirect(QPDFObjGen const& og)
{
return getObjectByID(og.getObj(), og.getGen());
}
void void
QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
{ {
@ -1387,9 +1381,9 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
stopOnError("found other than one root while" stopOnError("found other than one root while"
" calculating linearization data"); " calculating linearization data");
} }
this->m->part4.push_back(objGenToIndirect(*(lc_root.begin()))); this->m->part4.push_back(getObjectByObjGen(*(lc_root.begin())));
for (auto const& og: lc_open_document) { for (auto const& og: lc_open_document) {
this->m->part4.push_back(objGenToIndirect(og)); this->m->part4.push_back(getObjectByObjGen(og));
} }
// Part 6: first page objects. Note: implementation note 124 // Part 6: first page objects. Note: implementation note 124
@ -1418,11 +1412,11 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// hint tables. // hint tables.
for (auto const& og: lc_first_page_private) { for (auto const& og: lc_first_page_private) {
this->m->part6.push_back(objGenToIndirect(og)); this->m->part6.push_back(getObjectByObjGen(og));
} }
for (auto const& og: lc_first_page_shared) { for (auto const& og: lc_first_page_shared) {
this->m->part6.push_back(objGenToIndirect(og)); this->m->part6.push_back(getObjectByObjGen(og));
} }
// Place the outline dictionary if it goes in the first page section. // Place the outline dictionary if it goes in the first page section.
@ -1468,7 +1462,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (auto const& og: this->m->obj_user_to_objects[ou]) { for (auto const& og: this->m->obj_user_to_objects[ou]) {
if (lc_other_page_private.count(og)) { if (lc_other_page_private.count(og)) {
lc_other_page_private.erase(og); lc_other_page_private.erase(og);
this->m->part7.push_back(objGenToIndirect(og)); this->m->part7.push_back(getObjectByObjGen(og));
++this->m->c_page_offset_data.entries.at(i).nobjects; ++this->m->c_page_offset_data.entries.at(i).nobjects;
} }
} }
@ -1485,7 +1479,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Order is unimportant. // Order is unimportant.
for (auto const& og: lc_other_page_shared) { for (auto const& og: lc_other_page_shared) {
this->m->part8.push_back(objGenToIndirect(og)); this->m->part8.push_back(getObjectByObjGen(og));
} }
// Part 9: other objects // Part 9: other objects
@ -1507,7 +1501,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (auto const& og: pages_ogs) { for (auto const& og: pages_ogs) {
if (lc_other.count(og)) { if (lc_other.count(og)) {
lc_other.erase(og); lc_other.erase(og);
this->m->part9.push_back(objGenToIndirect(og)); this->m->part9.push_back(getObjectByObjGen(og));
} }
} }
@ -1537,7 +1531,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (auto const& og: ogs) { for (auto const& og: ogs) {
if (lc_thumbnail_private.count(og)) { if (lc_thumbnail_private.count(og)) {
lc_thumbnail_private.erase(og); lc_thumbnail_private.erase(og);
this->m->part9.push_back(objGenToIndirect(og)); this->m->part9.push_back(getObjectByObjGen(og));
} }
} }
} }
@ -1550,7 +1544,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place shared thumbnail objects // Place shared thumbnail objects
for (auto const& og: lc_thumbnail_shared) { for (auto const& og: lc_thumbnail_shared) {
this->m->part9.push_back(objGenToIndirect(og)); this->m->part9.push_back(getObjectByObjGen(og));
} }
// Place outlines unless in first page // Place outlines unless in first page
@ -1560,7 +1554,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place all remaining objects // Place all remaining objects
for (auto const& og: lc_other) { for (auto const& og: lc_other) {
this->m->part9.push_back(objGenToIndirect(og)); this->m->part9.push_back(getObjectByObjGen(og));
} }
// Make sure we got everything exactly once. // Make sure we got everything exactly once.
@ -1662,7 +1656,7 @@ QPDF::pushOutlinesToPart(
lc_outlines.erase(outlines_og); lc_outlines.erase(outlines_og);
part.push_back(outlines); part.push_back(outlines);
for (auto const& og: lc_outlines) { for (auto const& og: lc_outlines) {
part.push_back(objGenToIndirect(og)); part.push_back(getObjectByObjGen(og));
++this->m->c_outline_data.nobjects; ++this->m->c_outline_data.nobjects;
} }
} }

View File

@ -252,9 +252,7 @@ QPDF::pushInheritedAttributesToPageInternal(
if ((warn_skipped_keys) && (cur_pages.hasKey("/Parent"))) { if ((warn_skipped_keys) && (cur_pages.hasKey("/Parent"))) {
QTC::TC("qpdf", "QPDF unknown key not inherited"); QTC::TC("qpdf", "QPDF unknown key not inherited");
setLastObjectDescription( setLastObjectDescription(
"Pages object", "Pages object", cur_pages.getObjGen());
cur_pages.getObjectID(),
cur_pages.getGeneration());
warn( warn(
qpdf_e_pages, qpdf_e_pages,
this->m->last_object_description, this->m->last_object_description,

View File

@ -207,8 +207,7 @@ QPDF::insertPageobjToPage(
// that causes this to happen. // that causes this to happen.
setLastObjectDescription( setLastObjectDescription(
"page " + QUtil::int_to_string(pos) + " (numbered from zero)", "page " + QUtil::int_to_string(pos) + " (numbered from zero)",
og.getObj(), og);
og.getGen());
throw QPDFExc( throw QPDFExc(
qpdf_e_pages, qpdf_e_pages,
this->m->file->getName(), this->m->file->getName(),
@ -334,7 +333,7 @@ QPDF::findPage(QPDFObjGen const& og)
auto it = this->m->pageobj_to_pages_pos.find(og); auto it = this->m->pageobj_to_pages_pos.find(og);
if (it == this->m->pageobj_to_pages_pos.end()) { if (it == this->m->pageobj_to_pages_pos.end()) {
QTC::TC("qpdf", "QPDF_pages findPage not found"); QTC::TC("qpdf", "QPDF_pages findPage not found");
setLastObjectDescription("page object", og.getObj(), og.getGen()); setLastObjectDescription("page object", og);
throw QPDFExc( throw QPDFExc(
qpdf_e_pages, qpdf_e_pages,
this->m->file->getName(), this->m->file->getName(),