Commit cee8d5c92ddb0333b72249ecc3878966d2991aa9

Authored by m-holger
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.
libqpdf/QPDF.cc
... ... @@ -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 787 // is_space and is_digit both return false on '\0', so this will not overrun the null-terminated
783 788 // buffer.
784 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 795 }
791 796 // Require digit
792 797 if (!QUtil::is_digit(*p)) {
793   - return false;
  798 + terminate();
794 799 }
795 800 // Gather digits
796 801 std::string obj_str;
... ... @@ -799,7 +804,7 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int&
799 804 }
800 805 // Require space
801 806 if (!QUtil::is_space(*p)) {
802   - return false;
  807 + terminate();
803 808 }
804 809 // Skip spaces
805 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 812 }
808 813 // Require digit
809 814 if (!QUtil::is_digit(*p)) {
810   - return false;
  815 + terminate();
811 816 }
812 817 // Gather digits
813 818 std::string num_str;
... ... @@ -818,10 +823,10 @@ QPDF::Xref_table::parse_first(std::string const& line, int& obj, int& num, int&
818 823 while (QUtil::is_space(*p)) {
819 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 832 bool
... ... @@ -968,14 +973,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
968 973 while (true) {
969 974 line.assign(50, '\0');
970 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 978 for (qpdf_offset_t i = obj; i - num < obj; ++i) {
980 979 if (i == 0) {
981 980 // This is needed by checkLinearization()
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -118,11 +118,14 @@ class QPDF::Xref_table
118 118 }
119 119  
120 120 private:
  121 + // Object, count, offset of first entry
  122 + typedef std::tuple<int, int, qpdf_offset_t> Subsection;
  123 +
121 124 void read(qpdf_offset_t offset);
122 125  
123 126 // Methods to parse tables
124 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 129 bool read_entry(qpdf_offset_t& f1, int& f2, char& type);
127 130 bool read_bad_entry(qpdf_offset_t& f1, int& f2, char& type);
128 131  
... ...