Commit 1e072e223a61d26b612864978b21aac6a0d0dc19

Authored by m-holger
1 parent 0ac37bc9

Move QPDF::insertXrefEntry etc to QPDF::Xref_table

include/qpdf/QPDF.hh
@@ -777,9 +777,6 @@ class QPDF @@ -777,9 +777,6 @@ class QPDF
777 QPDFObjectHandle& dict, 777 QPDFObjectHandle& dict,
778 int max_num_entries, 778 int max_num_entries,
779 std::function<QPDFExc(std::string_view)> damaged); 779 std::function<QPDFExc(std::string_view)> damaged);
780 - void insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2);  
781 - void insertFreeXrefEntry(QPDFObjGen);  
782 - void insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2);  
783 void setLastObjectDescription(std::string const& description, QPDFObjGen const& og); 780 void setLastObjectDescription(std::string const& description, QPDFObjGen const& og);
784 QPDFObjectHandle readTrailer(); 781 QPDFObjectHandle readTrailer();
785 QPDFObjectHandle readObject(std::string const& description, QPDFObjGen og); 782 QPDFObjectHandle readObject(std::string const& description, QPDFObjGen og);
libqpdf/QPDF.cc
@@ -196,15 +196,16 @@ QPDF::EncryptionParameters::EncryptionParameters() : @@ -196,15 +196,16 @@ QPDF::EncryptionParameters::EncryptionParameters() :
196 { 196 {
197 } 197 }
198 198
199 -QPDF::Members::Members() : 199 +QPDF::Members::Members(QPDF& qpdf) :
200 log(QPDFLogger::defaultLogger()), 200 log(QPDFLogger::defaultLogger()),
201 file(new InvalidInputSource()), 201 file(new InvalidInputSource()),
202 - encp(new EncryptionParameters) 202 + encp(new EncryptionParameters),
  203 + xref_table(qpdf)
