aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <jberkenbilt@users.noreply.github.com>2022-07-24 20:41:33 +0200
committerGitHub <noreply@github.com>2022-07-24 20:41:33 +0200
commit5696a507b6dacf34d066810a3f2fca3525eb02f5 (patch)
treeb0009760e0f76c28aa99581e4bc6087adf93749f /libqpdf
parent6f1041afb8e6d1f57169cd4c79f42a7c1ce94da8 (diff)
parent8b4afa428e9caa1a34cad434dfe8a3e01e5a24d3 (diff)
downloadqpdf-5696a507b6dacf34d066810a3f2fca3525eb02f5.tar.zst
Merge pull request #731 from m-holger/og_unparse
Tidy QPDFObjGen related code
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/CMakeLists.txt1
-rw-r--r--libqpdf/QPDF.cc226
-rw-r--r--libqpdf/QPDFAcroFormDocumentHelper.cc4
-rw-r--r--libqpdf/QPDFJob.cc24
-rw-r--r--libqpdf/QPDFObjGen.cc17
-rw-r--r--libqpdf/QPDFObjectHandle.cc112
-rw-r--r--libqpdf/QPDFPageObjectHelper.cc10
-rw-r--r--libqpdf/QPDFWriter.cc5
-rw-r--r--libqpdf/QPDF_Stream.cc45
-rw-r--r--libqpdf/QPDF_encryption.cc30
-rw-r--r--libqpdf/QPDF_json.cc8
-rw-r--r--libqpdf/QPDF_linearization.cc41
-rw-r--r--libqpdf/QPDF_optimization.cc4
-rw-r--r--libqpdf/QPDF_pages.cc5
-rw-r--r--libqpdf/qpdf/QPDF_Stream.hh11
15 files changed, 228 insertions, 315 deletions
diff --git a/libqpdf/CMakeLists.txt b/libqpdf/CMakeLists.txt
index 0e450503..cf807f6d 100644
--- a/libqpdf/CMakeLists.txt
+++ b/libqpdf/CMakeLists.txt
@@ -74,6 +74,7 @@ set(libqpdf_SOURCES
QPDFNumberTreeObjectHelper.cc
QPDFObject.cc
QPDFObjectHandle.cc
+ QPDFObjGen.cc
QPDFOutlineDocumentHelper.cc
QPDFOutlineObjectHelper.cc
QPDFPageDocumentHelper.cc
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 86a4e3d2..a0f0f9e1 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -113,15 +113,13 @@ namespace
QPDF::ForeignStreamData::ForeignStreamData(
std::shared_ptr<EncryptionParameters> encp,
std::shared_ptr<InputSource> file,
- int foreign_objid,
- int foreign_generation,
+ QPDFObjGen const& foreign_og,
qpdf_offset_t offset,
size_t length,
QPDFObjectHandle local_dict) :
encp(encp),
file(file),
- foreign_objid(foreign_objid),
- foreign_generation(foreign_generation),
+ foreign_og(foreign_og),
offset(offset),
length(length),
local_dict(local_dict)
@@ -137,22 +135,19 @@ QPDF::CopiedStreamDataProvider::CopiedStreamDataProvider(
bool
QPDF::CopiedStreamDataProvider::provideStreamData(
- int objid,
- int generation,
+ QPDFObjGen const& og,
Pipeline* pipeline,
bool suppress_warnings,
bool will_retry)
{
- std::shared_ptr<ForeignStreamData> foreign_data =
- this->foreign_stream_data[QPDFObjGen(objid, generation)];
+ std::shared_ptr<ForeignStreamData> foreign_data = foreign_stream_data[og];
bool result = false;
if (foreign_data.get()) {
result = destination_qpdf.pipeForeignStreamData(
foreign_data, pipeline, suppress_warnings, will_retry);
QTC::TC("qpdf", "QPDF copy foreign with data", result ? 0 : 1);
} else {
- QPDFObjectHandle foreign_stream =
- this->foreign_streams[QPDFObjGen(objid, generation)];
+ auto foreign_stream = foreign_streams[og];
result = foreign_stream.pipeStreamData(
pipeline, nullptr, 0, qpdf_dl_none, suppress_warnings, will_retry);
QTC::TC(
@@ -176,17 +171,16 @@ QPDF::CopiedStreamDataProvider::registerForeignStream(
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),
- objid(objid),
- gen(gen)
+ og(og)
{
}
void
QPDF::StringDecrypter::decryptString(std::string& val)
{
- qpdf->decryptString(val, objid, gen);
+ qpdf->decryptString(val, og);
}
std::string const&
@@ -205,8 +199,6 @@ QPDF::EncryptionParameters::EncryptionParameters() :
cf_stream(e_none),
cf_string(e_none),
cf_file(e_none),
- cached_key_objid(0),
- cached_key_generation(0),
user_password_matched(false),
owner_password_matched(false)
{
@@ -631,7 +623,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
(!this->m->trailer.isInitialized()) &&
(t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))) {
QPDFObjectHandle t =
- readObject(this->m->file, "trailer", 0, 0, false);
+ readObject(this->m->file, "trailer", QPDFObjGen(), false);
if (!t.isDictionary()) {
// Oh well. It was worth a try.
} else {
@@ -969,7 +961,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
// Set offset to previous xref table if any
QPDFObjectHandle cur_trailer =
- readObject(this->m->file, "trailer", 0, 0, false);
+ readObject(this->m->file, "trailer", QPDFObjGen(), false);
if (!cur_trailer.isDictionary()) {
QTC::TC("qpdf", "QPDF missing trailer");
throw QPDFExc(
@@ -1055,12 +1047,11 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
{
bool found = false;
if (!this->m->ignore_xref_streams) {
- int xobj;
- int xgen;
+ QPDFObjGen x_og;
QPDFObjectHandle xref_obj;
try {
xref_obj = readObjectAtOffset(
- false, xref_offset, "xref stream", 0, 0, xobj, xgen);
+ false, xref_offset, "xref stream", QPDFObjGen(0, 0), x_og);
} catch (QPDFExc&) {
// ignore -- report error below
}
@@ -1363,7 +1354,7 @@ QPDF::showXRefTable()
for (auto const& iter: this->m->xref_table) {
QPDFObjGen const& og = iter.first;
QPDFXRefEntry const& entry = iter.second;
- cout << og.getObj() << "/" << og.getGen() << ": ";
+ cout << og.unparse('/') << ": ";
switch (entry.getType()) {
case 1:
cout << "uncompressed; offset = " << entry.getOffset();
@@ -1405,9 +1396,8 @@ QPDF::fixDanglingReferences(bool force)
// For each non-scalar item to process, put it in the queue.
std::list<QPDFObjectHandle> queue;
queue.push_back(this->m->trailer);
- for (auto const& iter: to_process) {
- QPDFObjectHandle obj = QPDFObjectHandle::Factory::newIndirect(
- this, iter.getObj(), iter.getGen());
+ for (auto const& og: to_process) {
+ QPDFObjectHandle obj = QPDFObjectHandle::Factory::newIndirect(this, og);
if (obj.isDictionary() || obj.isArray()) {
queue.push_back(obj);
} else if (obj.isStream()) {
@@ -1473,29 +1463,24 @@ QPDF::getAllObjects()
std::vector<QPDFObjectHandle> result;
for (auto const& iter: this->m->obj_cache) {
QPDFObjGen const& og = iter.first;
- result.push_back(
- // line-break
- QPDFObjectHandle::Factory::newIndirect(
- this, og.getObj(), og.getGen()));
+ result.push_back(QPDFObjectHandle::Factory::newIndirect(this, og));
}
return result;
}
void
QPDF::setLastObjectDescription(
- std::string const& description, int objid, int generation)
+ std::string const& description, QPDFObjGen const& og)
{
this->m->last_object_description.clear();
if (!description.empty()) {
this->m->last_object_description += description;
- if (objid > 0) {
+ if (og.isIndirect()) {
this->m->last_object_description += ": ";
}
}
- if (objid > 0) {
- this->m->last_object_description += "object " +
- QUtil::int_to_string(objid) + " " +
- QUtil::int_to_string(generation);
+ if (og.isIndirect()) {
+ this->m->last_object_description += "object " + og.unparse(' ');
}
}
@@ -1503,19 +1488,17 @@ QPDFObjectHandle
QPDF::readObject(
std::shared_ptr<InputSource> input,
std::string const& description,
- int objid,
- int generation,
+ QPDFObjGen const& og,
bool in_object_stream)
{
- setLastObjectDescription(description, objid, generation);
+ setLastObjectDescription(description, og);
qpdf_offset_t offset = input->tell();
bool empty = false;
std::shared_ptr<StringDecrypter> decrypter_ph;
StringDecrypter* decrypter = 0;
if (this->m->encp->encrypted && (!in_object_stream)) {
- decrypter_ph =
- std::make_shared<StringDecrypter>(this, objid, generation);
+ decrypter_ph = std::make_shared<StringDecrypter>(this, og);
decrypter = decrypter_ph.get();
}
QPDFObjectHandle object = QPDFObjectHandle::parse(
@@ -1657,14 +1640,13 @@ QPDF::readObject(
} catch (QPDFExc& e) {
if (this->m->attempt_recovery) {
warn(e);
- length = recoverStreamLength(
- input, objid, generation, stream_offset);
+ length = recoverStreamLength(input, og, stream_offset);
} else {
throw e;
}
}
object = QPDFObjectHandle::Factory::newStream(
- this, objid, generation, object, stream_offset, length);
+ this, og, object, stream_offset, length);
} else {
input->seek(cur_offset, SEEK_SET);
}
@@ -1692,8 +1674,7 @@ QPDF::findEndstream()
size_t
QPDF::recoverStreamLength(
std::shared_ptr<InputSource> input,
- int objid,
- int generation,
+ QPDFObjGen const& og,
qpdf_offset_t stream_offset)
{
// Try to reconstruct stream length by looking for
@@ -1718,11 +1699,10 @@ QPDF::recoverStreamLength(
if (length) {
qpdf_offset_t this_obj_offset = 0;
- QPDFObjGen this_obj(0, 0);
+ QPDFObjGen this_og;
// Make sure this is inside this object
for (auto const& iter: this->m->xref_table) {
- QPDFObjGen const& og = iter.first;
QPDFXRefEntry const& entry = iter.second;
if (entry.getType() == 1) {
qpdf_offset_t obj_offset = entry.getOffset();
@@ -1730,12 +1710,11 @@ QPDF::recoverStreamLength(
((this_obj_offset == 0) ||
(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) &&
- (this_obj.getGen() == generation)) {
+ if (this_obj_offset && (this_og == og)) {
// Well, we found endstream\nendobj within the space
// allowed for this object, so we're probably in good
// shape.
@@ -1777,13 +1756,11 @@ QPDF::readObjectAtOffset(
bool try_recovery,
qpdf_offset_t offset,
std::string const& description,
- int exp_objid,
- int exp_generation,
- int& objid,
- int& generation)
+ QPDFObjGen const& exp_og,
+ QPDFObjGen& og)
{
bool check_og = true;
- if (exp_objid == 0) {
+ if (exp_og.getObj() == 0) {
// This method uses an expect object ID of 0 to indicate that
// we don't know or don't care what the actual object ID is at
// this offset. This is true when we read the xref stream and
@@ -1795,7 +1772,7 @@ QPDF::readObjectAtOffset(
check_og = false;
try_recovery = false;
} else {
- setLastObjectDescription(description, exp_objid, exp_generation);
+ setLastObjectDescription(description, exp_og);
}
if (!this->m->attempt_recovery) {
@@ -1841,9 +1818,9 @@ QPDF::readObjectAtOffset(
offset,
"expected n n obj");
}
- objid = QUtil::string_to_int(tobjid.getValue().c_str());
- generation = QUtil::string_to_int(tgen.getValue().c_str());
-
+ int objid = QUtil::string_to_int(tobjid.getValue().c_str());
+ int generation = QUtil::string_to_int(tgen.getValue().c_str());
+ og = QPDFObjGen(objid, generation);
if (objid == 0) {
QTC::TC("qpdf", "QPDF object id 0");
throw QPDFExc(
@@ -1853,17 +1830,14 @@ QPDF::readObjectAtOffset(
offset,
"object with ID 0");
}
-
- if (check_og &&
- (!((objid == exp_objid) && (generation == exp_generation)))) {
+ if (check_og && (exp_og != og)) {
QTC::TC("qpdf", "QPDF err wrong objid/generation");
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"));
+ (std::string("expected ") + exp_og.unparse(' ') + " obj"));
if (try_recovery) {
// Will be retried below
throw e;
@@ -1877,18 +1851,12 @@ QPDF::readObjectAtOffset(
if (try_recovery) {
// Try again after reconstructing xref table
reconstruct_xref(e);
- QPDFObjGen og(exp_objid, exp_generation);
- if (this->m->xref_table.count(og) &&
- (this->m->xref_table[og].getType() == 1)) {
- qpdf_offset_t new_offset = this->m->xref_table[og].getOffset();
+ if (this->m->xref_table.count(exp_og) &&
+ (this->m->xref_table[exp_og].getType() == 1)) {
+ qpdf_offset_t new_offset =
+ this->m->xref_table[exp_og].getOffset();
QPDFObjectHandle result = readObjectAtOffset(
- false,
- new_offset,
- description,
- exp_objid,
- exp_generation,
- objid,
- generation);
+ false, new_offset, description, exp_og, og);
QTC::TC("qpdf", "QPDF recovered in readObjectAtOffset");
return result;
} else {
@@ -1898,8 +1866,7 @@ QPDF::readObjectAtOffset(
"",
0,
std::string(
- "object " + QUtil::int_to_string(exp_objid) + " " +
- QUtil::int_to_string(exp_generation) +
+ "object " + exp_og.unparse(' ') +
" not found in file after regenerating"
" cross reference table"));
return QPDFObjectHandle::newNull();
@@ -1909,8 +1876,7 @@ QPDF::readObjectAtOffset(
}
}
- QPDFObjectHandle oh =
- readObject(this->m->file, description, objid, generation, false);
+ QPDFObjectHandle oh = readObject(this->m->file, description, og, false);
if (!(readToken(this->m->file) ==
QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) {
@@ -1922,7 +1888,6 @@ QPDF::readObjectAtOffset(
"expected endobj");
}
- QPDFObjGen og(objid, generation);
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
@@ -1987,12 +1952,11 @@ QPDF::objectChanged(QPDFObjGen const& og, std::shared_ptr<QPDFObject>& oph)
}
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
// to insert things into the object cache that don't actually
// exist in the file.
- QPDFObjGen og(objid, generation);
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
@@ -2002,8 +1966,7 @@ QPDF::resolve(int objid, int generation)
qpdf_e_damaged_pdf,
"",
this->m->file->getLastOffset(),
- ("loop detected resolving object " + QUtil::int_to_string(objid) +
- " " + QUtil::int_to_string(generation)));
+ ("loop detected resolving object " + og.unparse(' ')));
return QPDF_Null::create();
}
ResolveRecorder rr(this, og);
@@ -2016,16 +1979,9 @@ QPDF::resolve(int objid, int generation)
{
qpdf_offset_t offset = entry.getOffset();
// Object stored in cache by readObjectAtOffset
- int aobjid;
- int ageneration;
- QPDFObjectHandle oh = readObjectAtOffset(
- true,
- offset,
- "",
- objid,
- generation,
- aobjid,
- ageneration);
+ QPDFObjGen a_og;
+ QPDFObjectHandle oh =
+ readObjectAtOffset(true, offset, "", og, a_og);
}
break;
@@ -2039,8 +1995,7 @@ QPDF::resolve(int objid, int generation)
this->m->file->getName(),
"",
0,
- ("object " + QUtil::int_to_string(objid) + "/" +
- QUtil::int_to_string(generation) +
+ ("object " + og.unparse('/') +
" has unexpected xref entry type"));
}
} catch (QPDFExc& e) {
@@ -2050,8 +2005,7 @@ QPDF::resolve(int objid, int generation)
qpdf_e_damaged_pdf,
"",
0,
- ("object " + QUtil::int_to_string(objid) + "/" +
- QUtil::int_to_string(generation) +
+ ("object " + og.unparse('/') +
": error reading object: " + e.what()));
}
}
@@ -2065,10 +2019,7 @@ QPDF::resolve(int objid, int generation)
std::shared_ptr<QPDFObject> result(this->m->obj_cache[og].object);
if (!result->hasDescription()) {
- result->setDescription(
- this,
- ("object " + QUtil::int_to_string(objid) + " " +
- QUtil::int_to_string(generation)));
+ result->setDescription(this, ("object " + og.unparse(' ')));
}
return result;
}
@@ -2165,7 +2116,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
(entry.getObjStreamNumber() == obj_stream_number)) {
int offset = iter.second;
input->seek(offset, SEEK_SET);
- QPDFObjectHandle oh = readObject(input, "", obj, 0, true);
+ QPDFObjectHandle oh = readObject(input, "", og, true);
this->m->obj_cache[og] = ObjCache(
QPDFObjectHandle::ObjAccessor::getObject(oh),
end_before_space,
@@ -2187,48 +2138,46 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh)
QPDFObjGen next(max_objid + 1, 0);
this->m->obj_cache[next] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
- return QPDFObjectHandle::Factory::newIndirect(
- this, next.getObj(), next.getGen());
+ return QPDFObjectHandle::Factory::newIndirect(this, next);
}
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))) {
- resolve(objid, gen);
- replaceObject(objid, gen, QPDFObjectHandle::Factory::makeReserved());
+ resolve(og);
+ replaceObject(og, QPDFObjectHandle::Factory::makeReserved());
}
- return getObjectByID(objid, gen);
+ return getObjectByObjGen(og);
}
QPDFObjectHandle
-QPDF::reserveStream(int objid, int gen)
+QPDF::reserveStream(QPDFObjGen const& og)
{
return QPDFObjectHandle::Factory::newStream(
- this, objid, gen, QPDFObjectHandle::newDictionary(), 0, 0);
+ this, og, QPDFObjectHandle::newDictionary(), 0, 0);
}
QPDFObjectHandle
QPDF::getObjectByObjGen(QPDFObjGen const& og)
{
- return getObjectByID(og.getObj(), og.getGen());
+ return QPDFObjectHandle::Factory::newIndirect(this, og);
}
QPDFObjectHandle
QPDF::getObjectByID(int objid, int generation)
{
- return QPDFObjectHandle::Factory::newIndirect(this, objid, generation);
+ return getObjectByObjGen(QPDFObjGen(objid, generation));
}
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
-QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
+QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh)
{
if (oh.isIndirect()) {
QTC::TC("qpdf", "QPDF replaceObject called with indirect object");
@@ -2237,10 +2186,9 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
}
// Force new object to appear in the cache
- resolve(objid, generation);
+ resolve(og);
// Replace the object in the object cache
- QPDFObjGen og(objid, generation);
this->m->ever_replaced_objects = true;
this->m->obj_cache[og] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
@@ -2540,8 +2488,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
auto foreign_stream_data = std::make_shared<ForeignStreamData>(
foreign_stream_qpdf->m->encp,
foreign_stream_qpdf->m->file,
- foreign.getObjectID(),
- foreign.getGeneration(),
+ foreign.getObjGen(),
stream->getOffset(),
stream->getLength(),
dict);
@@ -2555,20 +2502,19 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
}
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
-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
// cache.
- resolve(objid1, generation1);
- resolve(objid2, generation2);
- QPDFObjGen og1(objid1, generation1);
- QPDFObjGen og2(objid2, generation2);
+ resolve(og1);
+ resolve(og2);
ObjCache t = this->m->obj_cache[og1];
this->m->ever_replaced_objects = true;
this->m->obj_cache[og1] = this->m->obj_cache[og2];
@@ -2752,8 +2698,7 @@ QPDF::pipeStreamData(
std::shared_ptr<EncryptionParameters> encp,
std::shared_ptr<InputSource> file,
QPDF& qpdf_for_warning,
- int objid,
- int generation,
+ QPDFObjGen const& og,
qpdf_offset_t offset,
size_t length,
QPDFObjectHandle stream_dict,
@@ -2764,14 +2709,7 @@ QPDF::pipeStreamData(
std::vector<std::shared_ptr<Pipeline>> to_delete;
if (encp->encrypted) {
decryptStream(
- encp,
- file,
- qpdf_for_warning,
- pipeline,
- objid,
- generation,
- stream_dict,
- to_delete);
+ encp, file, qpdf_for_warning, pipeline, og, stream_dict, to_delete);
}
bool success = false;
@@ -2809,8 +2747,7 @@ QPDF::pipeStreamData(
"",
file->getLastOffset(),
("error decoding stream data for object " +
- QUtil::int_to_string(objid) + " " +
- QUtil::int_to_string(generation) + ": " + e.what())));
+ og.unparse(' ') + ": " + e.what())));
if (will_retry) {
qpdf_for_warning.warn(
// line-break
@@ -2836,8 +2773,7 @@ QPDF::pipeStreamData(
bool
QPDF::pipeStreamData(
- int objid,
- int generation,
+ QPDFObjGen const& og,
qpdf_offset_t offset,
size_t length,
QPDFObjectHandle stream_dict,
@@ -2849,8 +2785,7 @@ QPDF::pipeStreamData(
this->m->encp,
this->m->file,
*this,
- objid,
- generation,
+ og,
offset,
length,
stream_dict,
@@ -2873,8 +2808,7 @@ QPDF::pipeForeignStreamData(
foreign->encp,
foreign->file,
*this,
- foreign->foreign_objid,
- foreign->foreign_generation,
+ foreign->foreign_og,
foreign->offset,
foreign->length,
foreign->local_dict,
diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc
index ddf10e6d..62dbaeee 100644
--- a/libqpdf/QPDFAcroFormDocumentHelper.cc
+++ b/libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -991,8 +991,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
} else {
parent.warnIfPossible(
"while traversing field " +
- obj.getObjGen().unparse() + ", found parent (" +
- parent_og.unparse() +
+ obj.getObjGen().unparse(',') + ", found parent (" +
+ parent_og.unparse(',') +
") that had not been seen, indicating likely"
" invalid field structure");
}
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index c5f0eb2d..343fa348 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -49,8 +49,7 @@ namespace
size_t oi_min_area,
QPDFObjectHandle& image);
virtual ~ImageOptimizer() = default;
- virtual void
- provideStreamData(int objid, int generation, Pipeline* pipeline);
+ virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline);
std::shared_ptr<Pipeline>
makePipeline(std::string const& description, Pipeline* next);
bool evaluate(std::string const& description);
@@ -250,7 +249,7 @@ ImageOptimizer::evaluate(std::string const& description)
}
void
-ImageOptimizer::provideStreamData(int, int, Pipeline* pipeline)
+ImageOptimizer::provideStreamData(QPDFObjGen const&, Pipeline* pipeline)
{
std::shared_ptr<Pipeline> p = makePipeline("", pipeline);
if (p.get() == nullptr) {
@@ -947,7 +946,7 @@ QPDFJob::doShowObj(QPDF& pdf)
}
if (error) {
throw std::runtime_error(
- "unable to get object " + obj.getObjGen().unparse());
+ "unable to get object " + obj.getObjGen().unparse(','));
}
}
@@ -995,7 +994,8 @@ QPDFJob::doListAttachments(QPDF& pdf)
auto efoh = i.second;
*this->m->log->getInfo()
<< key << " -> "
- << efoh->getEmbeddedFileStream().getObjGen().unparse() << "\n";
+ << efoh->getEmbeddedFileStream().getObjGen().unparse(',')
+ << "\n";
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
auto desc = efoh->getDescription();
if (!desc.empty()) {
@@ -1010,7 +1010,7 @@ QPDFJob::doListAttachments(QPDF& pdf)
for (auto i2: efoh->getEmbeddedFileStreams().ditems()) {
auto efs = QPDFEFStreamObjectHelper(i2.second);
v << " " << i2.first << " -> "
- << efs.getObjectHandle().getObjGen().unparse() << "\n";
+ << efs.getObjectHandle().getObjGen().unparse(',') << "\n";
v << " creation date: " << efs.getCreationDate()
<< "\n"
<< " modification date: " << efs.getModDate() << "\n"
@@ -2463,7 +2463,7 @@ QPDFJob::shouldRemoveUnreferencedResources(QPDF& pdf)
QTC::TC("qpdf", "QPDFJob found resources in non-leaf");
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
v << " found resources in non-leaf page node "
- << og.getObj() << " " << og.getGen() << "\n";
+ << og.unparse(' ') << "\n";
});
return true;
}
@@ -2480,9 +2480,8 @@ QPDFJob::shouldRemoveUnreferencedResources(QPDF& pdf)
QTC::TC("qpdf", "QPDFJob found shared resources in leaf");
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
v << " found shared resources in leaf node "
- << og.getObj() << " " << og.getGen() << ": "
- << resources_og.getObj() << " "
- << resources_og.getGen() << "\n";
+ << og.unparse(' ') << ": "
+ << resources_og.unparse(' ') << "\n";
});
return true;
}
@@ -2497,8 +2496,7 @@ QPDFJob::shouldRemoveUnreferencedResources(QPDF& pdf)
QTC::TC("qpdf", "QPDFJob found shared xobject in leaf");
doIfVerbose([&](Pipeline& v, std::string const& prefix) {
v << " found shared xobject in leaf node "
- << og.getObj() << " " << og.getGen() << ": "
- << xobject_og.getObj() << " " << xobject_og.getGen()
+ << og.unparse(' ') << ": " << xobject_og.unparse(' ')
<< "\n";
});
return true;
@@ -3375,7 +3373,7 @@ QPDFJob::writeJSON(QPDF& pdf)
auto wanted = getWantedJSONObjects();
for (auto const& og: wanted) {
std::ostringstream s;
- s << "obj:" << og.getObj() << " " << og.getGen() << " R";
+ s << "obj:" << og.unparse(' ') << " R";
json_objects.insert(s.str());
}
pdf.writeJSON(
diff --git a/libqpdf/QPDFObjGen.cc b/libqpdf/QPDFObjGen.cc
new file mode 100644
index 00000000..e372555d
--- /dev/null
+++ b/libqpdf/QPDFObjGen.cc
@@ -0,0 +1,17 @@
+#include <qpdf/QPDFObjGen.hh>
+
+#include <qpdf/QUtil.hh>
+
+std::ostream&
+operator<<(std::ostream& os, const QPDFObjGen& og)
+{
+ os << og.obj << "," << og.gen;
+ return os;
+}
+
+std::string
+QPDFObjGen::unparse(char separator) const
+{
+ return QUtil::int_to_string(this->obj) + separator +
+ QUtil::int_to_string(this->gen);
+}
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 66087dd4..753493ec 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -53,6 +53,24 @@ QPDFObjectHandle::StreamDataProvider::~StreamDataProvider()
void
QPDFObjectHandle::StreamDataProvider::provideStreamData(
+ QPDFObjGen const& og, Pipeline* pipeline)
+{
+ return provideStreamData(og.getObj(), og.getGen(), pipeline);
+}
+
+bool
+QPDFObjectHandle::StreamDataProvider::provideStreamData(
+ QPDFObjGen const& og,
+ Pipeline* pipeline,
+ bool suppress_warnings,
+ bool will_retry)
+{
+ return provideStreamData(
+ og.getObj(), og.getGen(), pipeline, suppress_warnings, will_retry);
+}
+
+void
+QPDFObjectHandle::StreamDataProvider::provideStreamData(
int objid, int generation, Pipeline* pipeline)
{
throw std::logic_error(
@@ -90,8 +108,7 @@ namespace
{
}
virtual ~CoalesceProvider() = default;
- virtual void
- provideStreamData(int objid, int generation, Pipeline* pipeline);
+ virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline);
private:
QPDFObjectHandle containing_page;
@@ -100,12 +117,11 @@ namespace
} // namespace
void
-CoalesceProvider::provideStreamData(int, int, Pipeline* p)
+CoalesceProvider::provideStreamData(QPDFObjGen const&, Pipeline* p)
{
QTC::TC("qpdf", "QPDFObjectHandle coalesce provide stream data");
- std::string description = "page object " +
- QUtil::int_to_string(containing_page.getObjectID()) + " " +
- QUtil::int_to_string(containing_page.getGeneration());
+ std::string description =
+ "page object " + containing_page.getObjGen().unparse(' ');
std::string all_description;
old_contents.pipeContentStreams(p, description, all_description);
}
@@ -219,27 +235,22 @@ LastChar::getLastChar()
QPDFObjectHandle::QPDFObjectHandle() :
initialized(false),
- qpdf(0),
- objid(0),
- generation(0),
+ qpdf(nullptr),
reserved(false)
{
}
-QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, int objid, int generation) :
+QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, QPDFObjGen const& og) :
initialized(true),
qpdf(qpdf),
- objid(objid),
- generation(generation),
+ og(og),
reserved(false)
{
}
QPDFObjectHandle::QPDFObjectHandle(std::shared_ptr<QPDFObject> const& data) :
initialized(true),
- qpdf(0),
- objid(0),
- generation(0),
+ qpdf(nullptr),
obj(data),
reserved(false)
{
@@ -1431,15 +1442,14 @@ namespace
}
virtual void
- provideStreamData(int, int, Pipeline* pipeline) override
+ provideStreamData(QPDFObjGen const&, Pipeline* pipeline) override
{
p1(pipeline);
}
virtual bool
provideStreamData(
- int,
- int,
+ QPDFObjGen const&,
Pipeline* pipeline,
bool suppress_warnings,
bool will_retry) override
@@ -1482,26 +1492,19 @@ QPDFObjectHandle::replaceStreamData(
QPDFObjGen
QPDFObjectHandle::getObjGen() const
{
- return QPDFObjGen(this->objid, this->generation);
-}
-
-std::string
-QPDFObjectHandle::getObjGenAsStr() const
-{
- return QUtil::int_to_string(this->objid) + " " +
- QUtil::int_to_string(this->generation);
+ return og;
}
int
QPDFObjectHandle::getObjectID() const
{
- return this->objid;
+ return og.getObj();
}
int
QPDFObjectHandle::getGeneration() const
{
- return this->generation;
+ return og.getGen();
}
std::map<std::string, QPDFObjectHandle>
@@ -1556,7 +1559,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
} else {
all_description += ",";
}
- all_description += " stream " + item.getObjGenAsStr();
+ all_description += " stream " + item.getObjGen().unparse(' ');
}
return result;
@@ -1565,7 +1568,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
std::vector<QPDFObjectHandle>
QPDFObjectHandle::getPageContents()
{
- std::string description = "page object " + getObjGenAsStr();
+ std::string description = "page object " + getObjGen().unparse(' ');
std::string all_description;
return this->getKey("/Contents")
.arrayOrStreamToStreamArray(description, all_description);
@@ -1674,7 +1677,7 @@ QPDFObjectHandle::unparse()
{
std::string result;
if (this->isIndirect()) {
- result = getObjGenAsStr() + " R";
+ result = getObjGen().unparse(' ') + " R";
} else {
result = unparseResolved();
}
@@ -1789,7 +1792,7 @@ QPDFObjectHandle::parse(
void
QPDFObjectHandle::pipePageContents(Pipeline* p)
{
- std::string description = "page object " + getObjGenAsStr();
+ std::string description = "page object " + getObjGen().unparse(' ');
std::string all_description;
this->getKey("/Contents")
.pipeContentStreams(p, description, all_description);
@@ -1813,7 +1816,7 @@ QPDFObjectHandle::pipeContentStreams(
throw QPDFExc(
qpdf_e_damaged_pdf,
"content stream",
- "content stream object " + stream.getObjGenAsStr(),
+ "content stream object " + stream.getObjGen().unparse(' '),
0,
"errors while decoding content stream");
}
@@ -1829,7 +1832,7 @@ QPDFObjectHandle::pipeContentStreams(
void
QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks)
{
- std::string description = "page object " + getObjGenAsStr();
+ std::string description = "page object " + getObjGen().unparse(' ');
this->getKey("/Contents")
.parseContentStream_internal(description, callbacks);
}
@@ -1837,14 +1840,15 @@ QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks)
void
QPDFObjectHandle::parseAsContents(ParserCallbacks* callbacks)
{
- std::string description = "object " + getObjGenAsStr();
+ std::string description = "object " + getObjGen().unparse(' ');
this->parseContentStream_internal(description, callbacks);
}
void
QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next)
{
- auto description = "token filter for page object " + getObjGenAsStr();
+ auto description =
+ "token filter for page object " + getObjGen().unparse(' ');
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
this->pipePageContents(&token_pipeline);
}
@@ -1852,7 +1856,7 @@ QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next)
void
QPDFObjectHandle::filterAsContents(TokenFilter* filter, Pipeline* next)
{
- auto description = "token filter for object " + getObjGenAsStr();
+ auto description = "token filter for object " + getObjGen().unparse(' ');
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
this->pipeStreamData(&token_pipeline, 0, qpdf_dl_specialized);
}
@@ -2192,8 +2196,9 @@ QPDFObjectHandle::parseInternal(
// Try to resolve indirect objects
object = newIndirect(
context,
- olist.at(olist.size() - 2).getIntValueAsInt(),
- olist.at(olist.size() - 1).getIntValueAsInt());
+ QPDFObjGen(
+ olist.at(olist.size() - 2).getIntValueAsInt(),
+ olist.at(olist.size() - 1).getIntValueAsInt()));
olist.remove_last();
olist.remove_last();
} else if ((value == "endobj") && (state == st_top)) {
@@ -2481,9 +2486,9 @@ QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset)
}
QPDFObjectHandle
-QPDFObjectHandle::newIndirect(QPDF* qpdf, int objid, int generation)
+QPDFObjectHandle::newIndirect(QPDF* qpdf, QPDFObjGen const& og)
{
- if (objid == 0) {
+ if (!og.isIndirect()) {
// Special case: QPDF uses objid 0 as a sentinel for direct
// objects, and the PDF specification doesn't allow for object
// 0. Treat indirect references to object 0 as null so that we
@@ -2492,7 +2497,7 @@ QPDFObjectHandle::newIndirect(QPDF* qpdf, int objid, int generation)
return newNull();
}
- return QPDFObjectHandle(qpdf, objid, generation);
+ return QPDFObjectHandle(qpdf, og);
}
QPDFObjectHandle
@@ -2640,14 +2645,13 @@ QPDFObjectHandle::newDictionary(
QPDFObjectHandle
QPDFObjectHandle::newStream(
QPDF* qpdf,
- int objid,
- int generation,
+ QPDFObjGen const& og,
QPDFObjectHandle stream_dict,
qpdf_offset_t offset,
size_t length)
{
- QPDFObjectHandle result = QPDFObjectHandle(QPDF_Stream::create(
- qpdf, objid, generation, stream_dict, offset, length));
+ QPDFObjectHandle result = QPDFObjectHandle(
+ QPDF_Stream::create(qpdf, og, stream_dict, offset, length));
if (offset) {
result.setParsedOffset(offset);
}
@@ -2663,11 +2667,11 @@ QPDFObjectHandle::newStream(QPDF* qpdf)
}
QTC::TC("qpdf", "QPDFObjectHandle newStream");
QPDFObjectHandle stream_dict = newDictionary();
- QPDFObjectHandle result = qpdf->makeIndirectObject(
- QPDFObjectHandle(QPDF_Stream::create(qpdf, 0, 0, stream_dict, 0, 0)));
+ QPDFObjectHandle result = qpdf->makeIndirectObject(QPDFObjectHandle(
+ QPDF_Stream::create(qpdf, QPDFObjGen(), stream_dict, 0, 0)));
result.dereference();
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(result.obj.get());
- stream->setObjGen(result.getObjectID(), result.getGeneration());
+ stream->setObjGen(result.getObjGen());
return result;
}
@@ -2695,8 +2699,7 @@ QPDFObjectHandle::newReserved(QPDF* qpdf)
// Reserve a spot for this object by assigning it an object
// number, but then return an unresolved handle to the object.
QPDFObjectHandle reserved = qpdf->makeIndirectObject(makeReserved());
- QPDFObjectHandle result =
- newIndirect(qpdf, reserved.objid, reserved.generation);
+ QPDFObjectHandle result = newIndirect(qpdf, reserved.getObjGen());
result.reserved = true;
return result;
}
@@ -2796,9 +2799,8 @@ QPDFObjectHandle::copyObject(
" reserved object handle direct");
}
- this->qpdf = 0;
- this->objid = 0;
- this->generation = 0;
+ qpdf = nullptr;
+ og = QPDFObjGen();
std::shared_ptr<QPDFObject> new_obj;
@@ -3112,7 +3114,7 @@ QPDFObjectHandle::dereference()
}
if (this->obj.get() == 0) {
std::shared_ptr<QPDFObject> obj =
- QPDF::Resolver::resolve(this->qpdf, getObjectID(), getGeneration());
+ QPDF::Resolver::resolve(this->qpdf, getObjGen());
if (obj.get() == 0) {
// QPDF::resolve never returns an uninitialized object, but
// check just in case.
diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc
index 6c38f098..96a8ce69 100644
--- a/libqpdf/QPDFPageObjectHelper.cc
+++ b/libqpdf/QPDFPageObjectHelper.cc
@@ -21,8 +21,7 @@ namespace
{
}
virtual ~ContentProvider() = default;
- virtual void
- provideStreamData(int objid, int generation, Pipeline* pipeline);
+ virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline);
private:
QPDFObjectHandle from_page;
@@ -30,12 +29,11 @@ namespace
} // namespace
void
-ContentProvider::provideStreamData(int, int, Pipeline* p)
+ContentProvider::provideStreamData(QPDFObjGen const&, Pipeline* p)
{
Pl_Concatenate concat("concatenate", p);
- std::string description = "contents from page object " +
- QUtil::int_to_string(from_page.getObjectID()) + " " +
- QUtil::int_to_string(from_page.getGeneration());
+ std::string description =
+ "contents from page object " + from_page.getObjGen().unparse(' ');
std::string all_description;
from_page.getKey("/Contents")
.pipeContentStreams(&concat, description, all_description);
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index d160ff99..50ec9406 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -1990,9 +1990,8 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
if (object_stream_index == -1) {
if (this->m->qdf_mode && (!this->m->suppress_original_object_ids)) {
writeString(
- "%% Original object ID: " +
- QUtil::int_to_string(object.getObjectID()) + " " +
- QUtil::int_to_string(object.getGeneration()) + "\n");
+ "%% Original object ID: " + object.getObjGen().unparse(' ') +
+ "\n");
}
openObject(new_id);
setDataKey(new_id);
diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc
index 0b06a7f5..84965102 100644
--- a/libqpdf/QPDF_Stream.cc
+++ b/libqpdf/QPDF_Stream.cc
@@ -110,14 +110,12 @@ StreamBlobProvider::operator()(Pipeline* p)
QPDF_Stream::QPDF_Stream(
QPDF* qpdf,
- int objid,
- int generation,
+ QPDFObjGen const& og,
QPDFObjectHandle stream_dict,
qpdf_offset_t offset,
size_t length) :
qpdf(qpdf),
- objid(objid),
- generation(generation),
+ og(og),
filter_on_write(true),
stream_dict(stream_dict),
offset(offset),
@@ -128,23 +126,18 @@ QPDF_Stream::QPDF_Stream(
"object for dictionary");
}
setDescription(
- this->qpdf,
- this->qpdf->getFilename() + ", stream object " +
- QUtil::int_to_string(this->objid) + " " +
- QUtil::int_to_string(this->generation));
+ qpdf, qpdf->getFilename() + ", stream object " + og.unparse(' '));
}
std::shared_ptr<QPDFObject>
QPDF_Stream::create(
QPDF* qpdf,
- int objid,
- int generation,
+ QPDFObjGen const& og,
QPDFObjectHandle stream_dict,
qpdf_offset_t offset,
size_t length)
{
- return do_create(
- new QPDF_Stream(qpdf, objid, generation, stream_dict, offset, length));
+ return do_create(new QPDF_Stream(qpdf, og, stream_dict, offset, length));
}
std::shared_ptr<QPDFObject>
@@ -181,23 +174,21 @@ QPDF_Stream::releaseResolved()
}
void
-QPDF_Stream::setObjGen(int objid, int generation)
+QPDF_Stream::setObjGen(QPDFObjGen const& og)
{
- if (!((this->objid == 0) && (this->generation == 0))) {
+ if (this->og.isIndirect()) {
throw std::logic_error(
"attempt to set object ID and generation of a stream"
" that already has them");
}
- this->objid = objid;
- this->generation = generation;
+ this->og = og;
}
std::string
QPDF_Stream::unparse()
{
// Unparse stream objects as indirect references
- return QUtil::int_to_string(this->objid) + " " +
- QUtil::int_to_string(this->generation) + " R";
+ return og.unparse(' ') + " R";
}
JSON
@@ -619,17 +610,12 @@ QPDF_Stream::pipeStreamData(
Pl_Count count("stream provider count", pipeline);
if (this->stream_provider->supportsRetry()) {
if (!this->stream_provider->provideStreamData(
- this->objid,
- this->generation,
- &count,
- suppress_warnings,
- will_retry)) {
+ og, &count, suppress_warnings, will_retry)) {
filter = false;
success = false;
}
} else {
- this->stream_provider->provideStreamData(
- this->objid, this->generation, &count);
+ this->stream_provider->provideStreamData(og, &count);
}
qpdf_offset_t actual_length = count.getCount();
qpdf_offset_t desired_length = 0;
@@ -642,10 +628,8 @@ QPDF_Stream::pipeStreamData(
// This would be caused by programmer error on the
// part of a library user, not by invalid input data.
throw std::runtime_error(
- "stream data provider for " +
- QUtil::int_to_string(this->objid) + " " +
- QUtil::int_to_string(this->generation) + " provided " +
- QUtil::int_to_string(actual_length) +
+ "stream data provider for " + og.unparse(' ') +
+ " provided " + QUtil::int_to_string(actual_length) +
" bytes instead of expected " +
QUtil::int_to_string(desired_length) + " bytes");
}
@@ -661,8 +645,7 @@ QPDF_Stream::pipeStreamData(
QTC::TC("qpdf", "QPDF_Stream pipe original stream data");
if (!QPDF::Pipe::pipeStreamData(
this->qpdf,
- this->objid,
- this->generation,
+ og,
this->offset,
this->length,
this->stream_dict,
diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc
index 5a7968ca..8c35b992 100644
--- a/libqpdf/QPDF_encryption.cc
+++ b/libqpdf/QPDF_encryption.cc
@@ -1075,8 +1075,7 @@ QPDF::initializeEncryption()
std::string
QPDF::getKeyForObject(
std::shared_ptr<EncryptionParameters> encp,
- int objid,
- int generation,
+ QPDFObjGen const& og,
bool use_aes)
{
if (!encp->encrypted) {
@@ -1084,26 +1083,24 @@ QPDF::getKeyForObject(
"request for encryption key in non-encrypted PDF");
}
- if (!((objid == encp->cached_key_objid) &&
- (generation == encp->cached_key_generation))) {
+ if (og != encp->cached_key_og) {
encp->cached_object_encryption_key = compute_data_key(
encp->encryption_key,
- objid,
- generation,
+ og.getObj(),
+ og.getGen(),
use_aes,
encp->encryption_V,
encp->encryption_R);
- encp->cached_key_objid = objid;
- encp->cached_key_generation = generation;
+ encp->cached_key_og = og;
}
return encp->cached_object_encryption_key;
}
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;
}
bool use_aes = false;
@@ -1139,8 +1136,7 @@ QPDF::decryptString(std::string& str, int objid, int generation)
}
}
- std::string key =
- getKeyForObject(this->m->encp, objid, generation, use_aes);
+ std::string key = getKeyForObject(this->m->encp, og, use_aes);
try {
if (use_aes) {
QTC::TC("qpdf", "QPDF_encryption aes decode string");
@@ -1175,9 +1171,8 @@ QPDF::decryptString(std::string& str, int objid, int generation)
this->m->file->getName(),
this->m->last_object_description,
this->m->file->getLastOffset(),
- "error decrypting string for object " +
- QUtil::int_to_string(objid) + " " +
- QUtil::int_to_string(generation) + ": " + e.what());
+ "error decrypting string for object " + og.unparse() + ": " +
+ e.what());
}
}
@@ -1187,8 +1182,7 @@ QPDF::decryptStream(
std::shared_ptr<InputSource> file,
QPDF& qpdf_for_warning,
Pipeline*& pipeline,
- int objid,
- int generation,
+ QPDFObjGen const& og,
QPDFObjectHandle& stream_dict,
std::vector<std::shared_ptr<Pipeline>>& heap)
{
@@ -1283,7 +1277,7 @@ QPDF::decryptStream(
break;
}
}
- std::string key = getKeyForObject(encp, objid, generation, use_aes);
+ std::string key = getKeyForObject(encp, og, use_aes);
std::shared_ptr<Pipeline> new_pipeline;
if (use_aes) {
QTC::TC("qpdf", "QPDF_encryption aes decode stream");
diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc
index 1db9018c..5527318c 100644
--- a/libqpdf/QPDF_json.cc
+++ b/libqpdf/QPDF_json.cc
@@ -371,9 +371,10 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
QPDFObjectHandle
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()) {
- this->reserved.insert(QPDFObjGen(obj, gen));
+ this->reserved.insert(og);
}
return oh;
}
@@ -495,8 +496,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
QTC::TC("qpdf", "QPDF_json updating existing stream");
} else {
this->this_stream_needs_data = true;
- replacement =
- pdf.reserveStream(tos.getObjectID(), tos.getGeneration());
+ replacement = pdf.reserveStream(tos.getObjGen());
replaceObject(tos, replacement, value);
}
} else {
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc
index ce6441c9..64805f58 100644
--- a/libqpdf/QPDF_linearization.cc
+++ b/libqpdf/QPDF_linearization.cc
@@ -137,8 +137,8 @@ QPDF::isLinearized()
return false;
}
- QPDFObjectHandle candidate =
- QPDFObjectHandle::Factory::newIndirect(this, lindict_obj, 0);
+ QPDFObjectHandle candidate = QPDFObjectHandle::Factory::newIndirect(
+ this, QPDFObjGen(lindict_obj, 0));
if (!candidate.isDictionary()) {
return false;
}
@@ -325,11 +325,10 @@ QPDF::readLinearizationData()
QPDFObjectHandle
QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
{
- int obj;
- int gen;
+ QPDFObjGen og;
QPDFObjectHandle H = readObjectAtOffset(
- false, offset, "linearization hint stream", 0, 0, obj, gen);
- ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)];
+ false, offset, "linearization hint stream", QPDFObjGen(0, 0), og);
+ ObjCache& oc = this->m->obj_cache[og];
qpdf_offset_t min_end_offset = oc.end_before_space;
qpdf_offset_t max_end_offset = oc.end_after_space;
if (!H.isStream()) {
@@ -707,7 +706,7 @@ QPDF::getUncompressedObject(
return obj;
} else {
int repl = (*(object_stream_data.find(obj.getObjectID()))).second;
- return objGenToIndirect(QPDFObjGen(repl, 0));
+ return getObjectByObjGen(QPDFObjGen(repl, 0));
}
}
@@ -1144,12 +1143,6 @@ QPDF::dumpHGeneric(HGeneric& t)
<< "group_length: " << t.group_length << "\n";
}
-QPDFObjectHandle
-QPDF::objGenToIndirect(QPDFObjGen const& og)
-{
- return getObjectByID(og.getObj(), og.getGen());
-}
-
void
QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
{
@@ -1388,9 +1381,9 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
stopOnError("found other than one root while"
" 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) {
- this->m->part4.push_back(objGenToIndirect(og));
+ this->m->part4.push_back(getObjectByObjGen(og));
}
// Part 6: first page objects. Note: implementation note 124
@@ -1419,11 +1412,11 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// hint tables.
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) {
- 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.
@@ -1469,7 +1462,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (auto const& og: this->m->obj_user_to_objects[ou]) {
if (lc_other_page_private.count(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;
}
}
@@ -1486,7 +1479,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Order is unimportant.
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
@@ -1508,7 +1501,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (auto const& og: pages_ogs) {
if (lc_other.count(og)) {
lc_other.erase(og);
- this->m->part9.push_back(objGenToIndirect(og));
+ this->m->part9.push_back(getObjectByObjGen(og));
}
}
@@ -1538,7 +1531,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (auto const& og: ogs) {
if (lc_thumbnail_private.count(og)) {
lc_thumbnail_private.erase(og);
- this->m->part9.push_back(objGenToIndirect(og));
+ this->m->part9.push_back(getObjectByObjGen(og));
}
}
}
@@ -1551,7 +1544,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place shared thumbnail objects
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
@@ -1561,7 +1554,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place all remaining objects
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.
@@ -1663,7 +1656,7 @@ QPDF::pushOutlinesToPart(
lc_outlines.erase(outlines_og);
part.push_back(outlines);
for (auto const& og: lc_outlines) {
- part.push_back(objGenToIndirect(og));
+ part.push_back(getObjectByObjGen(og));
++this->m->c_outline_data.nobjects;
}
}
diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc
index 1fd6da6f..cafdbe64 100644
--- a/libqpdf/QPDF_optimization.cc
+++ b/libqpdf/QPDF_optimization.cc
@@ -252,9 +252,7 @@ QPDF::pushInheritedAttributesToPageInternal(
if ((warn_skipped_keys) && (cur_pages.hasKey("/Parent"))) {
QTC::TC("qpdf", "QPDF unknown key not inherited");
setLastObjectDescription(
- "Pages object",
- cur_pages.getObjectID(),
- cur_pages.getGeneration());
+ "Pages object", cur_pages.getObjGen());
warn(
qpdf_e_pages,
this->m->last_object_description,
diff --git a/libqpdf/QPDF_pages.cc b/libqpdf/QPDF_pages.cc
index bd3f80a6..e1a3b2c1 100644
--- a/libqpdf/QPDF_pages.cc
+++ b/libqpdf/QPDF_pages.cc
@@ -207,8 +207,7 @@ QPDF::insertPageobjToPage(
// that causes this to happen.
setLastObjectDescription(
"page " + QUtil::int_to_string(pos) + " (numbered from zero)",
- og.getObj(),
- og.getGen());
+ og);
throw QPDFExc(
qpdf_e_pages,
this->m->file->getName(),
@@ -334,7 +333,7 @@ QPDF::findPage(QPDFObjGen const& og)
auto it = this->m->pageobj_to_pages_pos.find(og);
if (it == this->m->pageobj_to_pages_pos.end()) {
QTC::TC("qpdf", "QPDF_pages findPage not found");
- setLastObjectDescription("page object", og.getObj(), og.getGen());
+ setLastObjectDescription("page object", og);
throw QPDFExc(
qpdf_e_pages,
this->m->file->getName(),
diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh
index 3b7cf358..8980c751 100644
--- a/libqpdf/qpdf/QPDF_Stream.hh
+++ b/libqpdf/qpdf/QPDF_Stream.hh
@@ -19,8 +19,7 @@ class QPDF_Stream: public QPDFObject
virtual ~QPDF_Stream() = default;
static std::shared_ptr<QPDFObject> create(
QPDF*,
- int objid,
- int generation,
+ QPDFObjGen const& og,
QPDFObjectHandle stream_dict,
qpdf_offset_t offset,
size_t length);
@@ -78,7 +77,7 @@ class QPDF_Stream: public QPDFObject
// Replace object ID and generation. This may only be called if
// object ID and generation are 0. It is used by QPDFObjectHandle
// when adding streams to files.
- void setObjGen(int objid, int generation);
+ void setObjGen(QPDFObjGen const& og);
protected:
virtual void releaseResolved();
@@ -86,8 +85,7 @@ class QPDF_Stream: public QPDFObject
private:
QPDF_Stream(
QPDF*,
- int objid,
- int generation,
+ QPDFObjGen const& og,
QPDFObjectHandle stream_dict,
qpdf_offset_t offset,
size_t length);
@@ -111,8 +109,7 @@ class QPDF_Stream: public QPDFObject
void setDictDescription();
QPDF* qpdf;
- int objid;
- int generation;
+ QPDFObjGen og;
bool filter_on_write;
QPDFObjectHandle stream_dict;
qpdf_offset_t offset;