aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-07-21 15:00:06 +0200
committerJay Berkenbilt <ejb@ql.org>2012-07-21 15:06:10 +0200
commit6bbea4baa0c06b39b1b71f1aa6fc276789296556 (patch)
tree62198136a609c86029d124323be9e2ea72f88d9a /include
parentf3e267fce28c58039789379ba3488ad12c20a7f6 (diff)
downloadqpdf-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.hh2
-rw-r--r--include/qpdf/QPDF.hh21
-rw-r--r--include/qpdf/QPDFObjectHandle.hh56
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;