Commit cee8d5c92ddb0333b72249ecc3878966d2991aa9
1 parent
0c56cec6
Refactor Xref_table::parse_first
Rename to Xref_table::subsection. Return results instead of using out parameters. Take on responsibility for throwing exception and calculation of offset of first subsection entry.
Showing
2 changed files
with
20 additions
and
18 deletions
libqpdf/QPDF.cc
| @@ -776,9 +776,14 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset) | @@ -776,9 +776,14 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset) | ||
| 776 | } | 776 | } |
| 777 | } | 777 | } |
| 778 | 778 | ||
| 779 | -bool | ||
| 780 | -QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& bytes) | 779 | +QPDF::Xref_table::Subsection |
| 780 | +QPDF::Xref_table::subsection(std::string const& line) | ||
| 781 | { | 781 | { |
| 782 | + auto terminate = [this]() -> void { | ||
| 783 | + QTC::TC("qpdf", "QPDF invalid xref"); | ||
| 784 | + throw damaged_table("xref syntax invalid"); | ||
| 785 | + }; | ||
| 786 | + | ||
| 782 | // is_space and is_digit both return false on '\0', so this will not overrun the null-terminated | 787 | // is_space and is_digit both return false on '\0', so this will not overrun the null-terminated |
| 783 | // buffer. | 788 | // buffer. |
| 784 | char const* p = line.c_str(); | 789 | char const* p = line.c_str(); |
| @@ -790,7 +795,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | @@ -790,7 +795,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | ||
| 790 | } | 795 | } |
| 791 | // Require digit | 796 | // Require digit |
| 792 | if (!QUtil::is_digit(*p)) { | 797 | if (!QUtil::is_digit(*p)) { |
| 793 | - return false; | 798 | + terminate(); |
| 794 | } | 799 | } |
| 795 | // Gather digits | 800 | // Gather digits |
| 796 | std::string obj_str; | 801 | std::string obj_str; |
| @@ -799,7 +804,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | @@ -799,7 +804,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | ||
| 799 | } | 804 | } |
| 800 | // Require space | 805 | // Require space |
| 801 | if (!QUtil::is_space(*p)) { | 806 | if (!QUtil::is_space(*p)) { |
| 802 | - return false; | 807 | + terminate(); |
| 803 | } | 808 | } |
| 804 | // Skip spaces | 809 | // Skip spaces |
| 805 | while (QUtil::is_space(*p)) { | 810 | while (QUtil::is_space(*p)) { |
| @@ -807,7 +812,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | @@ -807,7 +812,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | ||
| 807 | } | 812 | } |
| 808 | // Require digit | 813 | // Require digit |
| 809 | if (!QUtil::is_digit(*p)) { | 814 | if (!QUtil::is_digit(*p)) { |
| 810 | - return false; | 815 | + terminate(); |
| 811 | } | 816 | } |
| 812 | // Gather digits | 817 | // Gather digits |
| 813 | std::string num_str; | 818 | std::string num_str; |
| @@ -818,10 +823,10 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | @@ -818,10 +823,10 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int& | ||
| 818 | while (QUtil::is_space(*p)) { | 823 | while (QUtil::is_space(*p)) { |
| 819 | ++p; | 824 | ++p; |
| 820 | } | 825 | } |
| 821 | - bytes = toI(p - start); | ||
| 822 | - obj = QUtil::string_to_int(obj_str.c_str()); | ||
| 823 | - num = QUtil::string_to_int(num_str.c_str()); | ||
| 824 | - return true; | 826 | + return { |
| 827 | + QUtil::string_to_int(obj_str.c_str()), | ||
| 828 | + QUtil::string_to_int(num_str.c_str()), | ||
| 829 | + file->getLastOffset() + toI(p - start)}; | ||
| 825 | } | 830 | } |
| 826 | 831 | ||
| 827 | bool | 832 | bool |
| @@ -968,14 +973,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) | @@ -968,14 +973,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) | ||
| 968 | while (true) { | 973 | while (true) { |
| 969 | line.assign(50, '\0'); | 974 | line.assign(50, '\0'); |
| 970 | file->read(line.data(), line.size()); | 975 | file->read(line.data(), line.size()); |
| 971 | - int obj = 0; | ||
| 972 | - int num = 0; | ||
| 973 | - int bytes = 0; | ||
| 974 | - if (!parse_first(line, obj, num, bytes)) { | ||
| 975 | - QTC::TC("qpdf", "QPDF invalid xref"); | ||
| 976 | - throw damaged_table("xref syntax invalid"); | ||
| 977 | - } | ||
| 978 | - file->seek(file->getLastOffset() + bytes, SEEK_SET); | 976 | + auto [obj, num, offset] = subsection(line); |
| 977 | + file->seek(offset, SEEK_SET); | ||
| 979 | for (qpdf_offset_t i = obj; i - num < obj; ++i) { | 978 | for (qpdf_offset_t i = obj; i - num < obj; ++i) { |
| 980 | if (i == 0) { | 979 | if (i == 0) { |
| 981 | // This is needed by checkLinearization() | 980 | // This is needed by checkLinearization() |
libqpdf/qpdf/QPDF_private.hh
| @@ -118,11 +118,14 @@ class QPDF::Xref_table | @@ -118,11 +118,14 @@ class QPDF::Xref_table | ||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | private: | 120 | private: |
| 121 | + // Object, count, offset of first entry | ||
| 122 | + typedef std::tuple<int, int, qpdf_offset_t> Subsection; | ||
| 123 | + | ||
| 121 | void read(qpdf_offset_t offset); | 124 | void read(qpdf_offset_t offset); |
| 122 | 125 | ||
| 123 | // Methods to parse tables | 126 | // Methods to parse tables |
| 124 | qpdf_offset_t read_table(qpdf_offset_t offset); | 127 | qpdf_offset_t read_table(qpdf_offset_t offset); |
| 125 | - bool parse_first(std::string const& line, int& obj, int& num, int& bytes); | 128 | + Subsection subsection(std::string const& line); |
| 126 | bool read_entry(qpdf_offset_t& f1, int& f2, char& type); | 129 | bool read_entry(qpdf_offset_t& f1, int& f2, char& type); |
| 127 | bool read_bad_entry(qpdf_offset_t& f1, int& f2, char& type); | 130 | bool read_bad_entry(qpdf_offset_t& f1, int& f2, char& type); |
| 128 | 131 |