Commit decc7d3c12ab8ce4a6c77d48cfc57d721913b887

Authored by m-holger
1 parent 587177b1

Refactor `QPDFObjectHandle` and `BaseHandle`: streamline type handling, simplify…

… warnings, and centralize utility methods.
include/qpdf/ObjectHandle.hh
@@ -22,7 +22,10 @@ @@ -22,7 +22,10 @@
22 22
23 #include <qpdf/Constants.h> 23 #include <qpdf/Constants.h>
24 #include <qpdf/DLL.h> 24 #include <qpdf/DLL.h>
  25 +#include <qpdf/Types.h>
  26 +
25 #include <qpdf/JSON.hh> 27 #include <qpdf/JSON.hh>
  28 +#include <qpdf/QPDFExc.hh>
26 #include <qpdf/QPDFObjGen.hh> 29 #include <qpdf/QPDFObjGen.hh>
27 #include <qpdf/Types.h> 30 #include <qpdf/Types.h>
28 31
@@ -71,6 +74,9 @@ namespace qpdf @@ -71,6 +74,9 @@ namespace qpdf
71 inline qpdf_object_type_e type_code() const; 74 inline qpdf_object_type_e type_code() const;
72 std::string unparse() const; 75 std::string unparse() const;
73 void write_json(int json_version, JSON::Writer& p) const; 76 void write_json(int json_version, JSON::Writer& p) const;
  77 + static void warn(QPDF*, QPDFExc&&);
  78 + void warn(QPDFExc&&) const;
  79 + void warn(std::string const& warning) const;
74 80
75 protected: 81 protected:
76 BaseHandle() = default; 82 BaseHandle() = default;
@@ -87,6 +93,11 @@ namespace qpdf @@ -87,6 +93,11 @@ namespace qpdf
87 template <typename T> 93 template <typename T>
88 T* as() const; 94 T* as() const;
89 95
  96 + std::string description() const;
  97 + std::runtime_error type_error(char const* expected_type) const;
  98 + QPDFExc type_error(char const* expected_type, std::string const& message) const;
  99 + char const* type_name() const;
  100 +
