Add method to terminate content stream parsing

This commit is contained in:
Jay Berkenbilt 2013-03-03 15:48:31 -05:00
parent 7be97b3e80
commit 119f2a4b68
7 changed files with 128 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2013-03-03 Jay Berkenbilt <ejb@ql.org>
* Add protected terminateParsing method to
QPDFObjectHandle::ParserCallbacks that implementor can call to
terminate parsing of a content stream.
2013-02-28 Jay Berkenbilt <ejb@ql.org>
* Favor fopen_s and strerror_s on MSVC to avoid CRT security

View File

@ -83,6 +83,13 @@ class QPDFObjectHandle
}
virtual void handleObject(QPDFObjectHandle) = 0;
virtual void handleEOF() = 0;
protected:
// Implementors may call this method during parsing to
// terminate parsing early. This method throws an exception
// that is caught by parseContentStream, so its effect is
// immediate.
void terminateParsing();
};

View File

@ -23,6 +23,16 @@
#include <stdlib.h>
#include <ctype.h>
class TerminateParsing
{
};
void
QPDFObjectHandle::ParserCallbacks::terminateParsing()
{
throw TerminateParsing();
}
QPDFObjectHandle::QPDFObjectHandle() :
initialized(false),
objid(0),
@ -728,7 +738,14 @@ QPDFObjectHandle::parseContentStream(QPDFObjectHandle stream_or_array,
throw std::logic_error(
"QPDFObjectHandle: parseContentStream called on non-stream");
}
parseContentStream_internal(stream, callbacks);
try
{
parseContentStream_internal(stream, callbacks);
}
catch (TerminateParsing&)
{
return;
}
}
callbacks->handleEOF();
}

View File

@ -199,7 +199,7 @@ $td->runtest("remove page we don't have",
show_ntests();
# ----------
$td->notify("--- Miscellaneous Tests ---");
$n_tests += 61;
$n_tests += 62;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@ -478,6 +478,11 @@ $td->runtest("tokenize content streams",
{$td->FILE => "tokenize-content-streams.out",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("terminate parsing",
{$td->COMMAND => "test_driver 37 terminate-parsing.pdf"},
{$td->FILE => "terminate-parsing.out",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("content stream errors",
{$td->COMMAND => "qpdf --check content-stream-errors.pdf"},
{$td->FILE => "content-stream-errors.out",

View File

@ -0,0 +1,86 @@
name: /potato
test suite: terminating parsing
real: 0.1
integer: 0
integer: 0
real: 0.1
integer: 0
integer: 0
operator: cm
operator: q
integer: 0
real: 1.1999
real: -1.1999
integer: 0
real: 121.19
real: 150.009
operator: cm
operator: BI
name: /CS
name: /G
name: /W
integer: 1
name: /H
integer: 1
name: /BPC
integer: 8
name: /F
name: /Fl
name: /DP
dictionary: << /Columns 1 /Predictor 15 >>
operator: ID
inline-image: 789c63fc0f0001030101
operator: EI
operator: Q
operator: q
integer: 0
real: 35.997
real: -128.389
integer: 0
real: 431.964
real: 7269.02
operator: cm
operator: BI
name: /CS
name: /G
name: /W
integer: 30
name: /H
integer: 107
name: /BPC
integer: 8
name: /F
name: /Fl
name: /DP
dictionary: << /Columns 30 /Predictor 15 >>
operator: ID
inline-image: 789cedd1a11100300800b1b2ffd06503148283bc8dfcf8af2a306ee352eff2e06318638c31c63b3801627b620a
operator: EI
operator: Q
operator: q
integer: 0
real: 38.3968
real: -93.5922
integer: 0
real: 431.964
real: 7567.79
operator: cm
operator: BI
name: /CS
name: /G
name: /W
integer: 32
name: /H
integer: 78
name: /BPC
integer: 8
name: /F
name: /Fl
name: /DP
dictionary: << /Columns 32 /Predictor 15 >>
operator: ID
inline-image: 789c63fccf801f308e2a185530aa60882a20203faa605401890a0643aa1e5530aa6054010d140000bdd03c13
operator: EI
operator: Q
-EOF-
test 37 done

Binary file not shown.

View File

@ -72,6 +72,11 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks
void
ParserCallbacks::handleObject(QPDFObjectHandle obj)
{
if (obj.isName() && (obj.getName() == "/Abort"))
{
std::cout << "test suite: terminating parsing" << std::endl;
terminateParsing();
}
std::cout << obj.getTypeName() << ": ";
if (obj.isInlineImage())
{