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