Commit 7aa5027bf827c3b7f7a2b94183e49fb077435ca9
1 parent
1737902a
Refactor QPDF::procesXRefStream
Add closure damaged to create damagedPDF exceptions.
Showing
1 changed file
with
18 additions
and
29 deletions
libqpdf/QPDF.cc
| @@ -971,16 +971,17 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset) | @@ -971,16 +971,17 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset) | ||
| 971 | qpdf_offset_t | 971 | qpdf_offset_t |
| 972 | QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | 972 | QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) |
| 973 | { | 973 | { |
| 974 | - QPDFObjectHandle dict = xref_obj.getDict(); | ||
| 975 | - QPDFObjectHandle W_obj = dict.getKey("/W"); | ||
| 976 | - QPDFObjectHandle Index_obj = dict.getKey("/Index"); | 974 | + auto damaged = [this, xref_offset](std::string_view msg) -> QPDFExc { |
| 975 | + return damagedPDF("xref stream", xref_offset, msg.data()); | ||
| 976 | + }; | ||
| 977 | + | ||
| 978 | + auto dict = xref_obj.getDict(); | ||
| 979 | + auto W_obj = dict.getKey("/W"); | ||
| 980 | + auto Index_obj = dict.getKey("/Index"); | ||
| 977 | if (!(W_obj.isArray() && (W_obj.getArrayNItems() >= 3) && W_obj.getArrayItem(0).isInteger() && | 981 | if (!(W_obj.isArray() && (W_obj.getArrayNItems() >= 3) && W_obj.getArrayItem(0).isInteger() && |
| 978 | W_obj.getArrayItem(1).isInteger() && W_obj.getArrayItem(2).isInteger() && | 982 | W_obj.getArrayItem(1).isInteger() && W_obj.getArrayItem(2).isInteger() && |
| 979 | dict.getKey("/Size").isInteger() && (Index_obj.isArray() || Index_obj.isNull()))) { | 983 | dict.getKey("/Size").isInteger() && (Index_obj.isArray() || Index_obj.isNull()))) { |
| 980 | - throw damagedPDF( | ||
| 981 | - "xref stream", | ||
| 982 | - xref_offset, | ||
| 983 | - "Cross-reference stream does not have proper /W and /Index keys"); | 984 | + throw damaged("Cross-reference stream does not have proper /W and /Index keys"); |
| 984 | } | 985 | } |
| 985 | 986 | ||
| 986 | int W[3]; | 987 | int W[3]; |
| @@ -989,16 +990,12 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | @@ -989,16 +990,12 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | ||
| 989 | for (int i = 0; i < 3; ++i) { | 990 | for (int i = 0; i < 3; ++i) { |
| 990 | W[i] = W_obj.getArrayItem(i).getIntValueAsInt(); | 991 | W[i] = W_obj.getArrayItem(i).getIntValueAsInt(); |
| 991 | if (W[i] > max_bytes) { | 992 | if (W[i] > max_bytes) { |
| 992 | - throw damagedPDF( | ||
| 993 | - "xref stream", | ||
| 994 | - xref_offset, | ||
| 995 | - "Cross-reference stream's /W contains impossibly large values"); | 993 | + throw damaged("Cross-reference stream's /W contains impossibly large values"); |
| 996 | } | 994 | } |
| 997 | entry_size += toS(W[i]); | 995 | entry_size += toS(W[i]); |
| 998 | } | 996 | } |
| 999 | if (entry_size == 0) { | 997 | if (entry_size == 0) { |
| 1000 | - throw damagedPDF( | ||
| 1001 | - "xref stream", xref_offset, "Cross-reference stream's /W indicates entry size of 0"); | 998 | + throw damaged("Cross-reference stream's /W indicates entry size of 0"); |
| 1002 | } | 999 | } |
| 1003 | unsigned long long max_num_entries = static_cast<unsigned long long>(-1) / entry_size; | 1000 | unsigned long long max_num_entries = static_cast<unsigned long long>(-1) / entry_size; |
| 1004 | 1001 | ||
| @@ -1007,21 +1004,15 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | @@ -1007,21 +1004,15 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | ||
| 1007 | if (Index_obj.isArray()) { | 1004 | if (Index_obj.isArray()) { |
| 1008 | int n_index = Index_obj.getArrayNItems(); | 1005 | int n_index = Index_obj.getArrayNItems(); |
| 1009 | if ((n_index % 2) || (n_index < 2)) { | 1006 | if ((n_index % 2) || (n_index < 2)) { |
| 1010 | - throw damagedPDF( | ||
| 1011 | - "xref stream", | ||
| 1012 | - xref_offset, | ||
| 1013 | - "Cross-reference stream's /Index has an invalid number of " | ||
| 1014 | - "values"); | 1007 | + throw damaged("Cross-reference stream's /Index has an invalid number of values"); |
| 1015 | } | 1008 | } |
| 1016 | for (int i = 0; i < n_index; ++i) { | 1009 | for (int i = 0; i < n_index; ++i) { |
| 1017 | if (Index_obj.getArrayItem(i).isInteger()) { | 1010 | if (Index_obj.getArrayItem(i).isInteger()) { |
| 1018 | indx.push_back(Index_obj.getArrayItem(i).getIntValue()); | 1011 | indx.push_back(Index_obj.getArrayItem(i).getIntValue()); |
| 1019 | } else { | 1012 | } else { |
| 1020 | - throw damagedPDF( | ||
| 1021 | - "xref stream", | ||
| 1022 | - xref_offset, | ||
| 1023 | - ("Cross-reference stream's /Index's item " + std::to_string(i) + | ||
| 1024 | - " is not an integer")); | 1013 | + throw damaged( |
| 1014 | + "Cross-reference stream's /Index's item " + std::to_string(i) + | ||
| 1015 | + " is not an integer"); | ||
| 1025 | } | 1016 | } |
| 1026 | } | 1017 | } |
| 1027 | QTC::TC("qpdf", "QPDF xref /Index is array", n_index == 2 ? 0 : 1); | 1018 | QTC::TC("qpdf", "QPDF xref /Index is array", n_index == 2 ? 0 : 1); |
| @@ -1041,12 +1032,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | @@ -1041,12 +1032,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj) | ||
| 1041 | // first object number + number of entries <= /Size. The spec requires us to ignore object | 1032 | // first object number + number of entries <= /Size. The spec requires us to ignore object |
| 1042 | // number > /Size. | 1033 | // number > /Size. |
| 1043 | if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) { | 1034 | if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) { |
| 1044 | - throw damagedPDF( | ||
| 1045 | - "xref stream", | ||
| 1046 | - xref_offset, | ||
| 1047 | - ("Cross-reference stream claims to contain too many entries: " + | ||
| 1048 | - std::to_string(indx.at(i)) + " " + std::to_string(max_num_entries) + " " + | ||
| 1049 | - std::to_string(num_entries))); | 1035 | + throw damaged( |
| 1036 | + "Cross-reference stream claims to contain too many entries: " + | ||
| 1037 | + std::to_string(indx.at(i)) + " " + std::to_string(max_num_entries) + " " + | ||
| 1038 | + std::to_string(num_entries)); | ||
| 1050 | } | 1039 | } |
| 1051 | num_entries += toS(indx.at(i)); | 1040 | num_entries += toS(indx.at(i)); |
| 1052 | } | 1041 | } |