Commit 5ccab4be03701744f9795b37b4e5835b1a7b1c1d

Authored by m-holger
Committed by Jay Berkenbilt
1 parent b9483662

Add private methods QPDF::damagedPDF

include/qpdf/QPDF.hh
... ... @@ -1194,6 +1194,22 @@ class QPDF
1194 1194 std::shared_ptr<QPDFObject> const& object,
1195 1195 qpdf_offset_t end_before_space,
1196 1196 qpdf_offset_t end_after_space);
  1197 + static QPDFExc damagedPDF(
  1198 + std::shared_ptr<InputSource> const& input,
  1199 + std::string const& object,
  1200 + qpdf_offset_t offset,
  1201 + std::string const& message);
  1202 + QPDFExc damagedPDF(
  1203 + std::shared_ptr<InputSource> const& input,
  1204 + qpdf_offset_t offset,
  1205 + std::string const& message);
  1206 + QPDFExc damagedPDF(
  1207 + std::string const& object,
  1208 + qpdf_offset_t offset,
  1209 + std::string const& message);
  1210 + QPDFExc damagedPDF(std::string const& object, std::string const& message);
  1211 + QPDFExc damagedPDF(qpdf_offset_t offset, std::string const& message);
  1212 + QPDFExc damagedPDF(std::string const& message);