90 std::shared_ptr<QPDFObject> obj; 101 std::shared_ptr<QPDFObject> obj;
91 }; 102 };
92 103
include/qpdf/QPDFObjectHandle.hh
@@ -1357,7 +1357,6 @@ class QPDFObjectHandle: public qpdf::BaseHandle @@ -1357,7 +1357,6 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1357 QPDF* context); 1357 QPDF* context);
1358 std::vector<QPDFObjectHandle> 1358 std::vector<QPDFObjectHandle>
1359 arrayOrStreamToStreamArray(std::string const& description, std::string& all_description); 1359 arrayOrStreamToStreamArray(std::string const& description, std::string& all_description);
1360 - static void warn(QPDF*, QPDFExc const&);  
1361 void checkOwnership(QPDFObjectHandle const&) const; 1360 void checkOwnership(QPDFObjectHandle const&) const;
1362 }; 1361 };
1363 1362
libqpdf/QPDFObjectHandle.cc
@@ -611,11 +611,11 @@ QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const&amp; rhs) const @@ -611,11 +611,11 @@ QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const&amp; rhs) const
611 qpdf_object_type_e 611 qpdf_object_type_e
612 QPDFObjectHandle::getTypeCode() const 612 QPDFObjectHandle::getTypeCode() const
613 { 613 {
614 - return obj ? obj->getResolvedTypeCode() : ::ot_uninitialized; 614 + return type_code();
615 } 615 }
616 616
617 char const* 617 char const*
618 -QPDFObjectHandle::getTypeName() const 618 +BaseHandle::type_name() const
619 { 619 {
620 static constexpr std::array<char const*, 16> tn{ 620 static constexpr std::array<char const*, 16> tn{
621 "uninitialized", 621 "uninitialized",
@@ -634,7 +634,13 @@ QPDFObjectHandle::getTypeName() const @@ -634,7 +634,13 @@ QPDFObjectHandle::getTypeName() const
634 "unresolved", 634 "unresolved",
635 "destroyed", 635 "destroyed",
636 "reference"}; 636 "reference"};
637 - return obj ? tn[getTypeCode()] : "uninitialized"; 637 + return tn[type_code()];
  638 +}
  639 +
  640 +char const*
  641 +QPDFObjectHandle::getTypeName() const
  642 +{
  643 + return type_name();
638 } 644 }
639 645
640 bool 646 bool
@@ -1242,27 +1248,23 @@ QPDFObjectHandle::arrayOrStreamToStreamArray( @@ -1242,27 +1248,23 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
1242 result.emplace_back(item); 1248 result.emplace_back(item);
1243 } else { 1249 } else {
1244 QTC::TC("qpdf", "QPDFObjectHandle non-stream in stream array"); 1250 QTC::TC("qpdf", "QPDFObjectHandle non-stream in stream array");
1245 - warn(  
1246 - item.getOwningQPDF(),  
1247 - QPDFExc(  
1248 - qpdf_e_damaged_pdf,  
1249 - "",  
1250 - description + ": item index " + std::to_string(i) + " (from 0)",  
1251 - 0,  
1252 - "ignoring non-stream in an array of streams")); 1251 + item.warn(
  1252 + {qpdf_e_damaged_pdf,
  1253 + "",
  1254 + description + ": item index " + std::to_string(i) + " (from 0)",
  1255 + 0,
  1256 + "ignoring non-stream in an array of streams"});
1253 } 1257 }
1254 } 1258 }
1255 } else if (isStream()) { 1259 } else if (isStream()) {
1256 result.emplace_back(*this); 1260 result.emplace_back(*this);
1257 - } else if (!isNull()) { 1261 + } else if (!null()) {
1258 warn( 1262 warn(
1259 - getOwningQPDF(),  
1260 - QPDFExc(  
1261 - qpdf_e_damaged_pdf,  
1262 - "",  
1263 - description,  
1264 - 0,  
1265 - " object is supposed to be a stream or an array of streams but is neither")); 1263 + {qpdf_e_damaged_pdf,
  1264 + "",
  1265 + description,
  1266 + 0,
  1267 + " object is supposed to be a stream or an array of streams but is neither"});
1266 } 1268 }
1267 1269
1268 bool first = true; 1270 bool first = true;
@@ -1824,6 +1826,12 @@ QPDFObjectHandle::newReserved(QPDF* qpdf) @@ -1824,6 +1826,12 @@ QPDFObjectHandle::newReserved(QPDF* qpdf)
1824 return qpdf->newReserved(); 1826 return qpdf->newReserved();
1825 } 1827 }
1826 1828
  1829 +std::string
  1830 +BaseHandle::description() const
  1831 +{
  1832 + return obj ? obj->getDescription() : ""s;
  1833 +}
  1834 +
1827 void 1835 void
1828 QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, std::string const& object_description) 1836 QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, std::string const& object_description)
1829 { 1837 {
@@ -1934,50 +1942,44 @@ QPDFObjectHandle::assertInitialized() const @@ -1934,50 +1942,44 @@ QPDFObjectHandle::assertInitialized() const
1934 } 1942 }
1935 } 1943 }
1936 1944
  1945 +std::runtime_error
  1946 +BaseHandle::type_error(char const* expected_type) const
  1947 +{
  1948 + return std::runtime_error(
  1949 + "operation for "s + expected_type + " attempted on object of type " + type_name());
  1950 +}
  1951 +
  1952 +QPDFExc
  1953 +BaseHandle::type_error(char const* expected_type, std::string const& message) const
  1954 +{
  1955 + return {
  1956 + qpdf_e_object,
  1957 + "",
  1958 + description(),
  1959 + 0,
  1960 + "operation for "s + expected_type + " attempted on object of type " + type_name() + ": " +
  1961 + message};
  1962 +}
  1963 +
