diff --git a/ChangeLog b/ChangeLog index 0f237206..036c2bca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2021-03-01 Jay Berkenbilt + * QPDFObjectHandle::ParserCallbacks: add virtual handleWarning + method, and provide default (empty) implementation of it and + handleEOF(). + * Add QPDF::numWarnings() -- useful to tell whether any warnings were issued by a specific bit of code. diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 356eb4e2..e0635842 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -224,7 +224,16 @@ class QPDFObjectHandle virtual void handleObject( QPDFObjectHandle, size_t offset, size_t length); - virtual void handleEOF() = 0; + // handleWarning is called if a warning was issued during the + // parsing of the most recent object. There's no good way to + // get information about the warning, but implementors can use + // this to become aware that there was some problem while + // parsing this content stream. + QPDF_DLL + virtual void handleWarning(); + + QPDF_DLL + virtual void handleEOF(); // Override this if you want to know the full size of the // contents, possibly after concatenation of multiple streams. diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 6d4f10ce..35a4962a 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -151,6 +151,16 @@ QPDFObjectHandle::ParserCallbacks::handleObject( handleObject(oh); } +void +QPDFObjectHandle::ParserCallbacks::handleWarning() +{ +} + +void +QPDFObjectHandle::ParserCallbacks::handleEOF() +{ +} + void QPDFObjectHandle::ParserCallbacks::contentSize(size_t) { @@ -1847,10 +1857,15 @@ QPDFObjectHandle::parseContentStream_internal( pipeContentStreams(&buf, description, all_description); PointerHolder stream_data = buf.getBuffer(); callbacks->contentSize(stream_data->getSize()); + QPDF* context = getOwningQPDF(); + if ((! context) && isArray() && (getArrayNItems() > 0)) + { + context = getArrayItem(0).getOwningQPDF(); + } try { parseContentStream_data(stream_data, all_description, - callbacks, getOwningQPDF()); + callbacks, context); } catch (TerminateParsing&) { @@ -1881,9 +1896,15 @@ QPDFObjectHandle::parseContentStream_data( tokenizer.readToken(input, "content", true); qpdf_offset_t offset = input->getLastOffset(); input->seek(offset, SEEK_SET); + size_t before_nwarnings = (context ? context->numWarnings() : 0); QPDFObjectHandle obj = parseInternal(input, "content", tokenizer, empty, 0, context, true); + size_t after_nwarnings = (context ? context->numWarnings() : 0); + if (after_nwarnings > before_nwarnings) + { + callbacks->handleWarning(); + } if (! obj.isInitialized()) { // EOF @@ -1910,6 +1931,7 @@ QPDFObjectHandle::parseContentStream_data( QPDFExc(qpdf_e_damaged_pdf, input->getName(), "stream data", input->tell(), "EOF found while reading inline image")); + callbacks->handleWarning(); } else {