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

Merge pull request #1028 from m-holger/i1003

Maintain links to foreign pages when copying foreign objects (fixes #1003)
This commit is contained in:
Jay Berkenbilt 2023-09-02 14:59:16 -04:00 committed by GitHub
commit ec6784411d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 382 additions and 363 deletions

View File

@ -351,6 +351,8 @@ class QPDF
// QPDF with QPDFWriter if it has any reserved objects in it.
QPDF_DLL
QPDFObjectHandle newReserved();
QPDF_DLL
QPDFObjectHandle newIndirectNull();
// Install this object handle as an indirect object and return an indirect reference to it.
QPDF_DLL
@ -391,8 +393,8 @@ class QPDF
void swapObjects(int objid1, int generation1, int objid2, int generation2);
// Replace a reserved object. This is a wrapper around replaceObject but it guarantees that the
// underlying object is a reserved object. After this call, reserved will be a reference to
// replacement.
// underlying object is a reserved object or a null object. After this call, reserved will
// be a reference to replacement.
QPDF_DLL
void replaceReserved(QPDFObjectHandle reserved, QPDFObjectHandle replacement);

View File

@ -1860,6 +1860,12 @@ QPDF::newReserved()
return makeIndirectFromQPDFObject(QPDF_Reserved::create());
}
QPDFObjectHandle
QPDF::newIndirectNull()
{
return makeIndirectFromQPDFObject(QPDF_Null::create());
}
QPDFObjectHandle
QPDF::newStream()
{
@ -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();

View File

@ -121,8 +121,10 @@ QPDF_Dictionary::getAsMap() const
void
QPDF_Dictionary::replaceKey(std::string const& key, QPDFObjectHandle value)
{
if (value.isNull()) {
// The PDF spec doesn't distinguish between keys with null values and missing keys.
if (value.isNull() && !value.isIndirect()) {
// The PDF spec doesn't distinguish between keys with null values and missing keys. Allow
// indirect nulls which are equivalent to a dangling reference, which is permitted by the
// spec.
removeKey(key);
} else {
// add or replace value

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
>>
endobj
%% Original object ID: 25 0
%% Original object ID: 26 0
2 0 obj
<<
/DR 4 0 R
@ -53,7 +53,7 @@ endobj
>>
endobj
%% Original object ID: 26 0
%% Original object ID: 27 0
4 0 obj
<<
/Font <<
@ -70,7 +70,7 @@ endobj
>>
endobj
%% Original object ID: 24 0
%% Original object ID: 25 0
5 0 obj
<<
/AP <<
@ -94,7 +94,7 @@ endobj
>>
endobj
%% Original object ID: 38 0
%% Original object ID: 39 0
6 0 obj
<<
/DV /1
@ -110,7 +110,7 @@ endobj
>>
endobj
%% Original object ID: 51 0
%% Original object ID: 52 0
7 0 obj
<<
/AP <<
@ -141,7 +141,7 @@ endobj
>>
endobj
%% Original object ID: 57 0
%% Original object ID: 58 0
8 0 obj
<<
/AP <<
@ -172,7 +172,7 @@ endobj
>>
endobj
%% Original object ID: 63 0
%% Original object ID: 64 0
9 0 obj
<<
/AP <<
@ -203,7 +203,7 @@ endobj
>>
endobj
%% Original object ID: 76 0
%% Original object ID: 77 0
10 0 obj
<<
/DV /2
@ -219,7 +219,7 @@ endobj
>>
endobj
%% Original object ID: 88 0
%% Original object ID: 89 0
11 0 obj
<<
/AP <<
@ -243,7 +243,7 @@ endobj
>>
endobj
%% Original object ID: 92 0
%% Original object ID: 93 0
12 0 obj
<<
/AP <<
@ -274,7 +274,7 @@ endobj
>>
endobj
%% Original object ID: 96 0
%% Original object ID: 97 0
13 0 obj
<<
/AP <<
@ -312,7 +312,7 @@ endobj
>>
endobj
%% Original object ID: 100 0
%% Original object ID: 101 0
14 0 obj
<<
/AP <<
@ -343,7 +343,7 @@ endobj
>>
endobj
%% Original object ID: 104 0
%% Original object ID: 105 0
15 0 obj
<<
/AP <<
@ -374,7 +374,7 @@ endobj
>>
endobj
%% Original object ID: 117 0
%% Original object ID: 118 0
16 0 obj
<<
/AP <<
@ -398,7 +398,7 @@ endobj
>>
endobj
%% Original object ID: 129 0
%% Original object ID: 130 0
17 0 obj
<<
/DV /1
@ -414,7 +414,7 @@ endobj
>>
endobj
%% Original object ID: 142 0
%% Original object ID: 143 0
18 0 obj
<<
/AP <<
@ -445,7 +445,7 @@ endobj
>>
endobj
%% Original object ID: 148 0
%% Original object ID: 149 0
19 0 obj
<<
/AP <<
@ -476,7 +476,7 @@ endobj
>>
endobj
%% Original object ID: 154 0
%% Original object ID: 155 0
20 0 obj
<<
/AP <<
@ -507,7 +507,7 @@ endobj
>>
endobj
%% Original object ID: 167 0
%% Original object ID: 168 0
21 0 obj
<<
/DV /2
@ -523,7 +523,7 @@ endobj
>>
endobj
%% Original object ID: 179 0
%% Original object ID: 180 0
22 0 obj
<<
/AP <<
@ -547,7 +547,7 @@ endobj
>>
endobj
%% Original object ID: 183 0
%% Original object ID: 184 0
23 0 obj
<<
/AP <<
@ -578,7 +578,7 @@ endobj
>>
endobj
%% Original object ID: 187 0
%% Original object ID: 188 0
24 0 obj
<<
/AP <<
@ -616,7 +616,7 @@ endobj
>>
endobj
%% Original object ID: 191 0
%% Original object ID: 192 0
25 0 obj
<<
/AP <<
@ -647,7 +647,7 @@ endobj
>>
endobj
%% Original object ID: 195 0
%% Original object ID: 196 0
26 0 obj
<<
/AP <<
@ -1309,7 +1309,7 @@ endobj
>>
endobj
%% Original object ID: 27 0
%% Original object ID: 28 0
33 0 obj
<<
/BBox [
@ -1348,7 +1348,7 @@ endobj
77
endobj
%% Original object ID: 39 0
%% Original object ID: 40 0
35 0 obj
<<
/AP <<
@ -1377,7 +1377,7 @@ endobj
>>
endobj
%% Original object ID: 40 0
%% Original object ID: 41 0
36 0 obj
<<
/AP <<
@ -1406,7 +1406,7 @@ endobj
>>
endobj
%% Original object ID: 41 0
%% Original object ID: 42 0
37 0 obj
<<
/AP <<
@ -1435,7 +1435,7 @@ endobj
>>
endobj
%% Original object ID: 52 0
%% Original object ID: 53 0
38 0 obj
<<
/BBox [
@ -1467,7 +1467,7 @@ endobj
12
endobj
%% Original object ID: 53 0
%% Original object ID: 54 0
40 0 obj
<<
/BBox [
@ -1504,7 +1504,7 @@ endobj
82
endobj
%% Original object ID: 58 0
%% Original object ID: 59 0
42 0 obj
<<
/BBox [
@ -1536,7 +1536,7 @@ endobj
12
endobj
%% Original object ID: 59 0
%% Original object ID: 60 0
44 0 obj
<<
/BBox [
@ -1573,7 +1573,7 @@ endobj
82
endobj
%% Original object ID: 64 0
%% Original object ID: 65 0
46 0 obj
<<
/BBox [
@ -1605,7 +1605,7 @@ endobj
12
endobj
%% Original object ID: 65 0
%% Original object ID: 66 0
48 0 obj
<<
/BBox [
@ -1642,7 +1642,7 @@ endobj
82
endobj
%% Original object ID: 77 0
%% Original object ID: 78 0
50 0 obj
<<
/AP <<
@ -1671,7 +1671,7 @@ endobj
>>
endobj
%% Original object ID: 78 0
%% Original object ID: 79 0
51 0 obj
<<
/AP <<
@ -1700,7 +1700,7 @@ endobj
>>
endobj
%% Original object ID: 79 0
%% Original object ID: 80 0
52 0 obj
<<
/AP <<
@ -1729,7 +1729,7 @@ endobj
>>
endobj
%% Original object ID: 89 0
%% Original object ID: 90 0
53 0 obj
<<
/BBox [
@ -1768,7 +1768,7 @@ endobj
85
endobj
%% Original object ID: 93 0
%% Original object ID: 94 0
55 0 obj
<<
/BBox [
@ -1809,7 +1809,7 @@ endobj
114
endobj
%% Original object ID: 97 0
%% Original object ID: 98 0
57 0 obj
<<
/BBox [
@ -1864,7 +1864,7 @@ endobj
238
endobj
%% Original object ID: 101 0
%% Original object ID: 102 0
59 0 obj
<<
/BBox [
@ -1905,7 +1905,7 @@ endobj
117
endobj
%% Original object ID: 105 0
%% Original object ID: 106 0
61 0 obj
<<
/BBox [
@ -1946,7 +1946,7 @@ endobj
114
endobj
%% Original object ID: 118 0
%% Original object ID: 119 0
63 0 obj
<<
/BBox [
@ -1985,7 +1985,7 @@ endobj
77
endobj
%% Original object ID: 130 0
%% Original object ID: 131 0
65 0 obj
<<
/AP <<
@ -2014,7 +2014,7 @@ endobj
>>
endobj
%% Original object ID: 131 0
%% Original object ID: 132 0
66 0 obj
<<
/AP <<
@ -2043,7 +2043,7 @@ endobj
>>
endobj
%% Original object ID: 132 0
%% Original object ID: 133 0
67 0 obj
<<
/AP <<
@ -2072,7 +2072,7 @@ endobj
>>
endobj
%% Original object ID: 143 0
%% Original object ID: 144 0
68 0 obj
<<
/BBox [
@ -2104,7 +2104,7 @@ endobj
12
endobj
%% Original object ID: 144 0
%% Original object ID: 145 0
70 0 obj
<<
/BBox [
@ -2141,7 +2141,7 @@ endobj
82
endobj
%% Original object ID: 149 0
%% Original object ID: 150 0
72 0 obj
<<
/BBox [
@ -2173,7 +2173,7 @@ endobj
12
endobj
%% Original object ID: 150 0
%% Original object ID: 151 0
74 0 obj
<<
/BBox [
@ -2210,7 +2210,7 @@ endobj
82
endobj
%% Original object ID: 155 0
%% Original object ID: 156 0
76 0 obj
<<
/BBox [
@ -2242,7 +2242,7 @@ endobj
12
endobj
%% Original object ID: 156 0
%% Original object ID: 157 0
78 0 obj
<<
/BBox [
@ -2279,7 +2279,7 @@ endobj
82
endobj
%% Original object ID: 168 0
%% Original object ID: 169 0
80 0 obj
<<
/AP <<
@ -2308,7 +2308,7 @@ endobj
>>
endobj
%% Original object ID: 169 0
%% Original object ID: 170 0
81 0 obj
<<
/AP <<
@ -2337,7 +2337,7 @@ endobj
>>
endobj
%% Original object ID: 170 0
%% Original object ID: 171 0
82 0 obj
<<
/AP <<
@ -2366,7 +2366,7 @@ endobj
>>
endobj
%% Original object ID: 180 0
%% Original object ID: 181 0
83 0 obj
<<
/BBox [
@ -2405,7 +2405,7 @@ endobj
85
endobj
%% Original object ID: 184 0
%% Original object ID: 185 0
85 0 obj
<<
/BBox [
@ -2446,7 +2446,7 @@ endobj
114
endobj
%% Original object ID: 188 0
%% Original object ID: 189 0
87 0 obj
<<
/BBox [
@ -2501,7 +2501,7 @@ endobj
238
endobj
%% Original object ID: 192 0
%% Original object ID: 193 0
89 0 obj
<<
/BBox [
@ -2542,7 +2542,7 @@ endobj
117
endobj
%% Original object ID: 196 0
%% Original object ID: 197 0
91 0 obj
<<
/BBox [
@ -2583,7 +2583,7 @@ endobj
114
endobj
%% Original object ID: 111 0
%% Original object ID: 112 0
93 0 obj
<<
/AP <<
@ -2613,7 +2613,7 @@ endobj
>>
endobj
%% Original object ID: 114 0
%% Original object ID: 115 0
94 0 obj
<<
/F 28
@ -2630,7 +2630,7 @@ endobj
>>
endobj
%% Original object ID: 199 0
%% Original object ID: 200 0
95 0 obj
<<
/AP <<
@ -2660,7 +2660,7 @@ endobj
>>
endobj
%% Original object ID: 202 0
%% Original object ID: 203 0
96 0 obj
<<
/F 28
@ -2926,7 +2926,7 @@ endobj
>>
endobj
%% Original object ID: 42 0
%% Original object ID: 43 0
110 0 obj
<<
/BBox [
@ -2969,7 +2969,7 @@ endobj
220
endobj
%% Original object ID: 43 0
%% Original object ID: 44 0
112 0 obj
<<
/BBox [
@ -3001,7 +3001,7 @@ endobj
12
endobj
%% Original object ID: 44 0
%% Original object ID: 45 0
114 0 obj
<<
/BBox [
@ -3044,7 +3044,7 @@ endobj
220
endobj
%% Original object ID: 45 0
%% Original object ID: 46 0
116 0 obj
<<
/BBox [
@ -3076,7 +3076,7 @@ endobj
12
endobj
%% Original object ID: 46 0
%% Original object ID: 47 0
118 0 obj
<<
/BBox [
@ -3119,7 +3119,7 @@ endobj
220
endobj
%% Original object ID: 47 0
%% Original object ID: 48 0
120 0 obj
<<
/BBox [
@ -3151,7 +3151,7 @@ endobj
12
endobj
%% Original object ID: 80 0
%% Original object ID: 81 0
122 0 obj
<<
/BBox [
@ -3194,7 +3194,7 @@ endobj
220
endobj
%% Original object ID: 81 0
%% Original object ID: 82 0
124 0 obj
<<
/BBox [
@ -3226,7 +3226,7 @@ endobj
12
endobj
%% Original object ID: 82 0
%% Original object ID: 83 0
126 0 obj
<<
/BBox [
@ -3269,7 +3269,7 @@ endobj
220
endobj
%% Original object ID: 83 0
%% Original object ID: 84 0
128 0 obj
<<
/BBox [
@ -3301,7 +3301,7 @@ endobj
12
endobj
%% Original object ID: 84 0
%% Original object ID: 85 0
130 0 obj
<<
/BBox [
@ -3344,7 +3344,7 @@ endobj
220
endobj
%% Original object ID: 85 0
%% Original object ID: 86 0
132 0 obj
<<
/BBox [
@ -3376,7 +3376,7 @@ endobj
12
endobj
%% Original object ID: 133 0
%% Original object ID: 134 0
134 0 obj
<<
/BBox [
@ -3419,7 +3419,7 @@ endobj
220
endobj
%% Original object ID: 134 0
%% Original object ID: 135 0
136 0 obj
<<
/BBox [
@ -3451,7 +3451,7 @@ endobj
12
endobj
%% Original object ID: 135 0
%% Original object ID: 136 0
138 0 obj
<<
/BBox [
@ -3494,7 +3494,7 @@ endobj
220
endobj
%% Original object ID: 136 0
%% Original object ID: 137 0
140 0 obj
<<
/BBox [
@ -3526,7 +3526,7 @@ endobj
12
endobj
%% Original object ID: 137 0
%% Original object ID: 138 0
142 0 obj
<<
/BBox [
@ -3569,7 +3569,7 @@ endobj
220
endobj
%% Original object ID: 138 0
%% Original object ID: 139 0
144 0 obj
<<
/BBox [
@ -3601,7 +3601,7 @@ endobj
12
endobj
%% Original object ID: 171 0
%% Original object ID: 172 0
146 0 obj
<<
/BBox [
@ -3644,7 +3644,7 @@ endobj
220
endobj
%% Original object ID: 172 0
%% Original object ID: 173 0
148 0 obj
<<
/BBox [
@ -3676,7 +3676,7 @@ endobj
12
endobj
%% Original object ID: 173 0
%% Original object ID: 174 0
150 0 obj
<<
/BBox [
@ -3719,7 +3719,7 @@ endobj
220
endobj
%% Original object ID: 174 0
%% Original object ID: 175 0
152 0 obj
<<
/BBox [
@ -3751,7 +3751,7 @@ endobj
12
endobj
%% Original object ID: 175 0
%% Original object ID: 176 0
154 0 obj
<<
/BBox [
@ -3794,7 +3794,7 @@ endobj
220
endobj
%% Original object ID: 176 0
%% Original object ID: 177 0
156 0 obj
<<
/BBox [
@ -3826,7 +3826,7 @@ endobj
12
endobj
%% Original object ID: 112 0
%% Original object ID: 113 0
158 0 obj
<<
/BBox [
@ -3867,7 +3867,7 @@ endobj
929
endobj
%% Original object ID: 108 0
%% Original object ID: 109 0
160 0 obj
<<
/F 28
@ -3884,7 +3884,7 @@ endobj
>>
endobj
%% Original object ID: 109 0
%% Original object ID: 110 0
161 0 obj
<<
/AP <<
@ -3914,7 +3914,7 @@ endobj
>>
endobj
%% Original object ID: 200 0
%% Original object ID: 201 0
162 0 obj
<<
/BBox [
@ -4082,7 +4082,7 @@ endobj
>>
endobj
%% Original object ID: 110 0
%% Original object ID: 111 0
169 0 obj
<<
/BBox [