1937 void 1964 void
1938 -QPDFObjectHandle::typeWarning(char const* expected_type, std::string const& warning) const 1965 +QPDFObjectHandle::typeWarning(char const* expected_type, std::string const& message) const
1939 { 1966 {
1940 - QPDF* context = nullptr;  
1941 - std::string description;  
1942 - // Type checks above guarantee that the object has been dereferenced. Nevertheless, dereference  
1943 - // throws exceptions in the test suite  
1944 if (!obj) { 1967 if (!obj) {
1945 throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle"); 1968 throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
1946 } 1969 }
1947 - obj->getDescription(context, description);  
1948 - // Null context handled by warn  
1949 - warn(  
1950 - context,  
1951 - QPDFExc(  
1952 - qpdf_e_object,  
1953 - "",  
1954 - description,  
1955 - 0,  
1956 - std::string("operation for ") + expected_type + " attempted on object of type " +  
1957 - QPDFObjectHandle(*this).getTypeName() + ": " + warning)); 1970 + warn(type_error(expected_type, message));
1958 } 1971 }
1959 1972
1960 void 1973 void
1961 QPDFObjectHandle::warnIfPossible(std::string const& warning) const 1974 QPDFObjectHandle::warnIfPossible(std::string const& warning) const
1962 { 1975 {
1963 - QPDF* context = nullptr;  
1964 - std::string description;  
1965 - if (obj && obj->getDescription(context, description)) {  
1966 - warn(context, QPDFExc(qpdf_e_damaged_pdf, "", description, 0, warning));  
1967 - } else {  
1968 - *QPDFLogger::defaultLogger()->getError() << warning << "\n";  
1969 - } 1976 + warn(warning);
1970 } 1977 }
1971 1978
1972 void 1979 void
1973 QPDFObjectHandle::objectWarning(std::string const& warning) const 1980 QPDFObjectHandle::objectWarning(std::string const& warning) const
1974 { 1981 {
1975 - QPDF* context = nullptr;  
1976 - std::string description;  
1977 - // Type checks above guarantee that the object is initialized.  
1978 - obj->getDescription(context, description);  
1979 - // Null context handled by warn  
1980 - warn(context, QPDFExc(qpdf_e_object, "", description, 0, warning)); 1982 + warn({qpdf_e_object, "", description(), 0, warning});
1981 } 1983 }
1982 1984
1983 void 1985 void
@@ -2130,15 +2132,30 @@ QPDFObjectHandle::assertPageObject() const @@ -2130,15 +2132,30 @@ QPDFObjectHandle::assertPageObject() const
2130 } 2132 }
2131 2133
2132 void 2134 void
2133 -QPDFObjectHandle::warn(QPDF* qpdf, QPDFExc const& e) 2135 +BaseHandle::warn(QPDF* qpdf, QPDFExc&& e)
2134 { 2136 {
2135 - // If parsing on behalf of a QPDF object and want to give a warning, we can warn through the  
2136 - // object. If parsing for some other reason, such as an explicit creation of an object from a  
2137 - // string, then just throw the exception.  
2138 - if (qpdf) {  
2139 - qpdf->warn(e); 2137 + if (!qpdf) {
  2138 + throw std::move(e);
  2139 + }
  2140 + qpdf->warn(std::move(e));
  2141 +}
  2142 +
  2143 +void
  2144 +BaseHandle::warn(QPDFExc&& e) const
  2145 +{
  2146 + if (!qpdf()) {
  2147 + throw std::move(e);
  2148 + }
  2149 + qpdf()->warn(std::move(e));
  2150 +}
  2151 +
  2152 +void
  2153 +BaseHandle::warn(std::string const& warning) const
  2154 +{
  2155 + if (qpdf()) {
  2156 + warn({qpdf_e_damaged_pdf, "", description(), 0, warning});
2140 } else { 2157 } else {
2141 - throw e; 2158 + *QPDFLogger::defaultLogger()->getError() << warning << "\n";
2142 } 2159 }
2143 } 2160 }
2144 2161
libqpdf/qpdf/QPDFObject_private.hh
@@ -434,13 +434,6 @@ class QPDFObject @@ -434,13 +434,6 @@ class QPDFObject
434 parsed_offset = offset; 434 parsed_offset = offset;
435 } 435 }
436 } 436 }
437 - bool  
438 - getDescription(QPDF*& a_qpdf, std::string& description)  
439 - {  
440 - a_qpdf = qpdf;  
441 - description = getDescription();  
442 - return qpdf != nullptr;  
443 - }  
444 qpdf_offset_t 437 qpdf_offset_t
445 getParsedOffset() 438 getParsedOffset()
446 { 439 {