1197 1213  
1198 1214 // Calls finish() on the pipeline when done but does not delete it
1199 1215 bool pipeStreamData(
... ...
libqpdf/QPDF.cc
... ... @@ -481,7 +481,7 @@ QPDF::parse(char const* password)
481 481 PatternFinder hf(*this, &QPDF::findHeader);
482 482 if (!this->m->file->findFirst("%PDF-", 0, 1024, hf)) {
483 483 QTC::TC("qpdf", "QPDF not a pdf file");
484   - warn(qpdf_e_damaged_pdf, "", 0, "can't find PDF header");
  484 + warn(damagedPDF("", 0, "can't find PDF header"));
485 485 // QPDFWriter writes files that usually require at least
486 486 // version 1.2 for /FlateDecode
487 487 this->m->pdf_version = "1.2";
... ... @@ -503,24 +503,15 @@ QPDF::parse(char const* password)
503 503 try {
504 504 if (xref_offset == 0) {
505 505 QTC::TC("qpdf", "QPDF can't find startxref");
506   - throw QPDFExc(
507   - qpdf_e_damaged_pdf,
508   - this->m->file->getName(),
509   - "",
510   - 0,
511   - "can't find startxref");
  506 + throw damagedPDF("", 0, "can't find startxref");
512 507 }
513 508 try {
514 509 read_xref(xref_offset);
515 510 } catch (QPDFExc&) {
516 511 throw;
517 512 } catch (std::exception& e) {
518   - throw QPDFExc(
519   - qpdf_e_damaged_pdf,
520   - this->m->file->getName(),
521   - "",
522   - 0,
523   - std::string("error reading xref: ") + e.what());
  513 + throw damagedPDF(
  514 + "", 0, std::string("error reading xref: ") + e.what());
524 515 }
525 516 } catch (QPDFExc& e) {
526 517 if (this->m->attempt_recovery) {
... ... @@ -589,13 +580,9 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
589 580  
590 581 this->m->reconstructed_xref = true;
591 582  
592   - warn(qpdf_e_damaged_pdf, "", 0, "file is damaged");
  583 + warn(damagedPDF("", 0, "file is damaged"));
593 584 warn(e);
594   - warn(
595   - qpdf_e_damaged_pdf,
596   - "",
597   - 0,
598   - "Attempting to reconstruct cross-reference table");
  585 + warn(damagedPDF("", 0, "Attempting to reconstruct cross-reference table"));
599 586  
600 587 // Delete all references to type 1 (uncompressed) objects
601 588 std::set<QPDFObjGen> to_delete;
... ... @@ -655,13 +642,10 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
655 642 // with bad startxref pointers even when they have object
656 643 // streams.
657 644  
658   - throw QPDFExc(
659   - qpdf_e_damaged_pdf,
660   - this->m->file->getName(),
  645 + throw damagedPDF(
661 646 "",
662 647 0,
663   - "unable to find trailer "
664   - "dictionary while recovering damaged file");
  648 + "unable to find trailer dictionary while recovering damaged file");
665 649 }
666 650  
667 651 // We could iterate through the objects looking for streams and
... ... @@ -716,11 +700,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
716 700 if ((strncmp(buf, "xref", 4) == 0) && QUtil::is_space(buf[4])) {
717 701 if (skipped_space) {
718 702 QTC::TC("qpdf", "QPDF xref skipped space");
719   - warn(
720   - qpdf_e_damaged_pdf,
721   - "",
722   - 0,
723   - "extraneous whitespace seen before xref");
  703 + warn(damagedPDF(
  704 + "", 0, "extraneous whitespace seen before xref"));
724 705 }
725 706 QTC::TC(
726 707 "qpdf",
... ... @@ -741,22 +722,12 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
741 722 }
742 723 if (visited.count(xref_offset) != 0) {
743 724 QTC::TC("qpdf", "QPDF xref loop");
744   - throw QPDFExc(
745   - qpdf_e_damaged_pdf,
746   - this->m->file->getName(),
747   - "",
748   - 0,
749   - "loop detected following xref tables");
  725 + throw damagedPDF("", 0, "loop detected following xref tables");
750 726 }
751 727 }
752 728  
753 729 if (!this->m->trailer.isInitialized()) {
754   - throw QPDFExc(
755   - qpdf_e_damaged_pdf,
756   - this->m->file->getName(),
757   - "",
758   - 0,
759   - "unable to find trailer while reading xref");
  730 + throw damagedPDF("", 0, "unable to find trailer while reading xref");
760 731 }
761 732 int size = this->m->trailer.getKey("/Size").getIntValueAsInt();
762 733 int max_obj = 0;
... ... @@ -768,14 +739,12 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
768 739 }
769 740 if ((size < 1) || (size - 1 != max_obj)) {
770 741 QTC::TC("qpdf", "QPDF xref size mismatch");
771   - warn(
772   - qpdf_e_damaged_pdf,
  742 + warn(damagedPDF(
773 743 "",
774 744 0,
775   - (std::string("reported number of objects (") +
776   - std::to_string(size) +
  745 + ("reported number of objects (" + std::to_string(size) +
777 746 ") is not one plus the highest object number (" +
778   - std::to_string(max_obj) + ")"));
  747 + std::to_string(max_obj) + ")")));
779 748 }
780 749  
781 750 // We no longer need the deleted_objects table, so go ahead and
... ... @@ -899,11 +868,7 @@ QPDF::parse_xrefEntry(
899 868 }
900 869  
901 870 if (invalid) {
902   - warn(
903   - qpdf_e_damaged_pdf,
904   - "xref table",
905   - this->m->file->getLastOffset(),
906   - "accepting invalid xref table entry");
  871 + warn(damagedPDF("xref table", "accepting invalid xref table entry"));
907 872 }
908 873  
909 874 f1 = QUtil::string_to_ll(f1_str.c_str());
... ... @@ -929,12 +894,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
929 894 int bytes = 0;
930 895 if (!parse_xrefFirst(line, obj, num, bytes)) {
931 896 QTC::TC("qpdf", "QPDF invalid xref");
932   - throw QPDFExc(
933   - qpdf_e_damaged_pdf,
934   - this->m->file->getName(),
935   - "xref table",
936   - this->m->file->getLastOffset(),
937   - "xref syntax invalid");
  897 + throw damagedPDF("xref table", "xref syntax invalid");
938 898 }
939 899 this->m->file->seek(this->m->file->getLastOffset() + bytes, SEEK_SET);
940 900 for (qpdf_offset_t i = obj; i - num < obj; ++i) {
... ... @@ -949,11 +909,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
949 909 char type = '\0';
950 910 if (!parse_xrefEntry(xref_entry, f1, f2, type)) {
951 911 QTC::TC("qpdf", "QPDF invalid xref entry");
952   - throw QPDFExc(
953   - qpdf_e_damaged_pdf,
954   - this->m->file->getName(),
  912 + throw damagedPDF(
955 913 "xref table",
956   - this->m->file->getLastOffset(),
957 914 "invalid xref entry (obj=" + std::to_string(i) + ")");
958 915 }
959 916 if (type == 'f') {
... ... @@ -978,12 +935,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
978 935 readObject(this->m->file, "trailer", QPDFObjGen(), false);
979 936 if (!cur_trailer.isDictionary()) {
980 937 QTC::TC("qpdf", "QPDF missing trailer");
981   - throw QPDFExc(
982   - qpdf_e_damaged_pdf,
983   - this->m->file->getName(),
984   - "",
985   - this->m->file->getLastOffset(),
986   - "expected trailer dictionary");
  938 + throw damagedPDF("", "expected trailer dictionary");
987 939 }
988 940  
989 941 if (!this->m->trailer.isInitialized()) {
... ... @@ -991,22 +943,12 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
991 943  
992 944 if (!this->m->trailer.hasKey("/Size")) {
993 945 QTC::TC("qpdf", "QPDF trailer lacks size");
994   - throw QPDFExc(
995   - qpdf_e_damaged_pdf,
996   - this->m->file->getName(),
997   - "trailer",
998   - this->m->file->getLastOffset(),
999   - "trailer dictionary lacks /Size key");
  946 + throw damagedPDF("trailer", "trailer dictionary lacks /Size key");
1000 947 }
1001 948 if (!this->m->trailer.getKey("/Size").isInteger()) {
1002 949 QTC::TC("qpdf", "QPDF trailer size not integer");
1003   - throw QPDFExc(
1004   - qpdf_e_damaged_pdf,
1005   - this->m->file->getName(),
1006   - "trailer",
1007   - this->m->file->getLastOffset(),
1008   - "/Size key in trailer dictionary is not "
1009   - "an integer");
  950 + throw damagedPDF(
  951 + "trailer", "/Size key in trailer dictionary is not an integer");
1010 952 }
1011 953 }
1012 954  
... ... @@ -1021,12 +963,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
1021 963 (void)read_xrefStream(
1022 964 cur_trailer.getKey("/XRefStm").getIntValue());
1023 965 } else {
1024   - throw QPDFExc(
1025   - qpdf_e_damaged_pdf,
1026   - this->m->file->getName(),
1027   - "xref stream",
1028   - xref_offset,
1029   - "invalid /XRefStm");
  966 + throw damagedPDF(
  967 + "xref stream", xref_offset, "invalid /XRefStm");
1030 968 }
1031 969 }
1032 970 }
... ... @@ -1039,13 +977,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
1039 977 if (cur_trailer.hasKey("/Prev")) {
1040 978 if (!cur_trailer.getKey("/Prev").isInteger()) {
1041 979 QTC::TC("qpdf", "QPDF trailer prev not integer");
1042   - throw QPDFExc(
1043   - qpdf_e_damaged_pdf,
1044   - this->m->file->getName(),
1045   - "trailer",
1046   - this->m->file->getLastOffset(),
1047   - "/Prev key in trailer dictionary is not "
1048   - "an integer");
  980 + throw damagedPDF(
  981 + "trailer", "/Prev key in trailer dictionary is not an integer");
1049 982 }
1050 983 QTC::TC("qpdf", "QPDF prev key in trailer dictionary");
1051 984 xref_offset = cur_trailer.getKey("/Prev").getIntValue();
... ... @@ -1078,12 +1011,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
1078 1011  
1079 1012 if (!found) {
1080 1013 QTC::TC("qpdf", "QPDF can't find xref");
1081   - throw QPDFExc(
1082   - qpdf_e_damaged_pdf,
1083   - this->m->file->getName(),
1084   - "",
1085   - xref_offset,
1086   - "xref not found");
  1014 + throw damagedPDF("", xref_offset, "xref not found");
1087 1015 }
1088 1016  
1089 1017 return xref_offset;
... ... @@ -1101,13 +1029,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1101 1029 W_obj.getArrayItem(2).isInteger() &&
1102 1030 dict.getKey("/Size").isInteger() &&
1103 1031 (Index_obj.isArray() || Index_obj.isNull()))) {
1104   - throw QPDFExc(
1105   - qpdf_e_damaged_pdf,
1106   - this->m->file->getName(),
  1032 + throw damagedPDF(
1107 1033 "xref stream",
1108 1034 xref_offset,
1109   - "Cross-reference stream does not have"
1110   - " proper /W and /Index keys");
  1035 + "Cross-reference stream does not have proper /W and /Index keys");
1111 1036 }
1112 1037  
1113 1038 int W[3];
... ... @@ -1116,24 +1041,18 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1116 1041 for (int i = 0; i < 3; ++i) {
1117 1042 W[i] = W_obj.getArrayItem(i).getIntValueAsInt();
1118 1043 if (W[i] > max_bytes) {
1119   - throw QPDFExc(
1120   - qpdf_e_damaged_pdf,
1121   - this->m->file->getName(),
  1044 + throw damagedPDF(
1122 1045 "xref stream",
1123 1046 xref_offset,
1124   - "Cross-reference stream's /W contains"
1125   - " impossibly large values");
  1047 + "Cross-reference stream's /W contains impossibly large values");
1126 1048 }
1127 1049 entry_size += toS(W[i]);
1128 1050 }
1129 1051 if (entry_size == 0) {
1130   - throw QPDFExc(
1131   - qpdf_e_damaged_pdf,
1132   - this->m->file->getName(),
  1052 + throw damagedPDF(
1133 1053 "xref stream",
1134 1054 xref_offset,
1135   - "Cross-reference stream's /W indicates"
1136   - " entry size of 0");
  1055 + "Cross-reference stream's /W indicates entry size of 0");
1137 1056 }
1138 1057 unsigned long long max_num_entries =
1139 1058 static_cast<unsigned long long>(-1) / entry_size;
... ... @@ -1142,21 +1061,17 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1142 1061 if (Index_obj.isArray()) {
1143 1062 int n_index = Index_obj.getArrayNItems();
1144 1063 if ((n_index % 2) || (n_index < 2)) {
1145   - throw QPDFExc(
1146   - qpdf_e_damaged_pdf,
1147   - this->m->file->getName(),
  1064 + throw damagedPDF(
1148 1065 "xref stream",
1149 1066 xref_offset,
1150   - "Cross-reference stream's /Index has an"
1151   - " invalid number of values");
  1067 + "Cross-reference stream's /Index has an invalid number of "
  1068 + "values");
1152 1069 }
1153 1070 for (int i = 0; i < n_index; ++i) {
1154 1071 if (Index_obj.getArrayItem(i).isInteger()) {
1155 1072 indx.push_back(Index_obj.getArrayItem(i).getIntValue());
1156 1073 } else {
1157   - throw QPDFExc(
1158   - qpdf_e_damaged_pdf,
1159   - this->m->file->getName(),
  1074 + throw damagedPDF(
1160 1075 "xref stream",
1161 1076 xref_offset,
1162 1077 ("Cross-reference stream's /Index's item " +
... ... @@ -1174,13 +1089,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1174 1089 size_t num_entries = 0;
1175 1090 for (size_t i = 1; i < indx.size(); i += 2) {
1176 1091 if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) {
1177   - throw QPDFExc(
1178   - qpdf_e_damaged_pdf,
1179   - this->m->file->getName(),
  1092 + throw damagedPDF(
1180 1093 "xref stream",
1181 1094 xref_offset,
1182   - ("Cross-reference stream claims to contain"
1183   - " too many entries: " +
  1095 + ("Cross-reference stream claims to contain too many entries: " +
1184 1096 std::to_string(indx.at(i)) + " " +
1185 1097 std::to_string(max_num_entries) + " " +
1186 1098 std::to_string(num_entries)));
... ... @@ -1196,13 +1108,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1196 1108 size_t actual_size = bp->getSize();
1197 1109  
1198 1110 if (expected_size != actual_size) {
1199   - QPDFExc x(
1200   - qpdf_e_damaged_pdf,
1201   - this->m->file->getName(),
  1111 + QPDFExc x = damagedPDF(
1202 1112 "xref stream",
1203 1113 xref_offset,
1204   - ("Cross-reference stream data has the wrong size;"
1205   - " expected = " +
  1114 + ("Cross-reference stream data has the wrong size; expected = " +
1206 1115 std::to_string(expected_size) +
1207 1116 "; actual = " + std::to_string(actual_size)));
1208 1117 if (expected_size > actual_size) {
... ... @@ -1286,13 +1195,9 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1286 1195  
1287 1196 if (dict.hasKey("/Prev")) {
1288 1197 if (!dict.getKey("/Prev").isInteger()) {
1289   - throw QPDFExc(
1290   - qpdf_e_damaged_pdf,
1291   - this->m->file->getName(),
  1198 + throw damagedPDF(
1292 1199 "xref stream",
1293   - this->m->file->getLastOffset(),
1294   - "/Prev key in xref stream dictionary is not "
1295   - "an integer");
  1200 + "/Prev key in xref stream dictionary is not an integer");
1296 1201 }
1297 1202 QTC::TC("qpdf", "QPDF prev key in xref stream dictionary");
1298 1203 xref_offset = dict.getKey("/Prev").getIntValue();
... ... @@ -1351,11 +1256,8 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
1351 1256 break;
1352 1257  
1353 1258 default:
1354   - throw QPDFExc(
1355   - qpdf_e_damaged_pdf,
1356   - this->m->file->getName(),
  1259 + throw damagedPDF(
1357 1260 "xref stream",
1358   - this->m->file->getLastOffset(),
1359 1261 "unknown xref stream entry type " + std::to_string(f0));
1360 1262 break;
1361 1263 }
... ... @@ -1522,12 +1424,8 @@ QPDF::readObject(
1522 1424 // Nothing in the PDF spec appears to allow empty objects, but
1523 1425 // they have been encountered in actual PDF files and Adobe
1524 1426 // Reader appears to ignore them.
1525   - warn(QPDFExc(
1526   - qpdf_e_damaged_pdf,
1527   - input->getName(),
1528   - this->m->last_object_description,
1529   - input->getLastOffset(),
1530   - "empty object treated as null"));
  1427 + warn(damagedPDF(
  1428 + input, input->getLastOffset(), "empty object treated as null"));
1531 1429 } else if (object.isDictionary() && (!in_object_stream)) {
1532 1430 // check for stream
1533 1431 qpdf_offset_t cur_offset = input->tell();
... ... @@ -1569,34 +1467,27 @@ QPDF::readObject(
1569 1467 // of not having seen a newline.
1570 1468 QTC::TC("qpdf", "QPDF stream with CR only");
1571 1469 input->unreadCh(ch);
1572   - warn(QPDFExc(
1573   - qpdf_e_damaged_pdf,
1574   - input->getName(),
1575   - this->m->last_object_description,
  1470 + warn(damagedPDF(
  1471 + input,
1576 1472 input->tell(),
1577   - "stream keyword followed"
1578   - " by carriage return only"));
  1473 + "stream keyword followed by carriage return "
  1474 + "only"));
1579 1475 }
1580 1476 }
1581 1477 } else if (QUtil::is_space(ch)) {
1582   - warn(QPDFExc(
1583   - qpdf_e_damaged_pdf,
1584   - input->getName(),
1585   - this->m->last_object_description,
  1478 + warn(damagedPDF(
  1479 + input,
1586 1480 input->tell(),
1587   - "stream keyword followed by"
1588   - " extraneous whitespace"));
  1481 + "stream keyword followed by extraneous whitespace"));
1589 1482 done = false;
1590 1483 } else {
1591 1484 QTC::TC("qpdf", "QPDF stream without newline");
1592 1485 input->unreadCh(ch);
1593   - warn(QPDFExc(
1594   - qpdf_e_damaged_pdf,
1595   - input->getName(),
1596   - this->m->last_object_description,
  1486 + warn(damagedPDF(
  1487 + input,
1597 1488 input->tell(),
1598   - "stream keyword not followed"
1599   - " by proper line terminator"));
  1489 + "stream keyword not followed by proper line "
  1490 + "terminator"));
1600 1491 }
1601 1492 }
1602 1493  
... ... @@ -1612,21 +1503,15 @@ QPDF::readObject(
1612 1503  
1613 1504 if (dict.count("/Length") == 0) {
1614 1505 QTC::TC("qpdf", "QPDF stream without length");
1615   - throw QPDFExc(
1616   - qpdf_e_damaged_pdf,
1617   - input->getName(),
1618   - this->m->last_object_description,
1619   - offset,
1620   - "stream dictionary lacks /Length key");
  1506 + throw damagedPDF(
  1507 + input, offset, "stream dictionary lacks /Length key");
1621 1508 }
1622 1509  
1623 1510 QPDFObjectHandle length_obj = dict["/Length"];
1624 1511 if (!length_obj.isInteger()) {
1625 1512 QTC::TC("qpdf", "QPDF stream length not integer");
1626   - throw QPDFExc(
1627   - qpdf_e_damaged_pdf,
1628   - input->getName(),
1629   - this->m->last_object_description,
  1513 + throw damagedPDF(
  1514 + input,
1630 1515 offset,
1631 1516 "/Length key in stream dictionary is not "
1632 1517 "an integer");
... ... @@ -1640,12 +1525,8 @@ QPDF::readObject(
1640 1525 QPDFTokenizer::Token(
1641 1526 QPDFTokenizer::tt_word, "endstream"))) {
1642 1527 QTC::TC("qpdf", "QPDF missing endstream");
1643   - throw QPDFExc(
1644   - qpdf_e_damaged_pdf,
1645   - input->getName(),
1646   - this->m->last_object_description,
1647   - input->getLastOffset(),
1648   - "expected endstream");
  1528 + throw damagedPDF(
  1529 + input, input->getLastOffset(), "expected endstream");
1649 1530 }
1650 1531 } catch (QPDFExc& e) {
1651 1532 if (this->m->attempt_recovery) {
... ... @@ -1689,12 +1570,8 @@ QPDF::recoverStreamLength(
1689 1570 {
1690 1571 // Try to reconstruct stream length by looking for
1691 1572 // endstream or endobj
1692   - warn(QPDFExc(
1693   - qpdf_e_damaged_pdf,
1694   - input->getName(),
1695   - this->m->last_object_description,
1696   - stream_offset,
1697   - "attempting to recover stream length"));
  1573 + warn(damagedPDF(
  1574 + input, stream_offset, "attempting to recover stream length"));
1698 1575  
1699 1576 PatternFinder ef(*this, &QPDF::findEndstream);
1700 1577 size_t length = 0;
... ... @@ -1734,18 +1611,13 @@ QPDF::recoverStreamLength(
1734 1611 }
1735 1612  
1736 1613 if (length == 0) {
1737   - warn(QPDFExc(
1738   - qpdf_e_damaged_pdf,
1739   - input->getName(),
1740   - this->m->last_object_description,
  1614 + warn(damagedPDF(
  1615 + input,
1741 1616 stream_offset,
1742   - "unable to recover stream data;"
1743   - " treating stream as empty"));
  1617 + "unable to recover stream data; treating stream as empty"));
1744 1618 } else {
1745   - warn(QPDFExc(
1746   - qpdf_e_damaged_pdf,
1747   - input->getName(),
1748   - this->m->last_object_description,
  1619 + warn(damagedPDF(
  1620 + input,
1749 1621 stream_offset,
1750 1622 "recovered stream length: " + std::to_string(length)));
1751 1623 }
... ... @@ -1795,11 +1667,7 @@ QPDF::readObjectAtOffset(
1795 1667 // ignore these.
1796 1668 if (offset == 0) {
1797 1669 QTC::TC("qpdf", "QPDF bogus 0 offset", 0);
1798   - warn(
1799   - qpdf_e_damaged_pdf,
1800   - this->m->last_object_description,
1801   - 0,
1802   - "object has offset 0");
  1670 + warn(damagedPDF(0, "object has offset 0"));
1803 1671 return QPDFObjectHandle::newNull();
1804 1672 }
1805 1673  
... ... @@ -1820,33 +1688,19 @@ QPDF::readObjectAtOffset(
1820 1688 try {
1821 1689 if (!(objidok && genok && objok)) {
1822 1690 QTC::TC("qpdf", "QPDF expected n n obj");
1823   - throw QPDFExc(
1824   - qpdf_e_damaged_pdf,
1825   - this->m->file->getName(),
1826   - this->m->last_object_description,
1827   - offset,
1828   - "expected n n obj");
  1691 + throw damagedPDF(offset, "expected n n obj");
1829 1692 }
1830 1693 int objid = QUtil::string_to_int(tobjid.getValue().c_str());
1831 1694 int generation = QUtil::string_to_int(tgen.getValue().c_str());
1832 1695 og = QPDFObjGen(objid, generation);
1833 1696 if (objid == 0) {
1834 1697 QTC::TC("qpdf", "QPDF object id 0");
1835   - throw QPDFExc(
1836   - qpdf_e_damaged_pdf,
1837   - this->m->file->getName(),
1838   - this->m->last_object_description,
1839   - offset,
1840   - "object with ID 0");
  1698 + throw damagedPDF(offset, "object with ID 0");
1841 1699 }
1842 1700 if (check_og && (exp_og != og)) {
1843 1701 QTC::TC("qpdf", "QPDF err wrong objid/generation");
1844   - QPDFExc e(
1845   - qpdf_e_damaged_pdf,
1846   - this->m->file->getName(),
1847   - this->m->last_object_description,
1848   - offset,
1849   - (std::string("expected ") + exp_og.unparse(' ') + " obj"));
  1702 + QPDFExc e =
  1703 + damagedPDF(offset, "expected " + exp_og.unparse(' ') + " obj");
1850 1704 if (try_recovery) {
1851 1705 // Will be retried below
1852 1706 throw e;
... ... @@ -1870,14 +1724,12 @@ QPDF::readObjectAtOffset(
1870 1724 return result;
1871 1725 } else {
1872 1726 QTC::TC("qpdf", "QPDF object gone after xref reconstruction");
1873   - warn(
1874   - qpdf_e_damaged_pdf,
  1727 + warn(damagedPDF(
1875 1728 "",
1876 1729 0,
1877   - std::string(
1878   - "object " + exp_og.unparse(' ') +
1879   - " not found in file after regenerating"
1880   - " cross reference table"));
  1730 + ("object " + exp_og.unparse(' ') +
  1731 + " not found in file after regenerating cross reference "
  1732 + "table")));
1881 1733 return QPDFObjectHandle::newNull();
1882 1734 }
1883 1735 } else {
... ... @@ -1890,11 +1742,7 @@ QPDF::readObjectAtOffset(
1890 1742 if (!(readToken(this->m->file) ==
1891 1743 QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) {
1892 1744 QTC::TC("qpdf", "QPDF err expected endobj");
1893   - warn(
1894   - qpdf_e_damaged_pdf,
1895   - this->m->last_object_description,
1896   - this->m->file->getLastOffset(),
1897   - "expected endobj");
  1745 + warn(damagedPDF("expected endobj"));
1898 1746 }
1899 1747  
1900 1748 if (isUnresolved(og)) {
... ... @@ -1919,12 +1767,7 @@ QPDF::readObjectAtOffset(
1919 1767 break;
1920 1768 }
1921 1769 } else {
1922   - throw QPDFExc(
1923   - qpdf_e_damaged_pdf,
1924   - this->m->file->getName(),
1925   - this->m->last_object_description,
1926   - this->m->file->tell(),
1927   - "EOF after endobj");
  1770 + throw damagedPDF(m->file->tell(), "EOF after endobj");
1928 1771 }
1929 1772 }
1930 1773 qpdf_offset_t end_after_space = this->m->file->tell();
... ... @@ -1950,11 +1793,8 @@ QPDF::resolve(QPDFObjGen const&amp; og)
1950 1793 // indirectly in some key that has to be resolved during
1951 1794 // object parsing, such as stream length.
1952 1795 QTC::TC("qpdf", "QPDF recursion loop in resolve");
1953   - warn(
1954   - qpdf_e_damaged_pdf,
1955   - "",
1956   - this->m->file->getLastOffset(),
1957   - ("loop detected resolving object " + og.unparse(' ')));
  1796 + warn(damagedPDF(
  1797 + "", "loop detected resolving object " + og.unparse(' ')));
1958 1798 updateCache(og, QPDF_Null::create(), -1, -1);
1959 1799 return;
1960 1800 }
... ... @@ -1979,9 +1819,7 @@ QPDF::resolve(QPDFObjGen const&amp; og)
1979 1819 break;
1980 1820  
1981 1821 default:
1982   - throw QPDFExc(
1983   - qpdf_e_damaged_pdf,
1984   - this->m->file->getName(),
  1822 + throw damagedPDF(
1985 1823 "",
1986 1824 0,
1987 1825 ("object " + og.unparse('/') +
... ... @@ -1990,12 +1828,11 @@ QPDF::resolve(QPDFObjGen const&amp; og)
1990 1828 } catch (QPDFExc& e) {
1991 1829 warn(e);
1992 1830 } catch (std::exception& e) {
1993   - warn(
1994   - qpdf_e_damaged_pdf,
  1831 + warn(damagedPDF(
1995 1832 "",
1996 1833 0,
1997 1834 ("object " + og.unparse('/') +
1998   - ": error reading object: " + e.what()));
  1835 + ": error reading object: " + e.what())));
1999 1836 }
2000 1837 }
2001 1838  
... ... @@ -2021,13 +1858,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
2021 1858 // Force resolution of object stream
2022 1859 QPDFObjectHandle obj_stream = getObjectByID(obj_stream_number, 0);
2023 1860 if (!obj_stream.isStream()) {
2024   - throw QPDFExc(
2025   - qpdf_e_damaged_pdf,
2026   - this->m->file->getName(),
2027   - this->m->last_object_description,
2028   - this->m->file->getLastOffset(),
2029   - ("supposed object stream " + std::to_string(obj_stream_number) +
2030   - " is not a stream"));
  1861 + throw damagedPDF(
  1862 + "supposed object stream " + std::to_string(obj_stream_number) +
  1863 + " is not a stream");
2031 1864 }
2032 1865  
2033 1866 // For linearization data in the object, use the data from the
... ... @@ -2041,20 +1874,13 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
2041 1874 QPDFObjectHandle dict = obj_stream.getDict();
2042 1875 if (!dict.isDictionaryOfType("/ObjStm")) {
2043 1876 QTC::TC("qpdf", "QPDF ERR object stream with wrong type");
2044   - warn(
2045   - qpdf_e_damaged_pdf,
2046   - this->m->last_object_description,
2047   - this->m->file->getLastOffset(),
2048   - ("supposed object stream " + std::to_string(obj_stream_number) +
2049   - " has wrong type"));
  1877 + warn(damagedPDF(
  1878 + "supposed object stream " + std::to_string(obj_stream_number) +
  1879 + " has wrong type"));
2050 1880 }
2051 1881  
2052 1882 if (!(dict.getKey("/N").isInteger() && dict.getKey("/First").isInteger())) {
2053   - throw QPDFExc(
2054   - qpdf_e_damaged_pdf,
2055   - this->m->file->getName(),
2056   - this->m->last_object_description,
2057   - this->m->file->getLastOffset(),
  1883 + throw damagedPDF(
2058 1884 ("object stream " + std::to_string(obj_stream_number) +
2059 1885 " has incorrect keys"));
2060 1886 }
... ... @@ -2077,10 +1903,8 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
2077 1903 QPDFTokenizer::Token toffset = readToken(input);
2078 1904 if (!((tnum.getType() == QPDFTokenizer::tt_integer) &&
2079 1905 (toffset.getType() == QPDFTokenizer::tt_integer))) {
2080   - throw QPDFExc(
2081   - qpdf_e_damaged_pdf,
2082   - input->getName(),
2083   - this->m->last_object_description,
  1906 + throw damagedPDF(
  1907 + input,
2084 1908 input->getLastOffset(),
2085 1909 "expected integer in object stream header");
2086 1910 }
... ... @@ -2618,12 +2442,7 @@ QPDF::getRoot()
2618 2442 {
2619 2443 QPDFObjectHandle root = this->m->trailer.getKey("/Root");
2620 2444 if (!root.isDictionary()) {
2621   - throw QPDFExc(
2622   - qpdf_e_damaged_pdf,
2623   - this->m->file->getName(),
2624   - "",
2625   - 0,
2626   - "unable to find /Root dictionary");
  2445 + throw damagedPDF("", 0, "unable to find /Root dictionary");
2627 2446 }
2628 2447 return root;
2629 2448 }
... ... @@ -2751,9 +2570,8 @@ QPDF::pipeStreamData(
2751 2570 size_t to_read = (sizeof(buf) < length ? sizeof(buf) : length);
2752 2571 size_t len = file->read(buf, to_read);
2753 2572 if (len == 0) {
2754   - throw QPDFExc(
2755   - qpdf_e_damaged_pdf,
2756   - file->getName(),
  2573 + throw damagedPDF(
  2574 + file,
2757 2575 "",
2758 2576 file->getLastOffset(),
2759 2577 "unexpected EOF reading stream data");
... ... @@ -2772,9 +2590,8 @@ QPDF::pipeStreamData(
2772 2590 QTC::TC("qpdf", "QPDF decoding error warning");
2773 2591 qpdf_for_warning.warn(
2774 2592 // line-break
2775   - QPDFExc(
2776   - qpdf_e_damaged_pdf,
2777   - file->getName(),
  2593 + damagedPDF(
  2594 + file,
2778 2595 "",
2779 2596 file->getLastOffset(),
2780 2597 ("error decoding stream data for object " +
... ... @@ -2782,9 +2599,8 @@ QPDF::pipeStreamData(
2782 2599 if (will_retry) {
2783 2600 qpdf_for_warning.warn(
2784 2601 // line-break
2785   - QPDFExc(
2786   - qpdf_e_damaged_pdf,
2787   - file->getName(),
  2602 + damagedPDF(
  2603 + file,
2788 2604 "",
2789 2605 file->getLastOffset(),
2790 2606 "stream will be re-processed without"
... ... @@ -2848,18 +2664,72 @@ QPDF::pipeForeignStreamData(
2848 2664 will_retry);
2849 2665 }
2850 2666  
  2667 +// Throw a generic exception when we lack context for something
  2668 +// more specific. New code should not use this. This method exists
  2669 +// to improve somewhat from calling assert in very old code.
2851 2670 void
2852 2671 QPDF::stopOnError(std::string const& message)
2853 2672 {
2854   - // Throw a generic exception when we lack context for something
2855   - // more specific. New code should not use this. This method exists
2856   - // to improve somewhat from calling assert in very old code.
2857   - throw QPDFExc(
2858   - qpdf_e_damaged_pdf,
2859   - this->m->file->getName(),
2860   - "",
2861   - this->m->file->getLastOffset(),
2862   - message);
  2673 + throw damagedPDF("", message);
  2674 +}
  2675 +
  2676 +// Return an exception of type qpdf_e_damaged_pdf.
  2677 +QPDFExc
  2678 +QPDF::damagedPDF(
  2679 + std::shared_ptr<InputSource> const& input,
  2680 + std::string const& object,
  2681 + qpdf_offset_t offset,
  2682 + std::string const& message)
  2683 +{
  2684 + return QPDFExc(
  2685 + qpdf_e_damaged_pdf, input->getName(), object, offset, message);
  2686 +}
  2687 +
  2688 +// Return an exception of type qpdf_e_damaged_pdf. The object is taken from
  2689 +// m->last_object_description.
  2690 +QPDFExc
  2691 +QPDF::damagedPDF(
  2692 + std::shared_ptr<InputSource> const& input,
  2693 + qpdf_offset_t offset,
  2694 + std::string const& message)
  2695 +{
  2696 + return damagedPDF(input, m->last_object_description, offset, message);
  2697 +}
  2698 +
  2699 +// Return an exception of type qpdf_e_damaged_pdf. The filename is taken from
  2700 +// m->file.
  2701 +QPDFExc
  2702 +QPDF::damagedPDF(
  2703 + std::string const& object, qpdf_offset_t offset, std::string const& message)
  2704 +{
  2705 + return QPDFExc(
  2706 + qpdf_e_damaged_pdf, m->file->getName(), object, offset, message);
  2707 +}
  2708 +
  2709 +// Return an exception of type qpdf_e_damaged_pdf. The filename is taken from
  2710 +// m->file and the offset from .m->file->getLastOffset().
  2711 +QPDFExc
  2712 +QPDF::damagedPDF(std::string const& object, std::string const& message)
  2713 +{
  2714 + return damagedPDF(object, m->file->getLastOffset(), message);
  2715 +}
  2716 +
  2717 +// Return an exception of type qpdf_e_damaged_pdf. The filename is taken from
  2718 +// m->file and the object from .m->last_object_description.
  2719 +QPDFExc
  2720 +QPDF::damagedPDF(qpdf_offset_t offset, std::string const& message)
  2721 +{
  2722 + return damagedPDF(m->last_object_description, offset, message);
  2723 +}
  2724 +
  2725 +// Return an exception of type qpdf_e_damaged_pdf. The filename is taken from
  2726 +// m->file, the object from m->last_object_description and the offset from
  2727 +// m->file->getLastOffset().
  2728 +QPDFExc
  2729 +QPDF::damagedPDF(std::string const& message)
  2730 +{
  2731 + return damagedPDF(
  2732 + m->last_object_description, m->file->getLastOffset(), message);
2863 2733 }
2864 2734  
2865 2735 bool
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -804,21 +804,12 @@ QPDF::initializeEncryption()
804 804 // Treating a missing ID as the empty string enables qpdf to
805 805 // decrypt some invalid encrypted files with no /ID that
806 806 // poppler can read but Adobe Reader can't.
807   - warn(
808   - qpdf_e_damaged_pdf,
809   - "trailer",
810   - this->m->file->getLastOffset(),
811   - "invalid /ID in trailer dictionary");
  807 + warn(damagedPDF("trailer", "invalid /ID in trailer dictionary"));
812 808 }
813 809  
814 810 QPDFObjectHandle encryption_dict = this->m->trailer.getKey("/Encrypt");
815 811 if (!encryption_dict.isDictionary()) {
816   - throw QPDFExc(
817   - qpdf_e_damaged_pdf,
818   - this->m->file->getName(),
819   - this->m->last_object_description,
820   - this->m->file->getLastOffset(),
821   - "/Encrypt in trailer dictionary is not a dictionary");
  812 + throw damagedPDF("/Encrypt in trailer dictionary is not a dictionary");
822 813 }
823 814  
824 815 if (!(encryption_dict.getKey("/Filter").isName() &&
... ... @@ -835,8 +826,7 @@ QPDF::initializeEncryption()
835 826 qpdf_e_unsupported,
836 827 "encryption dictionary",
837 828 this->m->file->getLastOffset(),
838   - "file uses encryption SubFilters,"
839   - " which qpdf does not support");
  829 + "file uses encryption SubFilters, which qpdf does not support");
840 830 }
841 831  
842 832 if (!(encryption_dict.getKey("/V").isInteger() &&
... ... @@ -844,13 +834,10 @@ QPDF::initializeEncryption()
844 834 encryption_dict.getKey("/O").isString() &&
845 835 encryption_dict.getKey("/U").isString() &&
846 836 encryption_dict.getKey("/P").isInteger())) {
847   - throw QPDFExc(
848   - qpdf_e_damaged_pdf,
849   - this->m->file->getName(),
  837 + throw damagedPDF(
850 838 "encryption dictionary",
851   - this->m->file->getLastOffset(),
852   - "some encryption dictionary parameters are missing "
853   - "or the wrong type");
  839 + "some encryption dictionary parameters are missing or the wrong "
  840 + "type");
854 841 }
855 842  
856 843 int V = encryption_dict.getKey("/V").getIntValueAsInt();
... ... @@ -886,25 +873,18 @@ QPDF::initializeEncryption()
886 873 pad_short_parameter(O, key_bytes);
887 874 pad_short_parameter(U, key_bytes);
888 875 if (!((O.length() == key_bytes) && (U.length() == key_bytes))) {
889   - throw QPDFExc(
890   - qpdf_e_damaged_pdf,
891   - this->m->file->getName(),
  876 + throw damagedPDF(
892 877 "encryption dictionary",
893   - this->m->file->getLastOffset(),
894   - "incorrect length for /O and/or /U in "
895   - "encryption dictionary");
  878 + "incorrect length for /O and/or /U in encryption dictionary");
896 879 }
897 880 } else {
898 881 if (!(encryption_dict.getKey("/OE").isString() &&
899 882 encryption_dict.getKey("/UE").isString() &&
900 883 encryption_dict.getKey("/Perms").isString())) {
901   - throw QPDFExc(
902   - qpdf_e_damaged_pdf,
903   - this->m->file->getName(),
  884 + throw damagedPDF(
904 885 "encryption dictionary",
905   - this->m->file->getLastOffset(),
906   - "some V=5 encryption dictionary parameters are "
907   - "missing or the wrong type");
  886 + "some V=5 encryption dictionary parameters are missing or the "
  887 + "wrong type");
908 888 }
909 889 OE = encryption_dict.getKey("/OE").getStringValue();
910 890 UE = encryption_dict.getKey("/UE").getStringValue();
... ... @@ -1062,12 +1042,10 @@ QPDF::initializeEncryption()
1062 1042 this->m->encp->encryption_key = recover_encryption_key_with_password(
1063 1043 this->m->encp->provided_password, data, perms_valid);
1064 1044 if (!perms_valid) {
1065   - warn(
1066   - qpdf_e_damaged_pdf,
  1045 + warn(damagedPDF(
1067 1046 "encryption dictionary",
1068   - this->m->file->getLastOffset(),
1069   - "/Perms field in encryption dictionary"
1070   - " doesn't match expected value");
  1047 + "/Perms field in encryption dictionary doesn't match expected "
  1048 + "value"));
1071 1049 }
1072 1050 }
1073 1051 }
... ... @@ -1121,13 +1099,9 @@ QPDF::decryptString(std::string&amp; str, QPDFObjGen const&amp; og)
1121 1099 break;
1122 1100  
1123 1101 default:
1124   - warn(
1125   - qpdf_e_damaged_pdf,
1126   - this->m->last_object_description,
1127   - this->m->file->getLastOffset(),
1128   - "unknown encryption filter for strings"
1129   - " (check /StrF in /Encrypt dictionary);"
1130   - " strings may be decrypted improperly");
  1102 + warn(damagedPDF(
  1103 + "unknown encryption filter for strings (check /StrF in "
  1104 + "/Encrypt dictionary); strings may be decrypted improperly"));
1131 1105 // To avoid repeated warnings, reset cf_string. Assume
1132 1106 // we'd want to use AES if V == 4.
1133 1107 this->m->encp->cf_string = e_aes;
... ... @@ -1166,13 +1140,9 @@ QPDF::decryptString(std::string&amp; str, QPDFObjGen const&amp; og)
1166 1140 } catch (QPDFExc&) {
1167 1141 throw;
1168 1142 } catch (std::runtime_error& e) {
1169   - throw QPDFExc(
1170   - qpdf_e_damaged_pdf,
1171   - this->m->file->getName(),
1172   - this->m->last_object_description,
1173   - this->m->file->getLastOffset(),
  1143 + throw damagedPDF(
1174 1144 "error decrypting string for object " + og.unparse() + ": " +
1175   - e.what());
  1145 + e.what());
1176 1146 }
1177 1147 }
1178 1148  
... ... @@ -1265,11 +1235,8 @@ QPDF::decryptStream(
1265 1235 file->getName(),
1266 1236 "",
1267 1237 file->getLastOffset(),
1268   - "unknown encryption filter for streams"
1269   - " (check " +
1270   - method_source +
1271   - ");"
1272   - " streams may be decrypted improperly"));
  1238 + "unknown encryption filter for streams (check " +
  1239 + method_source + "); streams may be decrypted improperly"));
1273 1240 // To avoid repeated warnings, reset cf_stream. Assume
1274 1241 // we'd want to use AES if V == 4.
1275 1242 encp->cf_stream = e_aes;
... ...
libqpdf/QPDF_linearization.cc
... ... @@ -186,24 +186,16 @@ QPDF::readLinearizationData()
186 186  
187 187 if (!(H.isArray() && O.isInteger() && E.isInteger() && N.isInteger() &&
188 188 T.isInteger() && (P.isInteger() || P.isNull()))) {
189   - throw QPDFExc(
190   - qpdf_e_damaged_pdf,
191   - this->m->file->getName(),
  189 + throw damagedPDF(
192 190 "linearization dictionary",
193   - this->m->file->getLastOffset(),
194   - "some keys in linearization dictionary are of "
195   - "the wrong type");
  191 + "some keys in linearization dictionary are of the wrong type");
196 192 }
197 193  
198 194 // Hint table array: offset length [ offset length ]
199 195 size_t n_H_items = toS(H.getArrayNItems());
200 196 if (!((n_H_items == 2) || (n_H_items == 4))) {
201   - throw QPDFExc(
202   - qpdf_e_damaged_pdf,
203   - this->m->file->getName(),
204   - "linearization dictionary",
205   - this->m->file->getLastOffset(),
206   - "H has the wrong number of items");
  197 + throw damagedPDF(
  198 + "linearization dictionary", "H has the wrong number of items");
207 199 }
208 200  
209 201 std::vector<int> H_items;
... ... @@ -212,11 +204,8 @@ QPDF::readLinearizationData()
212 204 if (oh.isInteger()) {
213 205 H_items.push_back(oh.getIntValueAsInt());
214 206 } else {
215   - throw QPDFExc(
216   - qpdf_e_damaged_pdf,
217   - this->m->file->getName(),
  207 + throw damagedPDF(
218 208 "linearization dictionary",
219   - this->m->file->getLastOffset(),
220 209 "some H items are of the wrong type");
221 210 }
222 211 }
... ... @@ -249,12 +238,8 @@ QPDF::readLinearizationData()
249 238 // initialized from N, to pre-allocate memory, so make sure it's
250 239 // accurate and bail right now if it's not.
251 240 if (N.getIntValue() != static_cast<long long>(getAllPages().size())) {
252   - throw QPDFExc(
253   - qpdf_e_damaged_pdf,
254   - this->m->file->getName(),
255   - "linearization hint table",
256   - this->m->file->getLastOffset(),
257   - "/N does not match number of pages");
  241 + throw damagedPDF(
  242 + "linearization hint table", "/N does not match number of pages");
258 243 }
259 244  
260 245 // file_size initialized by isLinearized()
... ... @@ -297,11 +282,8 @@ QPDF::readLinearizationData()
297 282  
298 283 int HSi = HS.getIntValueAsInt();
299 284 if ((HSi < 0) || (toS(HSi) >= h_size)) {
300   - throw QPDFExc(
301   - qpdf_e_damaged_pdf,
302   - this->m->file->getName(),
  285 + throw damagedPDF(
303 286 "linearization hint table",
304   - this->m->file->getLastOffset(),
305 287 "/S (shared object) offset is out of bounds");
306 288 }
307 289 readHSharedObject(BitStream(h_buf + HSi, h_size - toS(HSi)));
... ... @@ -309,11 +291,8 @@ QPDF::readLinearizationData()
309 291 if (HO.isInteger()) {
310 292 int HOi = HO.getIntValueAsInt();
311 293 if ((HOi < 0) || (toS(HOi) >= h_size)) {
312   - throw QPDFExc(
313   - qpdf_e_damaged_pdf,
314   - this->m->file->getName(),
  294 + throw damagedPDF(
315 295 "linearization hint table",
316   - this->m->file->getLastOffset(),
317 296 "/O (outline) offset is out of bounds");
318 297 }
319 298 readHGeneric(
... ... @@ -331,12 +310,8 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length)
331 310 qpdf_offset_t min_end_offset = oc.end_before_space;
332 311 qpdf_offset_t max_end_offset = oc.end_after_space;
333 312 if (!H.isStream()) {
334   - throw QPDFExc(
335   - qpdf_e_damaged_pdf,
336   - this->m->file->getName(),
337   - "linearization dictionary",
338   - this->m->file->getLastOffset(),
339   - "hint table is not a stream");
  313 + throw damagedPDF(
  314 + "linearization dictionary", "hint table is not a stream");
340 315 }
341 316  
342 317 QPDFObjectHandle Hdict = H.getDict();
... ... @@ -362,12 +337,8 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length)
362 337 *this->m->log->getError()
363 338 << "expected = " << computed_end << "; actual = " << min_end_offset
364 339 << ".." << max_end_offset << "\n";
365   - throw QPDFExc(
366   - qpdf_e_damaged_pdf,
367   - this->m->file->getName(),
368   - "linearization dictionary",
369   - this->m->file->getLastOffset(),
370   - "hint table length mismatch");
  340 + throw damagedPDF(
  341 + "linearization dictionary", "hint table length mismatch");
371 342 }
372 343 H.pipeStreamData(&pl, 0, qpdf_dl_specialized);
373 344 return Hdict;
... ...
qpdf/test_char_sign.cc
1 1 #include <cstdio>
2   -int main()
  2 +int
  3 +main()
3 4 {
4 5 char ch = '\xf7';
5 6 if (ch < 0) {
... ...