diff options
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDF.cc | 12 | ||||
-rw-r--r-- | libqpdf/QPDFObjectHandle.cc | 62 | ||||
-rw-r--r-- | libqpdf/QPDF_Reserved.cc | 13 | ||||
-rw-r--r-- | libqpdf/build.mk | 1 | ||||
-rw-r--r-- | libqpdf/qpdf/QPDF_Reserved.hh | 13 |
5 files changed, 96 insertions, 5 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index a66b4f15..1c4e5d8d 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -2057,6 +2057,18 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) } void +QPDF::replaceReserved(QPDFObjectHandle reserved, + QPDFObjectHandle replacement) +{ + QTC::TC("qpdf", "QPDF replaceReserved"); + reserved.assertReserved(); + replaceObject(reserved.getObjectID(), + reserved.getGeneration(), + replacement); +} + + +void QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2) { // Force objects to be loaded into cache; then swap them in the diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 73d0019c..25298bee 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -10,6 +10,7 @@ #include <qpdf/QPDF_Array.hh> #include <qpdf/QPDF_Dictionary.hh> #include <qpdf/QPDF_Stream.hh> +#include <qpdf/QPDF_Reserved.hh> #include <qpdf/QTC.hh> #include <qpdf/QUtil.hh> @@ -20,7 +21,8 @@ QPDFObjectHandle::QPDFObjectHandle() : initialized(false), objid(0), - generation(0) + generation(0), + reserved(false) { } @@ -28,7 +30,8 @@ QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, int objid, int generation) : initialized(true), qpdf(qpdf), objid(objid), - generation(generation) + generation(generation), + reserved(false) { } @@ -37,7 +40,8 @@ QPDFObjectHandle::QPDFObjectHandle(QPDFObject* data) : qpdf(0), objid(0), generation(0), - obj(data) + obj(data), + reserved(false) { } @@ -166,6 +170,14 @@ QPDFObjectHandle::isStream() } bool +QPDFObjectHandle::isReserved() +{ + // dereference will clear reserved if this has been replaced + dereference(); + return this->reserved; +} + +bool QPDFObjectHandle::isIndirect() { assertInitialized(); @@ -568,6 +580,11 @@ QPDFObjectHandle::unparse() std::string QPDFObjectHandle::unparseResolved() { + if (this->reserved) + { + throw std::logic_error( + "QPDFObjectHandle: attempting to unparse a reserved object"); + } dereference(); return this->obj->unparse(); } @@ -690,6 +707,19 @@ QPDFObjectHandle::newStream(QPDF* qpdf, std::string const& data) } QPDFObjectHandle +QPDFObjectHandle::newReserved(QPDF* qpdf) +{ + // Reserve a spot for this object by assigning it an object + // number, but then return an unresolved handle to the object. + QPDFObjectHandle reserved = qpdf->makeIndirectObject( + QPDFObjectHandle(new QPDF_Reserved())); + QPDFObjectHandle result = + newIndirect(qpdf, reserved.objid, reserved.generation); + result.reserved = true; + return result; +} + +QPDFObjectHandle QPDFObjectHandle::shallowCopy() { assertInitialized(); @@ -746,6 +776,13 @@ QPDFObjectHandle::makeDirectInternal(std::set<int>& visited) visited.insert(cur_objid); } + if (isReserved()) + { + throw std::logic_error( + "QPDFObjectHandle: attempting to make a" + " reserved object handle direct"); + } + dereference(); this->objid = 0; this->generation = 0; @@ -903,6 +940,12 @@ QPDFObjectHandle::assertStream() } void +QPDFObjectHandle::assertReserved() +{ + assertType("Reserved", isReserved()); +} + +void QPDFObjectHandle::assertScalar() { assertType("Scalar", isScalar()); @@ -929,12 +972,21 @@ QPDFObjectHandle::dereference() { if (this->obj.getPointer() == 0) { - this->obj = QPDF::Resolver::resolve( + PointerHolder<QPDFObject> obj = QPDF::Resolver::resolve( this->qpdf, this->objid, this->generation); - if (this->obj.getPointer() == 0) + if (obj.getPointer() == 0) { QTC::TC("qpdf", "QPDFObjectHandle indirect to unknown"); this->obj = new QPDF_Null(); } + else if (dynamic_cast<QPDF_Reserved*>(obj.getPointer())) + { + // Do not resolve + } + else + { + this->reserved = false; + this->obj = obj; + } } } diff --git a/libqpdf/QPDF_Reserved.cc b/libqpdf/QPDF_Reserved.cc new file mode 100644 index 00000000..368db3b4 --- /dev/null +++ b/libqpdf/QPDF_Reserved.cc @@ -0,0 +1,13 @@ +#include <qpdf/QPDF_Reserved.hh> +#include <stdexcept> + +QPDF_Reserved::~QPDF_Reserved() +{ +} + +std::string +QPDF_Reserved::unparse() +{ + throw std::logic_error("attempt to unparse QPDF_Reserved"); + return ""; +} diff --git a/libqpdf/build.mk b/libqpdf/build.mk index 7efbbd85..422878f2 100644 --- a/libqpdf/build.mk +++ b/libqpdf/build.mk @@ -39,6 +39,7 @@ SRCS_libqpdf = \ libqpdf/QPDF_Name.cc \ libqpdf/QPDF_Null.cc \ libqpdf/QPDF_Real.cc \ + libqpdf/QPDF_Reserved.cc \ libqpdf/QPDF_Stream.cc \ libqpdf/QPDF_String.cc \ libqpdf/QPDF_encryption.cc \ diff --git a/libqpdf/qpdf/QPDF_Reserved.hh b/libqpdf/qpdf/QPDF_Reserved.hh new file mode 100644 index 00000000..b149f776 --- /dev/null +++ b/libqpdf/qpdf/QPDF_Reserved.hh @@ -0,0 +1,13 @@ +#ifndef __QPDF_RESERVED_HH__ +#define __QPDF_RESERVED_HH__ + +#include <qpdf/QPDFObject.hh> + +class QPDF_Reserved: public QPDFObject +{ + public: + virtual ~QPDF_Reserved(); + virtual std::string unparse(); +}; + +#endif // __QPDF_RESERVED_HH__ |