Commit a1a8f35b63bcad7e0cac31a205e109d6a0d70622
1 parent
51d350c9
Refactor QPDF_Array::getItem and rename to at
Showing
5 changed files
with
74 additions
and
88 deletions
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -801,90 +801,88 @@ QPDFObjectHandle::getArrayNItems() |
| 801 | 801 | QPDFObjectHandle |
| 802 | 802 | QPDFObjectHandle::getArrayItem(int n) |
| 803 | 803 | { |
| 804 | - auto array = asArray(); | |
| 805 | - if (array && n < array->size() && n >= 0) { | |
| 806 | - return array->getItem(n); | |
| 807 | - } else { | |
| 808 | - if (array) { | |
| 804 | + if (auto array = asArray()) { | |
| 805 | + if (auto result = array->at(n); result.obj != nullptr) { | |
| 806 | + return result; | |
| 807 | + } else { | |
| 809 | 808 | objectWarning("returning null for out of bounds array access"); |
| 810 | 809 | QTC::TC("qpdf", "QPDFObjectHandle array bounds"); |
| 811 | - } else { | |
| 812 | - typeWarning("array", "returning null"); | |
| 813 | - QTC::TC("qpdf", "QPDFObjectHandle array null for non-array"); | |
| 814 | 810 | } |
| 815 | - static auto constexpr msg = | |
| 816 | - " -> null returned from invalid array access"sv; | |
| 817 | - return QPDF_Null::create(obj, msg, ""); | |
| 811 | + } else { | |
| 812 | + typeWarning("array", "returning null"); | |
| 813 | + QTC::TC("qpdf", "QPDFObjectHandle array null for non-array"); | |
| 818 | 814 | } |
| 815 | + static auto constexpr msg = " -> null returned from invalid array access"sv; | |
| 816 | + return QPDF_Null::create(obj, msg, ""); | |
| 819 | 817 | } |
| 820 | 818 | |
| 821 | 819 | bool |
| 822 | 820 | QPDFObjectHandle::isRectangle() |
| 823 | 821 | { |
| 824 | - auto array = asArray(); | |
| 825 | - if (array == nullptr || array->size() != 4) { | |
| 826 | - return false; | |
| 827 | - } | |
| 828 | - for (int i = 0; i < 4; ++i) { | |
| 829 | - if (!array->getItem(i).isNumber()) { | |
| 830 | - return false; | |
| 822 | + if (auto array = asArray()) { | |
| 823 | + for (int i = 0; i < 4; ++i) { | |
| 824 | + if (auto item = array->at(i); !(item.obj && item.isNumber())) { | |
| 825 | + return false; | |
| 826 | + } | |
| 831 | 827 | } |
| 828 | + return array->size() == 4; | |
| 832 | 829 | } |
| 833 | - return true; | |
| 830 | + return false; | |
| 834 | 831 | } |
| 835 | 832 | |
| 836 | 833 | bool |
| 837 | 834 | QPDFObjectHandle::isMatrix() |
| 838 | 835 | { |
| 839 | - auto array = asArray(); | |
| 840 | - if (array == nullptr || array->size() != 6) { | |
| 841 | - return false; | |
| 842 | - } | |
| 843 | - for (int i = 0; i < 6; ++i) { | |
| 844 | - if (!array->getItem(i).isNumber()) { | |
| 845 | - return false; | |
| 836 | + if (auto array = asArray()) { | |
| 837 | + for (int i = 0; i < 6; ++i) { | |
| 838 | + if (auto item = array->at(i); !(item.obj && item.isNumber())) { | |
| 839 | + return false; | |
| 840 | + } | |
| 846 | 841 | } |
| 842 | + return array->size() == 6; | |
| 847 | 843 | } |
| 848 | - return true; | |
| 844 | + return false; | |
| 849 | 845 | } |
| 850 | 846 | |
| 851 | 847 | QPDFObjectHandle::Rectangle |
| 852 | 848 | QPDFObjectHandle::getArrayAsRectangle() |
| 853 | 849 | { |
| 854 | - Rectangle result; | |
| 855 | - if (isRectangle()) { | |
| 856 | - auto array = asArray(); | |
| 857 | - // Rectangle coordinates are always supposed to be llx, lly, | |
| 858 | - // urx, ury, but files have been found in the wild where | |
| 859 | - // llx > urx or lly > ury. | |
| 860 | - double i0 = array->getItem(0).getNumericValue(); | |
| 861 | - double i1 = array->getItem(1).getNumericValue(); | |
| 862 | - double i2 = array->getItem(2).getNumericValue(); | |
| 863 | - double i3 = array->getItem(3).getNumericValue(); | |
| 864 | - result = Rectangle( | |
| 865 | - std::min(i0, i2), | |
| 866 | - std::min(i1, i3), | |
| 867 | - std::max(i0, i2), | |
| 868 | - std::max(i1, i3)); | |
| 850 | + if (auto array = asArray()) { | |
| 851 | + if (array->size() != 4) { | |
| 852 | + return {}; | |
| 853 | + } | |
| 854 | + double items[4]; | |
| 855 | + for (int i = 0; i < 4; ++i) { | |
| 856 | + if (!array->at(i).getValueAsNumber(items[i])) { | |
| 857 | + return {}; | |
| 858 | + } | |
| 859 | + } | |
| 860 | + return Rectangle( | |
| 861 | + std::min(items[0], items[2]), | |
| 862 | + std::min(items[1], items[3]), | |
| 863 | + std::max(items[0], items[2]), | |
| 864 | + std::max(items[1], items[3])); | |
| 869 | 865 | } |
| 870 | - return result; | |
| 866 | + return {}; | |
| 871 | 867 | } |
| 872 | 868 | |
| 873 | 869 | QPDFObjectHandle::Matrix |
| 874 | 870 | QPDFObjectHandle::getArrayAsMatrix() |
| 875 | 871 | { |
| 876 | - Matrix result; | |
| 877 | - if (isMatrix()) { | |
| 878 | - auto array = asArray(); | |
| 879 | - result = Matrix( | |
| 880 | - array->getItem(0).getNumericValue(), | |
| 881 | - array->getItem(1).getNumericValue(), | |
| 882 | - array->getItem(2).getNumericValue(), | |
| 883 | - array->getItem(3).getNumericValue(), | |
| 884 | - array->getItem(4).getNumericValue(), | |
| 885 | - array->getItem(5).getNumericValue()); | |
| 872 | + if (auto array = asArray()) { | |
| 873 | + if (array->size() != 6) { | |
| 874 | + return {}; | |
| 875 | + } | |
| 876 | + double items[6]; | |
| 877 | + for (int i = 0; i < 6; ++i) { | |
| 878 | + if (!array->at(i).getValueAsNumber(items[i])) { | |
| 879 | + return {}; | |
| 880 | + } | |
| 881 | + } | |
| 882 | + return Matrix( | |
| 883 | + items[0], items[1], items[2], items[3], items[4], items[5]); | |
| 886 | 884 | } |
| 887 | - return result; | |
| 885 | + return {}; | |
| 888 | 886 | } |
| 889 | 887 | |
| 890 | 888 | std::vector<QPDFObjectHandle> |
| ... | ... | @@ -991,8 +989,8 @@ QPDFObjectHandle |
| 991 | 989 | QPDFObjectHandle::eraseItemAndGetOld(int at) |
| 992 | 990 | { |
| 993 | 991 | auto array = asArray(); |
| 994 | - auto result = (array && at < array->size() && at >= 0) ? array->getItem(at) | |
| 995 | - : newNull(); | |
| 992 | + auto result = | |
| 993 | + (array && at < array->size() && at >= 0) ? array->at(at) : newNull(); | |
| 996 | 994 | eraseItem(at); |
| 997 | 995 | return result; |
| 998 | 996 | } |
| ... | ... | @@ -1515,7 +1513,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray( |
| 1515 | 1513 | if (auto array = asArray()) { |
| 1516 | 1514 | int n_items = array->size(); |
| 1517 | 1515 | for (int i = 0; i < n_items; ++i) { |
| 1518 | - QPDFObjectHandle item = array->getItem(i); | |
| 1516 | + QPDFObjectHandle item = array->at(i); | |
| 1519 | 1517 | if (item.isStream()) { |
| 1520 | 1518 | result.push_back(item); |
| 1521 | 1519 | } else { |
| ... | ... | @@ -2215,7 +2213,7 @@ QPDFObjectHandle::makeDirect( |
| 2215 | 2213 | auto array = asArray(); |
| 2216 | 2214 | int n = array->size(); |
| 2217 | 2215 | for (int i = 0; i < n; ++i) { |
| 2218 | - items.push_back(array->getItem(i)); | |
| 2216 | + items.push_back(array->at(i)); | |
| 2219 | 2217 | items.back().makeDirect(visited, stop_at_streams); |
| 2220 | 2218 | } |
| 2221 | 2219 | this->obj = QPDF_Array::create(items); | ... | ... |
libqpdf/QPDF_Array.cc
| ... | ... | @@ -105,7 +105,7 @@ QPDF_Array::unparse() |
| 105 | 105 | std::string result = "[ "; |
| 106 | 106 | int size = sp_elements.size(); |
| 107 | 107 | for (int i = 0; i < size; ++i) { |
| 108 | - result += sp_elements.at(i).unparse(); | |
| 108 | + result += at(i).unparse(); | |
| 109 | 109 | result += " "; |
| 110 | 110 | } |
| 111 | 111 | result += "]"; |
| ... | ... | @@ -114,7 +114,7 @@ QPDF_Array::unparse() |
| 114 | 114 | std::string result = "[ "; |
| 115 | 115 | auto size = elements.size(); |
| 116 | 116 | for (int i = 0; i < int(size); ++i) { |
| 117 | - result += getItem(i).unparse(); | |
| 117 | + result += at(i).unparse(); | |
| 118 | 118 | result += " "; |
| 119 | 119 | } |
| 120 | 120 | result += "]"; |
| ... | ... | @@ -129,35 +129,29 @@ QPDF_Array::getJSON(int json_version) |
| 129 | 129 | JSON j = JSON::makeArray(); |
| 130 | 130 | int size = sp_elements.size(); |
| 131 | 131 | for (int i = 0; i < size; ++i) { |
| 132 | - j.addArrayElement(sp_elements.at(i).getJSON(json_version)); | |
| 132 | + j.addArrayElement(at(i).getJSON(json_version)); | |
| 133 | 133 | } |
| 134 | 134 | return j; |
| 135 | 135 | } else { |
| 136 | 136 | JSON j = JSON::makeArray(); |
| 137 | 137 | size_t size = elements.size(); |
| 138 | 138 | for (int i = 0; i < int(size); ++i) { |
| 139 | - j.addArrayElement(getItem(i).getJSON(json_version)); | |
| 139 | + j.addArrayElement(at(i).getJSON(json_version)); | |
| 140 | 140 | } |
| 141 | 141 | return j; |
| 142 | 142 | } |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | QPDFObjectHandle |
| 146 | -QPDF_Array::getItem(int n) const | |
| 146 | +QPDF_Array::at(int n) const noexcept | |
| 147 | 147 | { |
| 148 | - if (sparse) { | |
| 149 | - if ((n < 0) || (n >= QIntC::to_int(sp_elements.size()))) { | |
| 150 | - throw std::logic_error( | |
| 151 | - "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | |
| 152 | - } | |
| 153 | - return sp_elements.at(n); | |
| 148 | + if (n < 0 || n >= size()) { | |
| 149 | + return {}; | |
| 150 | + } else if (sparse) { | |
| 151 | + auto const& iter = sp_elements.elements.find(n); | |
| 152 | + return iter == sp_elements.elements.end() ? null_oh : (*iter).second; | |
| 154 | 153 | } else { |
| 155 | - if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { | |
| 156 | - throw std::logic_error( | |
| 157 | - "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | |
| 158 | - } | |
| 159 | - auto const& obj = elements.at(size_t(n)); | |
| 160 | - return obj ? obj : null_oh; | |
| 154 | + return elements[size_t(n)]; | |
| 161 | 155 | } |
| 162 | 156 | } |
| 163 | 157 | |
| ... | ... | @@ -167,7 +161,7 @@ QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const |
| 167 | 161 | if (sparse) { |
| 168 | 162 | int size = sp_elements.size(); |
| 169 | 163 | for (int i = 0; i < size; ++i) { |
| 170 | - v.push_back(sp_elements.at(i)); | |
| 164 | + v.push_back(at(i)); | |
| 171 | 165 | } |
| 172 | 166 | } else { |
| 173 | 167 | v = std::vector<QPDFObjectHandle>(elements.cbegin(), elements.cend()); | ... | ... |
libqpdf/SparseOHArray.cc
| ... | ... | @@ -2,6 +2,8 @@ |
| 2 | 2 | |
| 3 | 3 | #include <stdexcept> |
| 4 | 4 | |
| 5 | +static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull(); | |
| 6 | + | |
| 5 | 7 | void |
| 6 | 8 | SparseOHArray::append(QPDFObjectHandle oh) |
| 7 | 9 | { |
| ... | ... | @@ -23,16 +25,8 @@ SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj) |
| 23 | 25 | QPDFObjectHandle |
| 24 | 26 | SparseOHArray::at(int idx) const |
| 25 | 27 | { |
| 26 | - if (idx < 0 || idx >= this->n_elements) { | |
| 27 | - throw std::logic_error( | |
| 28 | - "INTERNAL ERROR: bounds error accessing SparseOHArray element"); | |
| 29 | - } | |
| 30 | - auto const& iter = this->elements.find(idx); | |
| 31 | - if (iter == this->elements.end()) { | |
| 32 | - return QPDFObjectHandle::newNull(); | |
| 33 | - } else { | |
| 34 | - return (*iter).second; | |
| 35 | - } | |
| 28 | + auto const& iter = elements.find(idx); | |
| 29 | + return iter == elements.end() ? null_oh : (*iter).second; | |
| 36 | 30 | } |
| 37 | 31 | |
| 38 | 32 | void | ... | ... |
libqpdf/qpdf/QPDF_Array.hh
| ... | ... | @@ -27,7 +27,7 @@ class QPDF_Array: public QPDFValue |
| 27 | 27 | { |
| 28 | 28 | return sparse ? sp_elements.size() : int(elements.size()); |
| 29 | 29 | } |
| 30 | - QPDFObjectHandle getItem(int n) const; | |
| 30 | + QPDFObjectHandle at(int n) const noexcept; | |
| 31 | 31 | void getAsVector(std::vector<QPDFObjectHandle>&) const; |
| 32 | 32 | |
| 33 | 33 | void setItem(int, QPDFObjectHandle const&); | ... | ... |