Commit 39df5936fea3edd90e1cfeb568098a32510e6a3d

Authored by m-holger
1 parent ed656194

Refactor Xref_table::read_table

Rename to Xref_table::process_section.
Process trailer processing subsection entries.
libqpdf/QPDF.cc
@@ -732,7 +732,7 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset) @@ -732,7 +732,7 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset)
732 while (QUtil::is_space(buf[skip])) { 732 while (QUtil::is_space(buf[skip])) {
733 ++skip; 733 ++skip;
734 } 734 }
735 - xref_offset = read_table(xref_offset + skip); 735 + xref_offset = process_section(xref_offset + skip);
736 } else { 736 } else {
737 xref_offset = read_stream(xref_offset); 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,11 +994,32 @@ QPDF::Xref_table::read_entry(qpdf_offset_t& f1, int& f2, char& type)
994 994
995 // Read a single cross-reference table section and associated trailer. 995 // Read a single cross-reference table section and associated trailer.
996 qpdf_offset_t 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 file->seek(xref_offset, SEEK_SET); 999 file->seek(xref_offset, SEEK_SET);
1000 std::string line; 1000 std::string line;
1001 auto subs = subsections(line); 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 for (auto [obj, num, offset]: subs) { 1023 for (auto [obj, num, offset]: subs) {
1003 file->seek(offset, SEEK_SET); 1024 file->seek(offset, SEEK_SET);
1004 for (qpdf_offset_t i = obj; i - num < obj; ++i) { 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,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 if (cur_trailer.hasKey("/XRefStm")) { 1051 if (cur_trailer.hasKey("/XRefStm")) {
1051 if (ignore_streams_) { 1052 if (ignore_streams_) {
1052 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer"); 1053 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer");
@@ -1056,7 +1057,7 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset) @@ -1056,7 +1057,7 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
1056 // /Prev key instead of the xref stream's. 1057 // /Prev key instead of the xref stream's.
1057 (void)read_stream(cur_trailer.getKey("/XRefStm").getIntValue()); 1058 (void)read_stream(cur_trailer.getKey("/XRefStm").getIntValue());
1058 } else { 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,7 +1065,8 @@ QPDF::Xref_table::read_table(qpdf_offset_t xref_offset)
1064 if (cur_trailer.hasKey("/Prev")) { 1065 if (cur_trailer.hasKey("/Prev")) {
1065 if (!cur_trailer.getKey("/Prev").isInteger()) { 1066 if (!cur_trailer.getKey("/Prev").isInteger()) {
1066 QTC::TC("qpdf", "QPDF trailer prev not integer"); 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 QTC::TC("qpdf", "QPDF prev key in trailer dictionary"); 1071 QTC::TC("qpdf", "QPDF prev key in trailer dictionary");
1070 return cur_trailer.getKey("/Prev").getIntValue(); 1072 return cur_trailer.getKey("/Prev").getIntValue();
libqpdf/qpdf/QPDF_private.hh
@@ -124,7 +124,7 @@ class QPDF::Xref_table @@ -124,7 +124,7 @@ class QPDF::Xref_table
124 void read(qpdf_offset_t offset); 124 void read(qpdf_offset_t offset);
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 process_section(qpdf_offset_t offset);
128 std::vector<Subsection> subsections(std::string& line); 128 std::vector<Subsection> subsections(std::string& line);
129 Subsection subsection(std::string const& line); 129 Subsection subsection(std::string const& line);
130 bool read_entry(qpdf_offset_t& f1, int& f2, char& type); 130 bool read_entry(qpdf_offset_t& f1, int& f2, char& type);