Commit f1c774f13fac105a904b1901bfbdc2f892ebccf9

Authored by m-holger
1 parent 973edb4f

Refactor QPDF::processXRefStream

Tune pointer arithmetic.
Showing 1 changed file with 10 additions and 5 deletions
libqpdf/QPDF.cc
@@ -1002,6 +1002,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) @@ -1002,6 +1002,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
1002 } 1002 }
1003 unsigned long long max_num_entries = static_cast<unsigned long long>(-1) / entry_size; 1003 unsigned long long max_num_entries = static_cast<unsigned long long>(-1) / entry_size;
1004 1004
  1005 + // Process /Index entry
1005 std::vector<long long> indx; 1006 std::vector<long long> indx;
1006 if (Index_obj.isArray()) { 1007 if (Index_obj.isArray()) {
1007 int n_index = Index_obj.getArrayNItems(); 1008 int n_index = Index_obj.getArrayNItems();
@@ -1025,6 +1026,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1025,6 +1026,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1025 } 1026 }
1026 QTC::TC("qpdf", "QPDF xref /Index is array", n_index == 2 ? 0 : 1); 1027 QTC::TC("qpdf", "QPDF xref /Index is array", n_index == 2 ? 0 : 1);
1027 } else { 1028 } else {
  1029 + // We have already validayed the /Index key.
1028 QTC::TC("qpdf", "QPDF xref /Index is null"); 1030 QTC::TC("qpdf", "QPDF xref /Index is null");
1029 long long size = dict.getKey("/Size").getIntValue(); 1031 long long size = dict.getKey("/Size").getIntValue();
1030 indx.push_back(0); 1032 indx.push_back(0);
@@ -1033,6 +1035,11 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1033,6 +1035,11 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1033 1035
1034 size_t num_entries = 0; 1036 size_t num_entries = 0;
1035 for (size_t i = 1; i < indx.size(); i += 2) { 1037 for (size_t i = 1; i < indx.size(); i += 2) {
  1038 + // We are guarding against the possibility of num_entries * entry_size overflowing.
  1039 + // We are not checking that entries are in ascending order as required by the spec, which
  1040 + // probably should generate a warning. We are also not checking that for each subsection
  1041 + // first object number + number of entries <= /Size. The spec requires us to ignore object
  1042 + // number > /Size.
1036 if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) { 1043 if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) {
1037 throw damagedPDF( 1044 throw damagedPDF(
1038 "xref stream", 1045 "xref stream",
@@ -1070,13 +1077,11 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1070,13 +1077,11 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1070 bool saw_first_compressed_object = false; 1077 bool saw_first_compressed_object = false;
1071 1078
1072 // Actual size vs. expected size check above ensures that we will not overflow any buffers here. 1079 // Actual size vs. expected size check above ensures that we will not overflow any buffers here.
1073 - // We know that entry_size * num_entries is equal to the size of the buffer.  
1074 - unsigned char const* data = bp->getBuffer(); 1080 + // We know that entry_size * num_entries is less or equal to the size of the buffer.
  1081 + auto p = bp->getBuffer();
1075 for (size_t i = 0; i < num_entries; ++i) { 1082 for (size_t i = 0; i < num_entries; ++i) {
1076 // Read this entry 1083 // Read this entry
1077 - unsigned char const* entry = data + (entry_size * i);  
1078 qpdf_offset_t fields[3]; 1084 qpdf_offset_t fields[3];
1079 - unsigned char const* p = entry;  
1080 for (int j = 0; j < 3; ++j) { 1085 for (int j = 0; j < 3; ++j) {
1081 fields[j] = 0; 1086 fields[j] = 0;
1082 if ((j == 0) && (W[0] == 0)) { 1087 if ((j == 0) && (W[0] == 0)) {
@@ -1085,7 +1090,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1085,7 +1090,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1085 } 1090 }
1086 for (int k = 0; k < W[j]; ++k) { 1091 for (int k = 0; k < W[j]; ++k) {
1087 fields[j] <<= 8; 1092 fields[j] <<= 8;
1088 - fields[j] += toI(*p++); 1093 + fields[j] |= *p++;
1089 } 1094 }
1090 } 1095 }
1091 1096