2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-25 23:02:38 +00:00

Use QPDFObjGen::set in QPDFAcroFormDocumentHelper::transformAnnotations

This commit is contained in:
m-holger 2023-01-05 14:04:41 +00:00
parent c12a6d06fc
commit e37ce44186

View File

@ -882,7 +882,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
// Now do the actual copies. // Now do the actual copies.
std::set<QPDFObjGen> added_new_fields; QPDFObjGen::set added_new_fields;
for (auto annot: old_annots.aitems()) { for (auto annot: old_annots.aitems()) {
if (annot.isStream()) { if (annot.isStream()) {
annot.warnIfPossible("ignoring annotation that's a stream"); annot.warnIfPossible("ignoring annotation that's a stream");
@ -964,73 +964,68 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
// Traverse the field, copying kids, and preserving // Traverse the field, copying kids, and preserving
// integrity. // integrity.
std::list<QPDFObjectHandle> queue; std::list<QPDFObjectHandle> queue;
QPDFObjGen::set seen;
if (maybe_copy_object(top_field)) { if (maybe_copy_object(top_field)) {
queue.push_back(top_field); queue.push_back(top_field);
} }
std::set<QPDFObjGen> seen; for (; !queue.empty(); queue.pop_front()) {
while (!queue.empty()) { auto& obj = queue.front();
QPDFObjectHandle obj = queue.front(); if (seen.add(obj)) {
queue.pop_front(); auto parent = obj.getKey("/Parent");
auto orig_og = obj.getObjGen(); if (parent.isIndirect()) {
if (seen.count(orig_og)) { auto parent_og = parent.getObjGen();
// loop if (orig_to_copy.count(parent_og)) {
break; obj.replaceKey("/Parent", orig_to_copy[parent_og]);
} } else {
seen.insert(orig_og); parent.warnIfPossible(
auto parent = obj.getKey("/Parent"); "while traversing field " +
if (parent.isIndirect()) { obj.getObjGen().unparse(',') +
auto parent_og = parent.getObjGen(); ", found parent (" + parent_og.unparse(',') +
if (orig_to_copy.count(parent_og)) { ") that had not been seen, indicating likely"
obj.replaceKey("/Parent", orig_to_copy[parent_og]); " invalid field structure");
} else {
parent.warnIfPossible(
"while traversing field " +
obj.getObjGen().unparse(',') + ", found parent (" +
parent_og.unparse(',') +
") that had not been seen, indicating likely"
" invalid field structure");
}
}
auto kids = obj.getKey("/Kids");
if (kids.isArray()) {
for (int i = 0; i < kids.getArrayNItems(); ++i) {
auto kid = kids.getArrayItem(i);
if (maybe_copy_object(kid)) {
kids.setArrayItem(i, kid);
queue.push_back(kid);
} }
} }
} auto kids = obj.getKey("/Kids");
if (kids.isArray()) {
if (override_da || override_q) { for (int i = 0; i < kids.getArrayNItems(); ++i) {
adjustInheritedFields( auto kid = kids.getArrayItem(i);
obj, if (maybe_copy_object(kid)) {
override_da, kids.setArrayItem(i, kid);
from_default_da, queue.push_back(kid);
override_q, }
from_default_q); }
} }
if (foreign) {
// Lazily initialize our /DR and the conflict map. if (override_da || override_q) {
init_dr_map(); adjustInheritedFields(
// The spec doesn't say anything about /DR on the obj,
// field, but lots of writers put one there, and override_da,
// it is frequently the same as the document-level from_default_da,
// /DR. To avoid having the field's /DR point to override_q,
// information that we are not maintaining, just from_default_q);
// reset it to that if it exists. Empirical }
// evidence suggests that many readers, including if (foreign) {
// Acrobat, Adobe Acrobat Reader, chrome, firefox, // Lazily initialize our /DR and the conflict map.
// the mac Preview application, and several of the init_dr_map();
// free readers on Linux all ignore /DR at the // The spec doesn't say anything about /DR on the
// field level. // field, but lots of writers put one there, and
if (obj.hasKey("/DR")) { // it is frequently the same as the document-level
obj.replaceKey("/DR", dr); // /DR. To avoid having the field's /DR point to
// information that we are not maintaining, just
// reset it to that if it exists. Empirical
// evidence suggests that many readers, including
// Acrobat, Adobe Acrobat Reader, chrome, firefox,
// the mac Preview application, and several of the
// free readers on Linux all ignore /DR at the
// field level.
if (obj.hasKey("/DR")) {
obj.replaceKey("/DR", dr);
}
}
if (foreign && obj.getKey("/DA").isString() &&
(!dr_map.empty())) {
adjustDefaultAppearances(obj, dr_map);
} }
}
if (foreign && obj.getKey("/DA").isString() &&
(!dr_map.empty())) {
adjustDefaultAppearances(obj, dr_map);
} }
} }
@ -1058,9 +1053,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
maybe_copy_object(annot); maybe_copy_object(annot);
// Now we have copies, so we can safely mutate. // Now we have copies, so we can safely mutate.
if (have_field && !added_new_fields.count(top_field.getObjGen())) { if (have_field && added_new_fields.add(top_field)) {
new_fields.push_back(top_field); new_fields.push_back(top_field);
added_new_fields.insert(top_field.getObjGen());
} }
new_annots.push_back(annot); new_annots.push_back(annot);