Commit 8e6974710cc75b3acfb592db9fb6fd8611c39732

Authored by m-holger
1 parent 250a7364

Add private method QPDF::insertFreeXrefEntry

include/qpdf/QPDF.hh
... ... @@ -1003,6 +1003,7 @@ class QPDF
1003 1003 qpdf_offset_t read_xrefStream(qpdf_offset_t offset);
1004 1004 qpdf_offset_t processXRefStream(qpdf_offset_t offset, QPDFObjectHandle& xref_stream);
1005 1005 void insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2);
  1006 + void insertFreeXrefEntry(QPDFObjGen);
1006 1007 void insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2);
1007 1008 void setLastObjectDescription(std::string const& description, QPDFObjGen const& og);
1008 1009 QPDFObjectHandle readObject(
... ...
libqpdf/QPDF.cc
... ... @@ -890,7 +890,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
890 890  
891 891 // Handle any deleted items now that we've read the /XRefStm.
892 892 for (auto const& og: deleted_items) {
893   - insertXrefEntry(og.getObj(), 0, 0, og.getGen());
  893 + insertFreeXrefEntry(og);
894 894 }
895 895  
896 896 if (cur_trailer.hasKey("/Prev")) {
... ... @@ -1088,9 +1088,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
1088 1088 if (fields[0] == 0) {
1089 1089 // Ignore fields[2], which we don't care about in this case. This works around the issue
1090 1090 // of some PDF files that put invalid values, like -1, here for deleted objects.
1091   - fields[2] = 0;
  1091 + insertFreeXrefEntry(QPDFObjGen(obj, 0));
  1092 + } else {
  1093 + insertXrefEntry(obj, toI(fields[0]), fields[1], toI(fields[2]));
1092 1094 }
1093   - insertXrefEntry(obj, toI(fields[0]), fields[1], toI(fields[2]));
1094 1095 }
1095 1096  
1096 1097 if (!m->trailer.isInitialized()) {
... ... @@ -1121,29 +1122,26 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2)
1121 1122 // If there is already an entry for this object and generation in the table, it means that a
1122 1123 // later xref table has registered this object. Disregard this one.
1123 1124  
1124   - QPDFObjGen og(obj, (f0 == 2 ? 0 : f2));
1125   - if (m->xref_table.count(og)) {
1126   - QTC::TC("qpdf", "QPDF xref reused object");
1127   - return;
1128   - }
1129 1125 if (m->deleted_objects.count(obj)) {
1130 1126 QTC::TC("qpdf", "QPDF xref deleted object");
1131 1127 return;
1132 1128 }
1133 1129  
1134   - switch (f0) {
1135   - case 0:
1136   - m->deleted_objects.insert(obj);
1137   - break;
  1130 + auto [iter, created] = m->xref_table.try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2)));
  1131 + if (!created) {
  1132 + QTC::TC("qpdf", "QPDF xref reused object");
  1133 + return;
  1134 + }
1138 1135  
  1136 + switch (f0) {
1139 1137 case 1:
1140 1138 // f2 is generation
1141 1139 QTC::TC("qpdf", "QPDF xref gen > 0", ((f2 > 0) ? 1 : 0));
1142   - m->xref_table[og] = QPDFXRefEntry(f1);
  1140 + iter->second = QPDFXRefEntry(f1);
1143 1141 break;
1144 1142  
1145 1143 case 2:
1146   - m->xref_table[og] = QPDFXRefEntry(toI(f1), f2);
  1144 + iter->second = QPDFXRefEntry(toI(f1), f2);
1147 1145 break;
1148 1146  
1149 1147 default:
... ... @@ -1152,6 +1150,14 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2)
1152 1150 }
1153 1151 }
1154 1152  
  1153 +void
  1154 +QPDF::insertFreeXrefEntry(QPDFObjGen og)
  1155 +{
  1156 + if (!m->xref_table.count(og)) {
  1157 + m->deleted_objects.insert(og.getObj());
  1158 + }
  1159 +}
  1160 +
1155 1161 // Replace uncompressed object. This is used in xref recovery mode, which reads the file from
1156 1162 // beginning to end.
1157 1163 void
... ...