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,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