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 777 QPDFObjectHandle& dict,
778 778 int max_num_entries,
779 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 780 void setLastObjectDescription(std::string const& description, QPDFObjGen const& og);
784 781 QPDFObjectHandle readTrailer();
785 782 QPDFObjectHandle readObject(std::string const& description, QPDFObjGen og);
... ...
libqpdf/QPDF.cc
... ... @@ -196,15 +196,16 @@ QPDF::EncryptionParameters::EncryptionParameters() :
196 196 {
197 197 }
198 198  
199   -QPDF::Members::Members() :
  199 +QPDF::Members::Members(QPDF& qpdf) :
200 200 log(QPDFLogger::defaultLogger()),
201 201 file(new InvalidInputSource()),
202   - encp(new EncryptionParameters)
  202 + encp(new EncryptionParameters),
  203 + xref_table(qpdf)
203 204 {
204 205 }
205 206  
206 207 QPDF::QPDF() :
207   - m(new Members())
  208 + m(new Members(*this))
208 209 {
209 210 m->tokenizer.allowEOF();
210 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 586 int obj = QUtil::string_to_int(t1.getValue().c_str());
586 587 int gen = QUtil::string_to_int(t2.getValue().c_str());
587 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 590 } else {
590 591 warn(damagedPDF(
591 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 982 "xref table", "invalid xref entry (obj=" + std::to_string(i) + ")");
982 983 }
983 984 if (type == 'f') {
984   - insertFreeXrefEntry(QPDFObjGen(toI(i), f2));
  985 + m->xref_table.insert_free(QPDFObjGen(toI(i), f2));
985 986 } else {
986   - insertXrefEntry(toI(i), 1, f1, f2);
  987 + m->xref_table.insert(toI(i), 1, f1, f2);
987 988 }
988 989 }
989 990 qpdf_offset_t pos = m->file->tell();
... ... @@ -1251,9 +1252,9 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1251 1252 // Ignore fields[2], which we don't care about in this case. This works around the
1252 1253 // issue of some PDF files that put invalid values, like -1, here for deleted
1253 1254 // objects.
1254   - insertFreeXrefEntry(QPDFObjGen(obj, 0));
  1255 + m->xref_table.insert_free(QPDFObjGen(obj, 0));
1255 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 1259 ++obj;
1259 1260 }
... ... @@ -1276,7 +1277,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1276 1277 }
1277 1278  
1278 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 1282 // Populate the xref table in such a way that the first reference to an object that we see,
1282 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 1286 // If there is already an entry for this object and generation in the table, it means that a
1286 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 1290 // ignore impossibly large object ids or object ids > Size.
1290 1291 return;
1291 1292 }
1292 1293  
1293   - if (m->xref_table.deleted_objects.count(obj)) {
  1294 + if (deleted_objects.count(obj)) {
1294 1295 QTC::TC("qpdf", "QPDF xref deleted object");
1295 1296 return;
1296 1297 }
1297 1298  
1298 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 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 1306 if (!created) {
1305 1307 QTC::TC("qpdf", "QPDF xref reused object");
1306 1308 return;
... ... @@ -1318,35 +1320,36 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2)
1318 1320 break;
1319 1321  
1320 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 1325 break;
1323 1326 }
1324 1327 }
1325 1328  
1326 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 1337 // Replace uncompressed object. This is used in xref recovery mode, which reads the file from
1335 1338 // beginning to end.
1336 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 1343 QTC::TC("qpdf", "QPDF xref overwrite invalid objgen");
1341 1344 return;
1342 1345 }
1343 1346  
1344 1347 QPDFObjGen og(obj, f2);
1345   - if (!m->xref_table.deleted_objects.count(obj)) {
  1348 + if (!deleted_objects.count(obj)) {
1346 1349 // deleted_objects stores the uncompressed objects removed from the xref table at the start
1347 1350 // of recovery.
1348 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 7 class QPDF::Xref_table: public std::map<QPDFObjGen, QPDFXRefEntry>
8 8 {
9 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 19 QPDFObjectHandle trailer;
11 20 bool reconstructed{false};
12 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 29 // Linearization data
21 30 bool uncompressed_after_compressed{false};
22 31 qpdf_offset_t first_item_offset{0}; // actual value from file
  32 +
  33 + private:
  34 + QPDF& qpdf;
23 35 };
24 36  
25 37 // Writer class is restricted to QPDFWriter so that only it can call certain methods.
... ... @@ -469,7 +481,7 @@ class QPDF::Members
469 481 ~Members() = default;
470 482  
471 483 private:
472   - Members();
  484 + Members(QPDF& qpdf);
473 485 Members(Members const&) = delete;
474 486  
475 487 std::shared_ptr<QPDFLogger> log;
... ...