203 { 204 {
204 } 205 }
205 206
206 QPDF::QPDF() : 207 QPDF::QPDF() :
207 - m(new Members()) 208 + m(new Members(*this))
208 { 209 {
209 m->tokenizer.allowEOF(); 210 m->tokenizer.allowEOF();
210 // Generate a unique ID. It just has to be unique among all QPDF objects allocated throughout 211 // Generate a unique ID. It just has to be unique among all QPDF objects allocated throughout
@@ -585,7 +586,7 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -585,7 +586,7 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
585 int obj = QUtil::string_to_int(t1.getValue().c_str()); 586 int obj = QUtil::string_to_int(t1.getValue().c_str());
586 int gen = QUtil::string_to_int(t2.getValue().c_str()); 587 int gen = QUtil::string_to_int(t2.getValue().c_str());
587 if (obj <= m->xref_table.max_id) { 588 if (obj <= m->xref_table.max_id) {
588 - insertReconstructedXrefEntry(obj, token_start, gen); 589 + m->xref_table.insert_reconstructed(obj, token_start, gen);
589 } else { 590 } else {
590 warn(damagedPDF( 591 warn(damagedPDF(
591 "", 0, "ignoring object with impossibly large id " + std::to_string(obj))); 592 "", 0, "ignoring object with impossibly large id " + std::to_string(obj)));
@@ -981,9 +982,9 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -981,9 +982,9 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
981 "xref table", "invalid xref entry (obj=" + std::to_string(i) + ")"); 982 "xref table", "invalid xref entry (obj=" + std::to_string(i) + ")");
982 } 983 }
983 if (type == 'f') { 984 if (type == 'f') {
984 - insertFreeXrefEntry(QPDFObjGen(toI(i), f2)); 985 + m->xref_table.insert_free(QPDFObjGen(toI(i), f2));
985 } else { 986 } else {
986 - insertXrefEntry(toI(i), 1, f1, f2); 987 + m->xref_table.insert(toI(i), 1, f1, f2);
987 } 988 }
988 } 989 }
989 qpdf_offset_t pos = m->file->tell(); 990 qpdf_offset_t pos = m->file->tell();
@@ -1251,9 +1252,9 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1251,9 +1252,9 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1251 // Ignore fields[2], which we don't care about in this case. This works around the 1252 // Ignore fields[2], which we don't care about in this case. This works around the
1252 // issue of some PDF files that put invalid values, like -1, here for deleted 1253 // issue of some PDF files that put invalid values, like -1, here for deleted
1253 // objects. 1254 // objects.
1254 - insertFreeXrefEntry(QPDFObjGen(obj, 0)); 1255 + m->xref_table.insert_free(QPDFObjGen(obj, 0));
1255 } else { 1256 } else {
1256 - insertXrefEntry(obj, toI(fields[0]), fields[1], toI(fields[2])); 1257 + m->xref_table.insert(obj, toI(fields[0]), fields[1], toI(fields[2]));
1257 } 1258 }
1258 ++obj; 1259 ++obj;
1259 } 1260 }
@@ -1276,7 +1277,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1276,7 +1277,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1276 } 1277 }
1277 1278
1278 void 1279 void
1279 -QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) 1280 +QPDF::Xref_table::insert(int obj, int f0, qpdf_offset_t f1, int f2)
1280 { 1281 {
1281 // Populate the xref table in such a way that the first reference to an object that we see, 1282 // Populate the xref table in such a way that the first reference to an object that we see,
1282 // which is the one in the latest xref table in which it appears, is the one that gets stored. 1283 // which is the one in the latest xref table in which it appears, is the one that gets stored.
@@ -1285,22 +1286,23 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) @@ -1285,22 +1286,23 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2)
1285 // If there is already an entry for this object and generation in the table, it means that a 1286 // If there is already an entry for this object and generation in the table, it means that a
1286 // later xref table has registered this object. Disregard this one. 1287 // later xref table has registered this object. Disregard this one.
1287 1288
1288 - if (obj > m->xref_table.max_id) { 1289 + if (obj > max_id) {
1289 // ignore impossibly large object ids or object ids > Size. 1290 // ignore impossibly large object ids or object ids > Size.
1290 return; 1291 return;
1291 } 1292 }
1292 1293
1293 - if (m->xref_table.deleted_objects.count(obj)) { 1294 + if (deleted_objects.count(obj)) {
1294 QTC::TC("qpdf", "QPDF xref deleted object"); 1295 QTC::TC("qpdf", "QPDF xref deleted object");
1295 return; 1296 return;
1296 } 1297 }
1297 1298
1298 if (f0 == 2 && static_cast<int>(f1) == obj) { 1299 if (f0 == 2 && static_cast<int>(f1) == obj) {
1299 - warn(damagedPDF("xref stream", "self-referential object stream " + std::to_string(obj))); 1300 + qpdf.warn(qpdf.damagedPDF(
  1301 + "xref stream", "self-referential object stream " + std::to_string(obj)));
1300 return; 1302 return;
1301 } 1303 }
1302 1304
1303 - auto [iter, created] = m->xref_table.try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2))); 1305 + auto [iter, created] = try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2)));
1304 if (!created) { 1306 if (!created) {
1305 QTC::TC("qpdf", "QPDF xref reused object"); 1307 QTC::TC("qpdf", "QPDF xref reused object");
1306 return; 1308 return;
@@ -1318,35 +1320,36 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2) @@ -1318,35 +1320,36 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2)
1318 break; 1320 break;
1319 1321
1320 default: 1322 default:
1321 - throw damagedPDF("xref stream", "unknown xref stream entry type " + std::to_string(f0)); 1323 + throw qpdf.damagedPDF(
  1324 + "xref stream", "unknown xref stream entry type " + std::to_string(f0));
