Commit 39df5936fea3edd90e1cfeb568098a32510e6a3d
1 parent
ed656194
Refactor Xref_table::read_table
Rename to Xref_table::process_section. Process trailer processing subsection entries.
Showing
2 changed files
with
27 additions
and
25 deletions
libqpdf/QPDF.cc
| ... | ... | @@ -732,7 +732,7 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset) |
| 732 | 732 | while (QUtil::is_space(buf[skip])) { |
| 733 | 733 | ++skip; |
| 734 | 734 | } |
| 735 | - xref_offset = read_table(xref_offset + skip); | |
| 735 | + xref_offset = process_section(xref_offset + skip); | |
| 736 | 736 | } else { |
| 737 | 737 | xref_offset = read_stream(xref_offset); |
| 738 | 738 | } |
| ... | ... | @@ -994,11 +994,32 @@ QPDF::Xref_table::read_entry(qpdf_offset_t& f1, int& f2, char& type) |
| 994 | 994 | |
| 995 | 995 | // Read a single cross-reference table section and associated trailer. |
| 996 | 996 | qpdf_offset_t |
| 997 | -QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) | |
| 997 | +QPDF::Xref_table::process_section(qpdf_offset_t xref_offset) | |
| 998 | 998 | { |
| 999 | 999 | file->seek(xref_offset, SEEK_SET); |
| 1000 | 1000 | std::string line; |
| 1001 | 1001 | auto subs = subsections(line); |
| 1002 | + | |
| 1003 | + auto cur_trailer_offset = file->tell(); | |
| 1004 | + auto cur_trailer = read_trailer(); | |
| 1005 | + if (!cur_trailer.isDictionary()) { | |
| 1006 | + QTC::TC("qpdf", "QPDF missing trailer"); | |
| 1007 | + throw qpdf.damagedPDF("", "expected trailer dictionary"); | |
| 1008 | + } | |
| 1009 | + | |
| 1010 | + if (!trailer_) { | |
| 1011 | + trailer_ = cur_trailer; | |
| 1012 | + | |
| 1013 | + if (!trailer_.hasKey("/Size")) { | |
| 1014 | + QTC::TC("qpdf", "QPDF trailer lacks size"); | |
| 1015 | + throw qpdf.damagedPDF("trailer", "trailer dictionary lacks /Size key"); | |
| 1016 | + } | |
| 1017 | + if (!trailer_.getKey("/Size").isInteger()) { | |
| 1018 | + QTC::TC("qpdf", "QPDF trailer size not integer"); | |
| 1019 | + throw qpdf.damagedPDF("trailer", "/Size key in trailer dictionary is not an integer"); | |
| 1020 | + } | |
| 1021 | + } | |
| 1022 | + | |
| 1002 | 1023 | for (auto [obj, num, offset]: subs) { |
| 1003 | 1024 | file->seek(offset, SEEK_SET); |
| 1004 | 1025 | for (qpdf_offset_t i = obj; i - num < obj; ++i) { |
| ... | ... | @@ -1027,26 +1048,6 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) |
| 1027 | 1048 | } |
| 1028 | 1049 | } |
| 1029 | 1050 | |
| 1030 | - // Set offset to previous xref table if any | |
| 1031 | - auto cur_trailer = read_trailer(); | |
| 1032 | - if (!cur_trailer.isDictionary()) { | |
| 1033 | - QTC::TC("qpdf", "QPDF missing trailer"); | |
| 1034 | - throw qpdf.damagedPDF("", "expected trailer dictionary"); | |
| 1035 | - } | |
| 1036 | - | |
| 1037 | - if (!trailer_) { | |
| 1038 | - trailer_ = cur_trailer; | |
| 1039 | - | |
| 1040 | - if (!trailer_.hasKey("/Size")) { | |
| 1041 | - QTC::TC("qpdf", "QPDF trailer lacks size"); | |
| 1042 | - throw qpdf.damagedPDF("trailer", "trailer dictionary lacks /Size key"); | |
| 1043 | - } | |
| 1044 | - if (!trailer_.getKey("/Size").isInteger()) { | |
| 1045 | - QTC::TC("qpdf", "QPDF trailer size not integer"); | |
| 1046 | - throw qpdf.damagedPDF("trailer", "/Size key in trailer dictionary is not an integer"); | |
| 1047 | - } | |
| 1048 | - } | |
| 1049 | - | |
| 1050 | 1051 | if (cur_trailer.hasKey("/XRefStm")) { |
| 1051 | 1052 | if (ignore_streams_) { |
| 1052 | 1053 | QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer"); |
| ... | ... | @@ -1056,7 +1057,7 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) |
| 1056 | 1057 | // /Prev key instead of the xref stream's. |
| 1057 | 1058 | (void)read_stream(cur_trailer.getKey("/XRefStm").getIntValue()); |
| 1058 | 1059 | } else { |
| 1059 | - throw qpdf.damagedPDF("xref stream", xref_offset, "invalid /XRefStm"); | |
| 1060 | + throw qpdf.damagedPDF("xref stream", cur_trailer_offset, "invalid /XRefStm"); | |
| 1060 | 1061 | } |
| 1061 | 1062 | } |
| 1062 | 1063 | } |
| ... | ... | @@ -1064,7 +1065,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) |
| 1064 | 1065 | if (cur_trailer.hasKey("/Prev")) { |
| 1065 | 1066 | if (!cur_trailer.getKey("/Prev").isInteger()) { |
| 1066 | 1067 | QTC::TC("qpdf", "QPDF trailer prev not integer"); |
| 1067 | - throw qpdf.damagedPDF("trailer", "/Prev key in trailer dictionary is not an integer"); | |
| 1068 | + throw qpdf.damagedPDF( | |
| 1069 | + "trailer", cur_trailer_offset, "/Prev key in trailer dictionary is not an integer"); | |
| 1068 | 1070 | } |
| 1069 | 1071 | QTC::TC("qpdf", "QPDF prev key in trailer dictionary"); |
| 1070 | 1072 | return cur_trailer.getKey("/Prev").getIntValue(); | ... | ... |
libqpdf/qpdf/QPDF_private.hh
| ... | ... | @@ -124,7 +124,7 @@ class QPDF::Xref_table |
| 124 | 124 | void read(qpdf_offset_t offset); |
| 125 | 125 | |
| 126 | 126 | // Methods to parse tables |
| 127 | - qpdf_offset_t read_table(qpdf_offset_t offset); | |
| 127 | + qpdf_offset_t process_section(qpdf_offset_t offset); | |
| 128 | 128 | std::vector<Subsection> subsections(std::string& line); |
| 129 | 129 | Subsection subsection(std::string const& line); |
| 130 | 130 | bool read_entry(qpdf_offset_t& f1, int& f2, char& type); | ... | ... |