diff --git a/ChangeLog b/ChangeLog index 7b1db1f2..2009162c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2021-02-15 Jay Berkenbilt + + * 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 * 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 @@ -1692,13 +1692,21 @@ QPDFObjectHandle::wrapInArray() 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 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 @@ -5194,6 +5194,14 @@ print "\n"; QPDFObjectHandle object. + + + Add a version of + QPDFObjectHandle::parse that takes a + QPDF pointer as context so that it + can parse strings containing indirect object references. + + Re-implement QPDFNameTreeObjectHelper 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) {