Commit ed656194281225079e26d303ffb02cdfd2855ab9
1 parent
cee8d5c9
Add new methods Xref_table::subsections
Calculate all subsections before reading subsection entries. Duplicates some warnings for the time being.
Showing
3 changed files
with
36 additions
and
5 deletions
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 |