1322 break; 1325 break;
1323 } 1326 }
1324 } 1327 }
1325 1328
1326 void 1329 void
1327 -QPDF::insertFreeXrefEntry(QPDFObjGen og) 1330 +QPDF::Xref_table::insert_free(QPDFObjGen og)
1328 { 1331 {
1329 - if (!m->xref_table.count(og)) {  
1330 - m->xref_table.deleted_objects.insert(og.getObj()); 1332 + if (!count(og)) {
  1333 + deleted_objects.insert(og.getObj());
1331 } 1334 }
1332 } 1335 }
1333 1336
1334 // Replace uncompressed object. This is used in xref recovery mode, which reads the file from 1337 // Replace uncompressed object. This is used in xref recovery mode, which reads the file from
1335 // beginning to end. 1338 // beginning to end.
1336 void 1339 void
1337 -QPDF::insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2) 1340 +QPDF::Xref_table::insert_reconstructed(int obj, qpdf_offset_t f1, int f2)
1338 { 1341 {
1339 - if (!(obj > 0 && obj <= m->xref_table.max_id && 0 <= f2 && f2 < 65535)) { 1342 + if (!(obj > 0 && obj <= max_id && 0 <= f2 && f2 < 65535)) {
1340 QTC::TC("qpdf", "QPDF xref overwrite invalid objgen"); 1343 QTC::TC("qpdf", "QPDF xref overwrite invalid objgen");
1341 return; 1344 return;
1342 } 1345 }
1343 1346
1344 QPDFObjGen og(obj, f2); 1347 QPDFObjGen og(obj, f2);
1345 - if (!m->xref_table.deleted_objects.count(obj)) { 1348 + if (!deleted_objects.count(obj)) {
1346 // deleted_objects stores the uncompressed objects removed from the xref table at the start 1349 // deleted_objects stores the uncompressed objects removed from the xref table at the start
1347 // of recovery. 1350 // of recovery.
1348 QTC::TC("qpdf", "QPDF xref overwrite object"); 1351 QTC::TC("qpdf", "QPDF xref overwrite object");
1349 - m->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f1); 1352 + insert_or_assign(QPDFObjGen(obj, f2), QPDFXRefEntry(f1));
1350 } 1353 }
1351 } 1354 }
1352 1355
libqpdf/qpdf/QPDF_private.hh
@@ -7,6 +7,15 @@ @@ -7,6 +7,15 @@
7 class QPDF::Xref_table: public std::map<QPDFObjGen, QPDFXRefEntry> 7 class QPDF::Xref_table: public std::map<QPDFObjGen, QPDFXRefEntry>
8 { 8 {
9 public: 9 public:
  10 + Xref_table(QPDF& qpdf) :
  11 + qpdf(qpdf)
  12 + {
  13 + }
  14 +
  15 + void insert_reconstructed(int obj, qpdf_offset_t f1, int f2);
  16 + void insert(int obj, int f0, qpdf_offset_t f1, int f2);
  17 + void insert_free(QPDFObjGen);
  18 +
10 QPDFObjectHandle trailer; 19 QPDFObjectHandle trailer;
11 bool reconstructed{false}; 20 bool reconstructed{false};
12 // Various tables are indexed by object id, with potential size id + 1 21 // Various tables are indexed by object id, with potential size id + 1
@@ -20,6 +29,9 @@ class QPDF::Xref_table: public std::map&lt;QPDFObjGen, QPDFXRefEntry&gt; @@ -20,6 +29,9 @@ class QPDF::Xref_table: public std::map&lt;QPDFObjGen, QPDFXRefEntry&gt;
20 // Linearization data 29 // Linearization data
21 bool uncompressed_after_compressed{false}; 30 bool uncompressed_after_compressed{false};
22 qpdf_offset_t first_item_offset{0}; // actual value from file 31 qpdf_offset_t first_item_offset{0}; // actual value from file
  32 +
  33 + private:
  34 + QPDF& qpdf;
23 }; 35 };
24 36
25 // Writer class is restricted to QPDFWriter so that only it can call certain methods. 37 // Writer class is restricted to QPDFWriter so that only it can call certain methods.
@@ -469,7 +481,7 @@ class QPDF::Members @@ -469,7 +481,7 @@ class QPDF::Members
469 ~Members() = default; 481 ~Members() = default;
470 482
471 private: 483 private:
472 - Members(); 484 + Members(QPDF& qpdf);
473 Members(Members const&) = delete; 485 Members(Members const&) = delete;
474 486
475 std::shared_ptr<QPDFLogger> log; 487 std::shared_ptr<QPDFLogger> log;