Commit e37ce44186b74d88551d1e8814141776cd15463e
1 parent
c12a6d06
Use QPDFObjGen::set in QPDFAcroFormDocumentHelper::transformAnnotations
Showing
1 changed file
with
56 additions
and
62 deletions
libqpdf/QPDFAcroFormDocumentHelper.cc
| @@ -882,7 +882,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( | @@ -882,7 +882,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( | ||
| 882 | 882 | ||
| 883 | // Now do the actual copies. | 883 | // Now do the actual copies. |
| 884 | 884 | ||
| 885 | - std::set<QPDFObjGen> added_new_fields; | 885 | + QPDFObjGen::set added_new_fields; |
| 886 | for (auto annot: old_annots.aitems()) { | 886 | for (auto annot: old_annots.aitems()) { |
| 887 | if (annot.isStream()) { | 887 | if (annot.isStream()) { |
| 888 | annot.warnIfPossible("ignoring annotation that's a stream"); | 888 | annot.warnIfPossible("ignoring annotation that's a stream"); |
| @@ -964,73 +964,68 @@ QPDFAcroFormDocumentHelper::transformAnnotations( | @@ -964,73 +964,68 @@ QPDFAcroFormDocumentHelper::transformAnnotations( | ||
| 964 | // Traverse the field, copying kids, and preserving | 964 | // Traverse the field, copying kids, and preserving |
| 965 | // integrity. | 965 | // integrity. |
| 966 | std::list<QPDFObjectHandle> queue; | 966 | std::list<QPDFObjectHandle> queue; |
| 967 | + QPDFObjGen::set seen; | ||
| 967 | if (maybe_copy_object(top_field)) { | 968 | if (maybe_copy_object(top_field)) { |
| 968 | queue.push_back(top_field); | 969 | queue.push_back(top_field); |
| 969 | } | 970 | } |
| 970 | - std::set<QPDFObjGen> seen; | ||
| 971 | - while (!queue.empty()) { | ||
| 972 | - QPDFObjectHandle obj = queue.front(); | ||
| 973 | - queue.pop_front(); | ||
| 974 | - auto orig_og = obj.getObjGen(); | ||
| 975 | - if (seen.count(orig_og)) { | ||
| 976 | - // loop | ||
| 977 | - break; | ||
| 978 | - } | ||
| 979 | - seen.insert(orig_og); | ||
| 980 | - auto parent = obj.getKey("/Parent"); | ||
| 981 | - if (parent.isIndirect()) { | ||
| 982 | - auto parent_og = parent.getObjGen(); | ||
| 983 | - if (orig_to_copy.count(parent_og)) { | ||
| 984 | - obj.replaceKey("/Parent", orig_to_copy[parent_og]); | ||
| 985 | - } else { | ||
| 986 | - parent.warnIfPossible( | ||
| 987 | - "while traversing field " + | ||
| 988 | - obj.getObjGen().unparse(',') + ", found parent (" + | ||
| 989 | - parent_og.unparse(',') + | ||
| 990 | - ") that had not been seen, indicating likely" | ||
| 991 | - " invalid field structure"); | 971 | + for (; !queue.empty(); queue.pop_front()) { |
| 972 | + auto& obj = queue.front(); | ||
| 973 | + if (seen.add(obj)) { | ||
| 974 | + auto parent = obj.getKey("/Parent"); | ||
| 975 | + if (parent.isIndirect()) { | ||
| 976 | + auto parent_og = parent.getObjGen(); | ||
| 977 | + if (orig_to_copy.count(parent_og)) { | ||
| 978 | + obj.replaceKey("/Parent", orig_to_copy[parent_og]); | ||
| 979 | + } else { | ||
| 980 | + parent.warnIfPossible( | ||
| 981 | + "while traversing field " + | ||
| 982 | + obj.getObjGen().unparse(',') + | ||
| 983 | + ", found parent (" + parent_og.unparse(',') + | ||
| 984 | + ") that had not been seen, indicating likely" | ||
| 985 | + " invalid field structure"); | ||
| 986 | + } | ||
| 992 | } | 987 | } |
| 993 | - } | ||
| 994 | - auto kids = obj.getKey("/Kids"); | ||
| 995 | - if (kids.isArray()) { | ||
| 996 | - for (int i = 0; i < kids.getArrayNItems(); ++i) { | ||
| 997 | - auto kid = kids.getArrayItem(i); | ||
| 998 | - if (maybe_copy_object(kid)) { | ||
| 999 | - kids.setArrayItem(i, kid); | ||
| 1000 | - queue.push_back(kid); | 988 | + auto kids = obj.getKey("/Kids"); |
| 989 | + if (kids.isArray()) { | ||
| 990 | + for (int i = 0; i < kids.getArrayNItems(); ++i) { | ||
| 991 | + auto kid = kids.getArrayItem(i); | ||
| 992 | + if (maybe_copy_object(kid)) { | ||
| 993 | + kids.setArrayItem(i, kid); | ||
| 994 | + queue.push_back(kid); | ||
| 995 | + } | ||
| 1001 | } | 996 | } |
| 1002 | } | 997 | } |
| 1003 | - } | ||
| 1004 | 998 | ||
| 1005 | - if (override_da || override_q) { | ||
| 1006 | - adjustInheritedFields( | ||
| 1007 | - obj, | ||
| 1008 | - override_da, | ||
| 1009 | - from_default_da, | ||
| 1010 | - override_q, | ||
| 1011 | - from_default_q); | ||
| 1012 | - } | ||
| 1013 | - if (foreign) { | ||
| 1014 | - // Lazily initialize our /DR and the conflict map. | ||
| 1015 | - init_dr_map(); | ||
| 1016 | - // The spec doesn't say anything about /DR on the | ||
| 1017 | - // field, but lots of writers put one there, and | ||
| 1018 | - // it is frequently the same as the document-level | ||
| 1019 | - // /DR. To avoid having the field's /DR point to | ||
| 1020 | - // information that we are not maintaining, just | ||
| 1021 | - // reset it to that if it exists. Empirical | ||
| 1022 | - // evidence suggests that many readers, including | ||
| 1023 | - // Acrobat, Adobe Acrobat Reader, chrome, firefox, | ||
| 1024 | - // the mac Preview application, and several of the | ||
| 1025 | - // free readers on Linux all ignore /DR at the | ||
| 1026 | - // field level. | ||
| 1027 | - if (obj.hasKey("/DR")) { | ||
| 1028 | - obj.replaceKey("/DR", dr); | 999 | + if (override_da || override_q) { |
| 1000 | + adjustInheritedFields( | ||
| 1001 | + obj, | ||
| 1002 | + override_da, | ||
| 1003 | + from_default_da, | ||
| 1004 | + override_q, | ||
| 1005 | + from_default_q); | ||
| 1006 | + } | ||
| 1007 | + if (foreign) { | ||
| 1008 | + // Lazily initialize our /DR and the conflict map. | ||
| 1009 | + init_dr_map(); | ||
| 1010 | + // The spec doesn't say anything about /DR on the | ||
| 1011 | + // field, but lots of writers put one there, and | ||
| 1012 | + // it is frequently the same as the document-level | ||
| 1013 | + // /DR. To avoid having the field's /DR point to | ||
| 1014 | + // information that we are not maintaining, just | ||
| 1015 | + // reset it to that if it exists. Empirical | ||
| 1016 | + // evidence suggests that many readers, including | ||
| 1017 | + // Acrobat, Adobe Acrobat Reader, chrome, firefox, | ||
| 1018 | + // the mac Preview application, and several of the | ||
| 1019 | + // free readers on Linux all ignore /DR at the | ||
| 1020 | + // field level. | ||
| 1021 | + if (obj.hasKey("/DR")) { | ||
| 1022 | + obj.replaceKey("/DR", dr); | ||
| 1023 | + } | ||
| 1024 | + } | ||
| 1025 | + if (foreign && obj.getKey("/DA").isString() && | ||
| 1026 | + (!dr_map.empty())) { | ||
| 1027 | + adjustDefaultAppearances(obj, dr_map); | ||
| 1029 | } | 1028 | } |
| 1030 | - } | ||
| 1031 | - if (foreign && obj.getKey("/DA").isString() && | ||
| 1032 | - (!dr_map.empty())) { | ||
| 1033 | - adjustDefaultAppearances(obj, dr_map); | ||
| 1034 | } | 1029 | } |
| 1035 | } | 1030 | } |
| 1036 | 1031 | ||
| @@ -1058,9 +1053,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations( | @@ -1058,9 +1053,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations( | ||
| 1058 | maybe_copy_object(annot); | 1053 | maybe_copy_object(annot); |
| 1059 | 1054 | ||
| 1060 | // Now we have copies, so we can safely mutate. | 1055 | // Now we have copies, so we can safely mutate. |
| 1061 | - if (have_field && !added_new_fields.count(top_field.getObjGen())) { | 1056 | + if (have_field && added_new_fields.add(top_field)) { |
| 1062 | new_fields.push_back(top_field); | 1057 | new_fields.push_back(top_field); |
| 1063 | - added_new_fields.insert(top_field.getObjGen()); | ||
| 1064 | } | 1058 | } |
| 1065 | new_annots.push_back(annot); | 1059 | new_annots.push_back(annot); |
| 1066 | 1060 |