aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-02-15 17:32:56 +0100
committerJay Berkenbilt <ejb@ql.org>2021-02-15 17:33:03 +0100
commita773f4c71d411754317c16140debec55fad88e16 (patch)
treede3641b4e5ef5738bbedc4e58d87d0f10cbe28f0
parent7eb903d9aa797a207f5b1b115dce2296d348000b (diff)
downloadqpdf-a773f4c71d411754317c16140debec55fad88e16.tar.zst
Add QPDFObjectHandle::parse for strings with context
-rw-r--r--ChangeLog6
-rw-r--r--include/qpdf/QPDFObjectHandle.hh14
-rw-r--r--libqpdf/QPDFObjectHandle.cc10
-rw-r--r--manual/qpdf-manual.xml8
-rw-r--r--qpdf/test_driver.cc3
5 files changed, 40 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b1db1f2..2009162c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2021-02-15 Jay Berkenbilt <ejb@ql.org>
+
+ * Add a version of QPDFObjectHandle::parse that takes a QPDF* as
+ context so that it can parse strings containing indirect object
+ references.
+
2021-02-14 Jay Berkenbilt <ejb@ql.org>
* Add new versions of QPDFObjectHandle::replaceStreamData that
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index cb4c5be6..efcd653a 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -379,6 +379,20 @@ class QPDFObjectHandle
static QPDFObjectHandle parse(std::string const& object_str,
std::string const& object_description = "");
+ // Construct an object of any type from a string representation of
+ // the object. Indirect object syntax (obj gen R) is allowed and
+ // will create indirect references within the passed-in context.
+ // If object_description is provided, it will appear in the
+ // message of any QPDFExc exception thrown for invalid syntax.
+ // Note that you can't parse an indirect object reference all by
+ // itself as parse will stop at the end of the first complete
+ // object, which will just be the first number and will report
+ // that there is trailing data at the end of the string.
+ QPDF_DLL
+ static QPDFObjectHandle parse(QPDF* context,
+ 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.
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index d4796498..8f7399f2 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -1693,12 +1693,20 @@ QPDFObjectHandle
QPDFObjectHandle::parse(std::string const& object_str,
std::string const& object_description)
{
+ return parse(nullptr, object_str, object_description);
+}
+
+QPDFObjectHandle
+QPDFObjectHandle::parse(QPDF* context,
+ std::string const& object_str,
+ std::string const& object_description)
+{
PointerHolder<InputSource> input =
new BufferInputSource("parsed object", object_str);
QPDFTokenizer tokenizer;
bool empty = false;
QPDFObjectHandle result =
- parse(input, object_description, tokenizer, empty, 0, 0);
+ parse(input, object_description, tokenizer, empty, 0, context);
size_t offset = QIntC::to_size(input->tell());
while (offset < object_str.length())
{
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index ae085d6e..508e0ec9 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -5196,6 +5196,14 @@ print "\n";
</listitem>
<listitem>
<para>
+ Add a version of
+ <function>QPDFObjectHandle::parse</function> that takes a
+ <classname>QPDF</classname> pointer as context so that it
+ can parse strings containing indirect object references.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
Re-implement <classname>QPDFNameTreeObjectHelper</classname>
and <classname>QPDFNumberTreeObjectHelper</classname> to be
more efficient, add an iterator-based API, give them the
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index d7c9a352..2ad5bd62 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -1319,6 +1319,9 @@ void runtest(int n, char const* filename1, char const* arg2)
std::cout << "trailing data: " << e.what()
<< std::endl;
}
+ assert(QPDFObjectHandle::parse(
+ &pdf, "[1 0 R]", "indirect test").unparse() ==
+ "[ 1 0 R ]");
}
else if (n == 32)
{