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 2021-02-14 Jay Berkenbilt <ejb@ql.org> 7 2021-02-14 Jay Berkenbilt <ejb@ql.org>
2 8
3 * Add new versions of QPDFObjectHandle::replaceStreamData that 9 * Add new versions of QPDFObjectHandle::replaceStreamData that
include/qpdf/QPDFObjectHandle.hh
@@ -379,6 +379,20 @@ class QPDFObjectHandle @@ -379,6 +379,20 @@ class QPDFObjectHandle
379 static QPDFObjectHandle parse(std::string const& object_str, 379 static QPDFObjectHandle parse(std::string const& object_str,
380 std::string const& object_description = ""); 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 // Construct an object as above by reading from the given 396 // Construct an object as above by reading from the given
383 // InputSource at its current position and using the tokenizer you 397 // InputSource at its current position and using the tokenizer you
384 // supply. Indirect objects and encrypted strings are permitted. 398 // supply. Indirect objects and encrypted strings are permitted.
libqpdf/QPDFObjectHandle.cc
@@ -1693,12 +1693,20 @@ QPDFObjectHandle @@ -1693,12 +1693,20 @@ QPDFObjectHandle
1693 QPDFObjectHandle::parse(std::string const& object_str, 1693 QPDFObjectHandle::parse(std::string const& object_str,
1694 std::string const& object_description) 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 PointerHolder<InputSource> input = 1704 PointerHolder<InputSource> input =
1697 new BufferInputSource("parsed object", object_str); 1705 new BufferInputSource("parsed object", object_str);
1698 QPDFTokenizer tokenizer; 1706 QPDFTokenizer tokenizer;
1699 bool empty = false; 1707 bool empty = false;
1700 QPDFObjectHandle result = 1708 QPDFObjectHandle result =
1701 - parse(input, object_description, tokenizer, empty, 0, 0); 1709 + parse(input, object_description, tokenizer, empty, 0, context);
1702 size_t offset = QIntC::to_size(input->tell()); 1710 size_t offset = QIntC::to_size(input->tell());
1703 while (offset < object_str.length()) 1711 while (offset < object_str.length())
1704 { 1712 {
manual/qpdf-manual.xml
@@ -5196,6 +5196,14 @@ print &quot;\n&quot;; @@ -5196,6 +5196,14 @@ print &quot;\n&quot;;
5196 </listitem> 5196 </listitem>
5197 <listitem> 5197 <listitem>
5198 <para> 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 Re-implement <classname>QPDFNameTreeObjectHelper</classname> 5207 Re-implement <classname>QPDFNameTreeObjectHelper</classname>
5200 and <classname>QPDFNumberTreeObjectHelper</classname> to be 5208 and <classname>QPDFNumberTreeObjectHelper</classname> to be
5201 more efficient, add an iterator-based API, give them the 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,6 +1319,9 @@ void runtest(int n, char const* filename1, char const* arg2)
1319 std::cout << "trailing data: " << e.what() 1319 std::cout << "trailing data: " << e.what()
1320 << std::endl; 1320 << std::endl;
1321 } 1321 }
  1322 + assert(QPDFObjectHandle::parse(
  1323 + &pdf, "[1 0 R]", "indirect test").unparse() ==
  1324 + "[ 1 0 R ]");
1322 } 1325 }
1323 else if (n == 32) 1326 else if (n == 32)
1324 { 1327 {