summaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc37
1 files changed, 26 insertions, 11 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index c5a7ab5d..e39f9b7a 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -1861,6 +1861,12 @@ QPDF::newReserved()
}
QPDFObjectHandle
+QPDF::newIndirectNull()
+{
+ return makeIndirectFromQPDFObject(QPDF_Null::create());
+}
+
+QPDFObjectHandle
QPDF::newStream()
{
return makeIndirectFromQPDFObject(
@@ -1948,7 +1954,10 @@ void
QPDF::replaceReserved(QPDFObjectHandle reserved, QPDFObjectHandle replacement)
{
QTC::TC("qpdf", "QPDF replaceReserved");
- reserved.assertReserved();
+ auto tc = reserved.getTypeCode();
+ if (!(tc == ::ot_reserved || tc == ::ot_null)) {
+ throw std::logic_error("replaceReserved called with non-reserverd object");
+ }
replaceObject(reserved.getObjGen(), replacement);
}
@@ -2012,8 +2021,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign)
reserveObjects(foreign, obj_copier, true);
if (!obj_copier.visiting.empty()) {
- throw std::logic_error("obj_copier.visiting is not empty"
- " after reserving objects");
+ throw std::logic_error("obj_copier.visiting is not empty after reserving objects");
}
// Copy any new objects and replace the reservations.
@@ -2026,7 +2034,13 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign)
}
obj_copier.to_copy.clear();
- return obj_copier.object_map[foreign.getObjGen()];
+ auto& result = obj_copier.object_map[foreign.getObjGen()];
+ if (!result.isInitialized()) {
+ result = QPDFObjectHandle::newNull();
+ warn(damagedPDF("Unexpected reference to /Pages object while copying foreign object. "
+ "Replacing with Null object."));
+ }
+ return result;
}
void
@@ -2042,11 +2056,6 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top)
return;
}
- if ((!top) && foreign.isPageObject()) {
- QTC::TC("qpdf", "QPDF not crossing page boundary");
- return;
- }
-
if (foreign.isIndirect()) {
QPDFObjGen foreign_og(foreign.getObjGen());
if (obj_copier.object_map.count(foreign_og) > 0) {
@@ -2061,8 +2070,14 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top)
}
QTC::TC("qpdf", "QPDF copy indirect");
if (obj_copier.object_map.count(foreign_og) == 0) {
+ obj_copier.object_map[foreign_og] =
+ foreign.isStream() ? newStream() : newIndirectNull();
+ if ((!top) && foreign.isPageObject()) {
+ QTC::TC("qpdf", "QPDF not crossing page boundary");
+ obj_copier.visiting.erase(foreign);
+ return;
+ }
obj_copier.to_copy.push_back(foreign);
- obj_copier.object_map[foreign_og] = foreign.isStream() ? newStream() : newReserved();
}
}
@@ -2094,7 +2109,7 @@ QPDF::replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_cop
QTC::TC("qpdf", "QPDF replace indirect");
auto mapping = obj_copier.object_map.find(foreign.getObjGen());
if (mapping == obj_copier.object_map.end()) {
- // This case would occur if this is a reference to a Page or Pages object that we didn't
+ // This case would occur if this is a reference to a Pages object that we didn't
// traverse into.
QTC::TC("qpdf", "QPDF replace foreign indirect with null");
result = QPDFObjectHandle::newNull();