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,6 +829,34 @@ QPDF::Xref_table::subsection(std::string const& line)
829 file->getLastOffset() + toI(p - start)}; 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 bool 860 bool
833 QPDF::Xref_table::read_bad_entry(qpdf_offset_t& f1, int& f2, char& type) 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,10 +998,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
970 { 998 {
971 file->seek(xref_offset, SEEK_SET); 999 file->seek(xref_offset, SEEK_SET);
972 std::string line; 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 file->seek(offset, SEEK_SET); 1003 file->seek(offset, SEEK_SET);
978 for (qpdf_offset_t i = obj; i - num < obj; ++i) { 1004 for (qpdf_offset_t i = obj; i - num < obj; ++i) {
979 if (i == 0) { 1005 if (i == 0) {
@@ -985,7 +1011,6 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) @@ -985,7 +1011,6 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
985 int f2 = 0; 1011 int f2 = 0;
986 char type = '\0'; 1012 char type = '\0';
987 if (!read_entry(f1, f2, type)) { 1013 if (!read_entry(f1, f2, type)) {
988 - QTC::TC("qpdf", "QPDF invalid xref entry");  
989 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")"); 1014 throw damaged_table("invalid xref entry (obj=" + std::to_string(i) + ")");
990 } 1015 }
991 if (type == 'f') { 1016 if (type == 'f') {
libqpdf/qpdf/QPDF_private.hh
@@ -125,6 +125,7 @@ class QPDF::Xref_table @@ -125,6 +125,7 @@ class QPDF::Xref_table
125 125
126 // Methods to parse tables 126 // Methods to parse tables
127 qpdf_offset_t read_table(qpdf_offset_t offset); 127 qpdf_offset_t read_table(qpdf_offset_t offset);
  128 + std::vector<Subsection> subsections(std::string& line);
128 Subsection subsection(std::string const& line); 129 Subsection subsection(std::string const& line);
129 bool read_entry(qpdf_offset_t& f1, int& f2, char& type); 130 bool read_entry(qpdf_offset_t& f1, int& f2, char& type);
130 bool read_bad_entry(qpdf_offset_t& f1, int& f2, char& type); 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,6 +3,11 @@ WARNING: xref-errors.pdf (xref table, offset 606): accepting invalid xref table
3 WARNING: xref-errors.pdf (xref table, offset 627): accepting invalid xref table entry 3 WARNING: xref-errors.pdf (xref table, offset 627): accepting invalid xref table entry
4 WARNING: xref-errors.pdf (xref table, offset 648): accepting invalid xref table entry 4 WARNING: xref-errors.pdf (xref table, offset 648): accepting invalid xref table entry
5 WARNING: xref-errors.pdf (xref table, offset 667): accepting invalid xref table entry 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 checking xref-errors.pdf 11 checking xref-errors.pdf
7 PDF Version: 1.3 12 PDF Version: 1.3
8 File is not encrypted 13 File is not encrypted