Commit a773f4c71d411754317c16140debec55fad88e16

Authored by Jay Berkenbilt
1 parent 7eb903d9

Add QPDFObjectHandle::parse for strings with context

ChangeLog
  1 +2021-02-15 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add a version of QPDFObjectHandle::parse that takes a QPDF* as
  4 + context so that it can parse strings containing indirect object
  5 + references.
  6 +
1 7 2021-02-14 Jay Berkenbilt <ejb@ql.org>
2 8  
3 9 * Add new versions of QPDFObjectHandle::replaceStreamData that
... ...
include/qpdf/QPDFObjectHandle.hh
... ... @@ -379,6 +379,20 @@ class QPDFObjectHandle
379 379 static QPDFObjectHandle parse(std::string const& object_str,
380 380 std::string const& object_description = "");
381 381  
  382 + // Construct an object of any type from a string representation of
  383 + // the object. Indirect object syntax (obj gen R) is allowed and
  384 + // will create indirect references within the passed-in context.
  385 + // If object_description is provided, it will appear in the
  386 + // message of any QPDFExc exception thrown for invalid syntax.
  387 + // Note that you can't parse an indirect object reference all by
  388 + // itself as parse will stop at the end of the first complete
  389 + // object, which will just be the first number and will report
  390 + // that there is trailing data at the end of the string.
  391 + QPDF_DLL
  392 + static QPDFObjectHandle parse(QPDF* context,
  393 + std::string const& object_str,
  394 + std::string const& object_description = "");
  395 +
382 396 // Construct an object as above by reading from the given
383 397 // InputSource at its current position and using the tokenizer you
384 398 // supply. Indirect objects and encrypted strings are permitted.
... ...
libqpdf/QPDFObjectHandle.cc
... ... @@ -1693,12 +1693,20 @@ QPDFObjectHandle
1693 1693 QPDFObjectHandle::parse(std::string const& object_str,
1694 1694 std::string const& object_description)
1695 1695 {
  1696 + return parse(nullptr, object_str, object_description);
  1697 +}
  1698 +
  1699 +QPDFObjectHandle
  1700 +QPDFObjectHandle::parse(QPDF* context,
  1701 + std::string const& object_str,
  1702 + std::string const& object_description)
  1703 +{
1696 1704 PointerHolder<InputSource> input =
1697 1705 new BufferInputSource("parsed object", object_str);
1698 1706 QPDFTokenizer tokenizer;
1699 1707 bool empty = false;
1700 1708 QPDFObjectHandle result =
1701   - parse(input, object_description, tokenizer, empty, 0, 0);
  1709 + parse(input, object_description, tokenizer, empty, 0, context);
1702 1710 size_t offset = QIntC::to_size(input->tell());
1703 1711 while (offset < object_str.length())
1704 1712 {
... ...
manual/qpdf-manual.xml
... ... @@ -5196,6 +5196,14 @@ print &quot;\n&quot;;
5196 5196 </listitem>
5197 5197 <listitem>
5198 5198 <para>
  5199 + Add a version of
  5200 + <function>QPDFObjectHandle::parse</function> that takes a
  5201 + <classname>QPDF</classname> pointer as context so that it
  5202 + can parse strings containing indirect object references.
  5203 + </para>
  5204 + </listitem>
  5205 + <listitem>
  5206 + <para>
5199 5207 Re-implement <classname>QPDFNameTreeObjectHelper</classname>
5200 5208 and <classname>QPDFNumberTreeObjectHelper</classname> to be
5201 5209 more efficient, add an iterator-based API, give them the
... ...
qpdf/test_driver.cc
... ... @@ -1319,6 +1319,9 @@ void runtest(int n, char const* filename1, char const* arg2)
1319 1319 std::cout << "trailing data: " << e.what()
1320 1320 << std::endl;
1321 1321 }
  1322 + assert(QPDFObjectHandle::parse(
  1323 + &pdf, "[1 0 R]", "indirect test").unparse() ==
  1324 + "[ 1 0 R ]");
1322 1325 }
1323 1326 else if (n == 32)
1324 1327 {
... ...