Commit ed656194281225079e26d303ffb02cdfd2855ab9

Authored by m-holger
1 parent cee8d5c9

Add new methods Xref_table::subsections

Calculate all subsections before reading subsection entries.

Duplicates some warnings for the time being.
libqpdf/QPDF.cc
... ... @@ -829,6 +829,34 @@ QPDF::Xref_table::subsection(std::string const& line)
829 829 file->getLastOffset() + toI(p - start)};
830 830 }
831 831  
  832 +std::vector<QPDF::Xref_table::Subsection>
  833 +QPDF::Xref_table::subsections(std::string& line)
  834 +{
  835 + std::vector<QPDF::Xref_table::Subsection> result;
  836 + qpdf_offset_t f1 = 0;
  837 + int f2 = 0;
  838 + char type = '\0';
  839 +
  840 + while (true) {
  841 + line.assign(50, '\0');
  842 + file->read(line.data(), line.size());
  843 + auto [obj, num, offset] = result.emplace_back(subsection(line));
  844 + file->seek(offset, SEEK_SET);
  845 + for (qpdf_offset_t i = obj; i - num < obj; ++i) {
  846 + if (!read_entry(f1, f2, type)) {
  847 + QTC::TC("qpdf", "QPDF invalid xref entry");
  848 + throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")");
  849 + }
  850 + }
  851 + qpdf_offset_t pos = file->tell();
  852 + if (read_token().isWord("trailer")) {
  853 + return result;
  854 + } else {
  855 + file->seek(pos, SEEK_SET);
  856 + }
  857 + }
  858 +}
  859 +
832 860 bool
833 861 QPDF::Xref_table::read_bad_entry(qpdf_offset_t& f1, int& f2, char& type)
834 862 {
... ... @@ -970,10 +998,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
970 998 {
971 999 file->seek(xref_offset, SEEK_SET);
972 1000 std::string line;
973   - while (true) {
974   - line.assign(50, '\0');
975   - file->read(line.data(), line.size());
976   - auto [obj, num, offset] = subsection(line);
  1001 + auto subs = subsections(line);
  1002 + for (auto [obj, num, offset]: subs) {
977 1003 file->seek(offset, SEEK_SET);
978 1004 for (qpdf_offset_t i = obj; i - num < obj; ++i) {
979 1005 if (i == 0) {
... ... @@ -985,7 +1011,6 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
985 1011 int f2 = 0;
986 1012 char type = '\0';
987 1013 if (!read_entry(f1, f2, type)) {
988   - QTC::TC("qpdf", "QPDF invalid xref entry");
989 1014 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")");
990 1015 }
991 1016 if (type == 'f') {
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -125,6 +125,7 @@ class QPDF::Xref_table
125 125  
126 126 // Methods to parse tables
127 127 qpdf_offset_t read_table(qpdf_offset_t offset);
  128 + std::vector<Subsection> subsections(std::string& line);
128 129 Subsection subsection(std::string const& line);
129 130 bool read_entry(qpdf_offset_t& f1, int& f2, char& type);
130 131 bool read_bad_entry(qpdf_offset_t& f1, int& f2, char& type);
... ...
qpdf/qtest/qpdf/xref-errors.out
... ... @@ -3,6 +3,11 @@ WARNING: xref-errors.pdf (xref table, offset 606): accepting invalid xref table
3 3 WARNING: xref-errors.pdf (xref table, offset 627): accepting invalid xref table entry
4 4 WARNING: xref-errors.pdf (xref table, offset 648): accepting invalid xref table entry
5 5 WARNING: xref-errors.pdf (xref table, offset 667): accepting invalid xref table entry
  6 +WARNING: xref-errors.pdf (xref table, offset 585): accepting invalid xref table entry
  7 +WARNING: xref-errors.pdf (xref table, offset 606): accepting invalid xref table entry
  8 +WARNING: xref-errors.pdf (xref table, offset 627): accepting invalid xref table entry
  9 +WARNING: xref-errors.pdf (xref table, offset 648): accepting invalid xref table entry
  10 +WARNING: xref-errors.pdf (xref table, offset 667): accepting invalid xref table entry
6 11 checking xref-errors.pdf
7 12 PDF Version: 1.3
8 13 File is not encrypted
... ...