diff options
author | Jay Berkenbilt <ejb@ql.org> | 2012-07-21 15:00:06 +0200 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2012-07-21 15:06:10 +0200 |
commit | 6bbea4baa0c06b39b1b71f1aa6fc276789296556 (patch) | |
tree | 62198136a609c86029d124323be9e2ea72f88d9a /include | |
parent | f3e267fce28c58039789379ba3488ad12c20a7f6 (diff) | |
download | qpdf-6bbea4baa0c06b39b1b71f1aa6fc276789296556.tar.zst |
Implement QPDFObjectHandle::parse
Move object parsing code from QPDF to QPDFObjectHandle and
parameterize the parts of it that are specific to a QPDF object.
Provide a version that can't handle indirect objects and that can be
called on an arbitrary string.
A side effect of this change is that the offset used when reporting
invalid stream length has changed, but since the new value seems like
a better value than the old one, the test suite has been updated
rather than making the code backward compatible. This only effects
the offset reported for invalid streams that lack /Length or have an
invalid /Length key.
Updated some test code and exmaples to use QPDFObjectHandle::parse.
Supporting changes include adding a BufferInputSource constructor that
takes a string.
Diffstat (limited to 'include')
-rw-r--r-- | include/qpdf/BufferInputSource.hh | 2 | ||||
-rw-r--r-- | include/qpdf/QPDF.hh | 21 | ||||
-rw-r--r-- | include/qpdf/QPDFObjectHandle.hh | 56 |
3 files changed, 74 insertions, 5 deletions
diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh index 63c14def..48f6e3ac 100644 --- a/include/qpdf/BufferInputSource.hh +++ b/include/qpdf/BufferInputSource.hh @@ -9,6 +9,8 @@ class BufferInputSource: public InputSource public: BufferInputSource(std::string const& description, Buffer* buf, bool own_memory = false); + BufferInputSource(std::string const& description, + std::string const& contents); virtual ~BufferInputSource(); virtual qpdf_offset_t findAndSkipNextEOL(); virtual std::string const& getName() const; diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index e6ff75b4..dc6e9090 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -531,6 +531,23 @@ class QPDF std::map<ObjGen, QPDFObjectHandle> foreign_streams; }; + class StringDecrypter: public QPDFObjectHandle::StringDecrypter + { + friend class QPDF; + + public: + StringDecrypter(QPDF* qpdf, int objid, int gen); + virtual ~StringDecrypter() + { + } + virtual void decryptString(std::string& val); + + private: + QPDF* qpdf; + int objid; + int gen; + }; + void parse(char const* password); void warn(QPDFExc const& e); void setTrailer(QPDFObjectHandle obj); @@ -547,10 +564,6 @@ class QPDF QPDFObjectHandle readObject( PointerHolder<InputSource>, std::string const& description, int objid, int generation, bool in_object_stream); - QPDFObjectHandle readObjectInternal( - PointerHolder<InputSource> input, int objid, int generation, - bool in_object_stream, - bool in_array, bool in_dictionary); size_t recoverStreamLength( PointerHolder<InputSource> input, int objid, int generation, qpdf_offset_t stream_offset); diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 22ded37e..a1819d99 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -18,6 +18,7 @@ #include <qpdf/PointerHolder.hh> #include <qpdf/Buffer.hh> +#include <qpdf/InputSource.hh> #include <qpdf/QPDFObject.hh> @@ -25,6 +26,7 @@ class Pipeline; class QPDF; class QPDF_Dictionary; class QPDF_Array; +class QPDFTokenizer; class QPDFObjectHandle { @@ -57,6 +59,18 @@ class QPDFObjectHandle Pipeline* pipeline) = 0; }; + // This class is used by parse to decrypt strings when reading an + // object that contains encrypted strings. + class StringDecrypter + { + public: + QPDF_DLL + virtual ~StringDecrypter() + { + } + virtual void decryptString(std::string& val) = 0; + }; + QPDF_DLL QPDFObjectHandle(); QPDF_DLL @@ -95,6 +109,30 @@ class QPDFObjectHandle // Public factory methods + // Construct an object of any type from a string representation of + // the object. Throws QPDFExc with an empty filename and an + // offset into the string if there is an error. Any indirect + // object syntax (obj gen R) will cause a logic_error exception to + // be thrown. If object_description is provided, it will appear + // in the message of any QPDFExc exception thrown for invalid + // syntax. + QPDF_DLL + static QPDFObjectHandle parse(std::string const& object_str, + std::string const& object_description = ""); + + // Construct an object as above by reading from the given + // InputSource at its current position and using the tokenizer you + // supply. Indirect objects and encrypted strings are permitted. + // This method is intended to be called by QPDF for parsing + // objects that are ready from the object's input stream. + QPDF_DLL + static QPDFObjectHandle parse(PointerHolder<InputSource> input, + std::string const& object_description, + QPDFTokenizer&, bool& empty, + StringDecrypter* decrypter, + QPDF* context); + + // Type-specific factories QPDF_DLL static QPDFObjectHandle newNull(); QPDF_DLL @@ -124,7 +162,8 @@ class QPDFObjectHandle // object. A subsequent call must be made to replaceStreamData() // to provide data for the stream. The stream's dictionary may be // retrieved by calling getDict(), and the resulting dictionary - // may be modified. + // may be modified. Alternatively, you can create a new + // dictionary and call replaceDict to install it. QPDF_DLL static QPDFObjectHandle newStream(QPDF* qpdf); @@ -303,6 +342,15 @@ class QPDFObjectHandle bool pipeStreamData(Pipeline*, bool filter, bool normalize, bool compress); + // Replace a stream's dictionary. The new dictionary must be + // consistent with the stream's data. This is most appropriately + // used when creating streams from scratch that will use a stream + // data provider and therefore start with an empty dictionary. It + // may be more convenient in this case than calling getDict and + // modifying it for each key. The pdf-create example does this. + QPDF_DLL + void replaceDict(QPDFObjectHandle); + // Replace this stream's stream data with the given data buffer, // and replace the /Filter and /DecodeParms keys in the stream // dictionary with the given values. (If either value is empty, @@ -489,6 +537,12 @@ class QPDFObjectHandle void dereference(); void makeDirectInternal(std::set<int>& visited); void releaseResolved(); + static QPDFObjectHandle parseInternal( + PointerHolder<InputSource> input, + std::string const& object_description, + QPDFTokenizer& tokenizer, bool& empty, + StringDecrypter* decrypter, QPDF* context, + bool in_array, bool in_dictionary); bool initialized; |