Commit a773f4c71d411754317c16140debec55fad88e16
1 parent
7eb903d9
Add QPDFObjectHandle::parse for strings with context
Showing
5 changed files
with
40 additions
and
1 deletions
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 "\n"; | @@ -5196,6 +5196,14 @@ print "\n"; | ||
| 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 | { |