Commit bee726609c9b0c3f6bc497de9ab0fc0790993c89
1 parent
2bf7359e
Remove redundant parameters from QPDF::readObject
Showing
2 changed files
with
30 additions
and
44 deletions
include/qpdf/QPDF.hh
| @@ -1006,11 +1006,7 @@ class QPDF | @@ -1006,11 +1006,7 @@ class QPDF | ||
| 1006 | void insertFreeXrefEntry(QPDFObjGen); | 1006 | void insertFreeXrefEntry(QPDFObjGen); |
| 1007 | void insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2); | 1007 | void insertReconstructedXrefEntry(int obj, qpdf_offset_t f1, int f2); |
| 1008 | void setLastObjectDescription(std::string const& description, QPDFObjGen const& og); | 1008 | void setLastObjectDescription(std::string const& description, QPDFObjGen const& og); |
| 1009 | - QPDFObjectHandle readObject( | ||
| 1010 | - std::shared_ptr<InputSource>, | ||
| 1011 | - std::string const& description, | ||
| 1012 | - QPDFObjGen const& og, | ||
| 1013 | - bool in_object_stream); | 1009 | + QPDFObjectHandle readObject(std::string const& description, QPDFObjGen og); |
| 1014 | QPDFObjectHandle readObjectInStream(std::shared_ptr<InputSource>, QPDFObjGen og); | 1010 | QPDFObjectHandle readObjectInStream(std::shared_ptr<InputSource>, QPDFObjGen og); |
| 1015 | size_t recoverStreamLength( | 1011 | size_t recoverStreamLength( |
| 1016 | std::shared_ptr<InputSource> input, QPDFObjGen const& og, qpdf_offset_t stream_offset); | 1012 | std::shared_ptr<InputSource> input, QPDFObjGen const& og, qpdf_offset_t stream_offset); |
libqpdf/QPDF.cc
| @@ -567,7 +567,7 @@ QPDF::reconstruct_xref(QPDFExc& e) | @@ -567,7 +567,7 @@ QPDF::reconstruct_xref(QPDFExc& e) | ||
| 567 | insertReconstructedXrefEntry(obj, token_start, gen); | 567 | insertReconstructedXrefEntry(obj, token_start, gen); |
| 568 | } | 568 | } |
| 569 | } else if (!m->trailer.isInitialized() && t1.isWord("trailer")) { | 569 | } else if (!m->trailer.isInitialized() && t1.isWord("trailer")) { |
| 570 | - QPDFObjectHandle t = readObject(m->file, "trailer", QPDFObjGen(), false); | 570 | + QPDFObjectHandle t = readObject("trailer", QPDFObjGen()); |
| 571 | if (!t.isDictionary()) { | 571 | if (!t.isDictionary()) { |
| 572 | // Oh well. It was worth a try. | 572 | // Oh well. It was worth a try. |
| 573 | } else { | 573 | } else { |
| @@ -855,7 +855,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) | @@ -855,7 +855,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) | ||
| 855 | } | 855 | } |
| 856 | 856 | ||
| 857 | // Set offset to previous xref table if any | 857 | // Set offset to previous xref table if any |
| 858 | - QPDFObjectHandle cur_trailer = readObject(m->file, "trailer", QPDFObjGen(), false); | 858 | + QPDFObjectHandle cur_trailer = readObject("trailer", QPDFObjGen()); |
| 859 | if (!cur_trailer.isDictionary()) { | 859 | if (!cur_trailer.isDictionary()) { |
| 860 | QTC::TC("qpdf", "QPDF missing trailer"); | 860 | QTC::TC("qpdf", "QPDF missing trailer"); |
| 861 | throw damagedPDF("", "expected trailer dictionary"); | 861 | throw damagedPDF("", "expected trailer dictionary"); |
| @@ -1268,32 +1268,28 @@ QPDF::setLastObjectDescription(std::string const& description, QPDFObjGen const& | @@ -1268,32 +1268,28 @@ QPDF::setLastObjectDescription(std::string const& description, QPDFObjGen const& | ||
| 1268 | } | 1268 | } |
| 1269 | 1269 | ||
| 1270 | QPDFObjectHandle | 1270 | QPDFObjectHandle |
| 1271 | -QPDF::readObject( | ||
| 1272 | - std::shared_ptr<InputSource> input, | ||
| 1273 | - std::string const& description, | ||
| 1274 | - QPDFObjGen const& og, | ||
| 1275 | - bool in_object_stream) | 1271 | +QPDF::readObject(std::string const& description, QPDFObjGen og) |
| 1276 | { | 1272 | { |
| 1277 | setLastObjectDescription(description, og); | 1273 | setLastObjectDescription(description, og); |
| 1278 | - qpdf_offset_t offset = input->tell(); | 1274 | + qpdf_offset_t offset = m->file->tell(); |
| 1279 | 1275 | ||
| 1280 | bool empty = false; | 1276 | bool empty = false; |
| 1281 | std::shared_ptr<StringDecrypter> decrypter_ph; | 1277 | std::shared_ptr<StringDecrypter> decrypter_ph; |
| 1282 | StringDecrypter* decrypter = nullptr; | 1278 | StringDecrypter* decrypter = nullptr; |
| 1283 | - if (m->encp->encrypted && (!in_object_stream)) { | 1279 | + if (m->encp->encrypted) { |
| 1284 | decrypter_ph = std::make_shared<StringDecrypter>(this, og); | 1280 | decrypter_ph = std::make_shared<StringDecrypter>(this, og); |
| 1285 | decrypter = decrypter_ph.get(); | 1281 | decrypter = decrypter_ph.get(); |
| 1286 | } | 1282 | } |
| 1287 | - auto object = QPDFParser(input, m->last_object_description, m->tokenizer, decrypter, this) | 1283 | + auto object = QPDFParser(m->file, m->last_object_description, m->tokenizer, decrypter, this) |
| 1288 | .parse(empty, false); | 1284 | .parse(empty, false); |
| 1289 | if (empty) { | 1285 | if (empty) { |
| 1290 | // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in | 1286 | // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in |
| 1291 | // actual PDF files and Adobe Reader appears to ignore them. | 1287 | // actual PDF files and Adobe Reader appears to ignore them. |
| 1292 | - warn(damagedPDF(input, input->getLastOffset(), "empty object treated as null")); | ||
| 1293 | - } else if (object.isDictionary() && (!in_object_stream)) { | 1288 | + warn(damagedPDF(m->file, m->file->getLastOffset(), "empty object treated as null")); |
| 1289 | + } else if (object.isDictionary()) { | ||
| 1294 | // check for stream | 1290 | // check for stream |
| 1295 | - qpdf_offset_t cur_offset = input->tell(); | ||
| 1296 | - if (readToken(input).isWord("stream")) { | 1291 | + qpdf_offset_t cur_offset = m->file->tell(); |
| 1292 | + if (readToken(m->file).isWord("stream")) { | ||
| 1297 | // The PDF specification states that the word "stream" should be followed by either a | 1293 | // The PDF specification states that the word "stream" should be followed by either a |
| 1298 | // carriage return and a newline or by a newline alone. It specifically disallowed | 1294 | // carriage return and a newline or by a newline alone. It specifically disallowed |
| 1299 | // following it by a carriage return alone since, in that case, there would be no way to | 1295 | // following it by a carriage return alone since, in that case, there would be no way to |
| @@ -1305,7 +1301,7 @@ QPDF::readObject( | @@ -1305,7 +1301,7 @@ QPDF::readObject( | ||
| 1305 | while (!done) { | 1301 | while (!done) { |
| 1306 | done = true; | 1302 | done = true; |
| 1307 | char ch; | 1303 | char ch; |
| 1308 | - if (input->read(&ch, 1) == 0) { | 1304 | + if (m->file->read(&ch, 1) == 0) { |
| 1309 | // A premature EOF here will result in some other problem that will get reported | 1305 | // A premature EOF here will result in some other problem that will get reported |
| 1310 | // at another time. | 1306 | // at another time. |
| 1311 | } else if (ch == '\n') { | 1307 | } else if (ch == '\n') { |
| @@ -1313,7 +1309,7 @@ QPDF::readObject( | @@ -1313,7 +1309,7 @@ QPDF::readObject( | ||
| 1313 | QTC::TC("qpdf", "QPDF stream with NL only"); | 1309 | QTC::TC("qpdf", "QPDF stream with NL only"); |
| 1314 | } else if (ch == '\r') { | 1310 | } else if (ch == '\r') { |
| 1315 | // Read another character | 1311 | // Read another character |
| 1316 | - if (input->read(&ch, 1) != 0) { | 1312 | + if (m->file->read(&ch, 1) != 0) { |
| 1317 | if (ch == '\n') { | 1313 | if (ch == '\n') { |
| 1318 | // Ready to read stream data | 1314 | // Ready to read stream data |
| 1319 | QTC::TC("qpdf", "QPDF stream with CRNL"); | 1315 | QTC::TC("qpdf", "QPDF stream with CRNL"); |
| @@ -1321,32 +1317,27 @@ QPDF::readObject( | @@ -1321,32 +1317,27 @@ QPDF::readObject( | ||
| 1321 | // Treat the \r by itself as the whitespace after endstream and start | 1317 | // Treat the \r by itself as the whitespace after endstream and start |
| 1322 | // reading stream data in spite of not having seen a newline. | 1318 | // reading stream data in spite of not having seen a newline. |
| 1323 | QTC::TC("qpdf", "QPDF stream with CR only"); | 1319 | QTC::TC("qpdf", "QPDF stream with CR only"); |
| 1324 | - input->unreadCh(ch); | 1320 | + m->file->unreadCh(ch); |
| 1325 | warn(damagedPDF( | 1321 | warn(damagedPDF( |
| 1326 | - input, | ||
| 1327 | - input->tell(), | ||
| 1328 | - "stream keyword followed by carriage return " | ||
| 1329 | - "only")); | 1322 | + m->file->tell(), |
| 1323 | + "stream keyword followed by carriage return only")); | ||
| 1330 | } | 1324 | } |
| 1331 | } | 1325 | } |
| 1332 | } else if (QUtil::is_space(ch)) { | 1326 | } else if (QUtil::is_space(ch)) { |
| 1333 | warn(damagedPDF( | 1327 | warn(damagedPDF( |
| 1334 | - input, input->tell(), "stream keyword followed by extraneous whitespace")); | 1328 | + m->file->tell(), "stream keyword followed by extraneous whitespace")); |
| 1335 | done = false; | 1329 | done = false; |
| 1336 | } else { | 1330 | } else { |
| 1337 | QTC::TC("qpdf", "QPDF stream without newline"); | 1331 | QTC::TC("qpdf", "QPDF stream without newline"); |
| 1338 | - input->unreadCh(ch); | 1332 | + m->file->unreadCh(ch); |
| 1339 | warn(damagedPDF( | 1333 | warn(damagedPDF( |
| 1340 | - input, | ||
| 1341 | - input->tell(), | ||
| 1342 | - "stream keyword not followed by proper line " | ||
| 1343 | - "terminator")); | 1334 | + m->file->tell(), "stream keyword not followed by proper line terminator")); |
| 1344 | } | 1335 | } |
| 1345 | } | 1336 | } |
| 1346 | 1337 | ||
| 1347 | // Must get offset before accessing any additional objects since resolving a previously | 1338 | // Must get offset before accessing any additional objects since resolving a previously |
| 1348 | // unresolved indirect object will change file position. | 1339 | // unresolved indirect object will change file position. |
| 1349 | - qpdf_offset_t stream_offset = input->tell(); | 1340 | + qpdf_offset_t stream_offset = m->file->tell(); |
| 1350 | size_t length = 0; | 1341 | size_t length = 0; |
| 1351 | 1342 | ||
| 1352 | try { | 1343 | try { |
| @@ -1355,37 +1346,36 @@ QPDF::readObject( | @@ -1355,37 +1346,36 @@ QPDF::readObject( | ||
| 1355 | if (!length_obj.isInteger()) { | 1346 | if (!length_obj.isInteger()) { |
| 1356 | if (length_obj.isNull()) { | 1347 | if (length_obj.isNull()) { |
| 1357 | QTC::TC("qpdf", "QPDF stream without length"); | 1348 | QTC::TC("qpdf", "QPDF stream without length"); |
| 1358 | - throw damagedPDF(input, offset, "stream dictionary lacks /Length key"); | 1349 | + throw damagedPDF(offset, "stream dictionary lacks /Length key"); |
| 1359 | } | 1350 | } |
| 1360 | QTC::TC("qpdf", "QPDF stream length not integer"); | 1351 | QTC::TC("qpdf", "QPDF stream length not integer"); |
| 1361 | - throw damagedPDF( | ||
| 1362 | - input, offset, "/Length key in stream dictionary is not an integer"); | 1352 | + throw damagedPDF(offset, "/Length key in stream dictionary is not an integer"); |
| 1363 | } | 1353 | } |
| 1364 | 1354 | ||
| 1365 | length = toS(length_obj.getUIntValue()); | 1355 | length = toS(length_obj.getUIntValue()); |
| 1366 | // Seek in two steps to avoid potential integer overflow | 1356 | // Seek in two steps to avoid potential integer overflow |
| 1367 | - input->seek(stream_offset, SEEK_SET); | ||
| 1368 | - input->seek(toO(length), SEEK_CUR); | ||
| 1369 | - if (!readToken(input).isWord("endstream")) { | 1357 | + m->file->seek(stream_offset, SEEK_SET); |
| 1358 | + m->file->seek(toO(length), SEEK_CUR); | ||
| 1359 | + if (!readToken(m->file).isWord("endstream")) { | ||
| 1370 | QTC::TC("qpdf", "QPDF missing endstream"); | 1360 | QTC::TC("qpdf", "QPDF missing endstream"); |
| 1371 | - throw damagedPDF(input, input->getLastOffset(), "expected endstream"); | 1361 | + throw damagedPDF("expected endstream"); |
| 1372 | } | 1362 | } |
| 1373 | } catch (QPDFExc& e) { | 1363 | } catch (QPDFExc& e) { |
| 1374 | if (m->attempt_recovery) { | 1364 | if (m->attempt_recovery) { |
| 1375 | warn(e); | 1365 | warn(e); |
| 1376 | - length = recoverStreamLength(input, og, stream_offset); | 1366 | + length = recoverStreamLength(m->file, og, stream_offset); |
| 1377 | } else { | 1367 | } else { |
| 1378 | throw; | 1368 | throw; |
| 1379 | } | 1369 | } |
| 1380 | } | 1370 | } |
| 1381 | object = newIndirect(og, QPDF_Stream::create(this, og, object, stream_offset, length)); | 1371 | object = newIndirect(og, QPDF_Stream::create(this, og, object, stream_offset, length)); |
| 1382 | } else { | 1372 | } else { |
| 1383 | - input->seek(cur_offset, SEEK_SET); | 1373 | + m->file->seek(cur_offset, SEEK_SET); |
| 1384 | } | 1374 | } |
| 1385 | } | 1375 | } |
| 1386 | 1376 | ||
| 1387 | // Override last_offset so that it points to the beginning of the object we just read | 1377 | // Override last_offset so that it points to the beginning of the object we just read |
| 1388 | - input->setLastOffset(offset); | 1378 | + m->file->setLastOffset(offset); |
| 1389 | return object; | 1379 | return object; |
| 1390 | } | 1380 | } |
| 1391 | 1381 | ||
| @@ -1579,7 +1569,7 @@ QPDF::readObjectAtOffset( | @@ -1579,7 +1569,7 @@ QPDF::readObjectAtOffset( | ||
| 1579 | } | 1569 | } |
| 1580 | } | 1570 | } |
| 1581 | 1571 | ||
| 1582 | - QPDFObjectHandle oh = readObject(m->file, description, og, false); | 1572 | + QPDFObjectHandle oh = readObject(description, og); |
| 1583 | 1573 | ||
| 1584 | if (!readToken(m->file).isWord("endobj")) { | 1574 | if (!readToken(m->file).isWord("endobj")) { |
| 1585 | QTC::TC("qpdf", "QPDF err expected endobj"); | 1575 | QTC::TC("qpdf", "QPDF err expected endobj"); |