aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/qpdf/QPDF.hh3
-rw-r--r--include/qpdf/QPDFTokenizer.hh3
-rw-r--r--libqpdf/QPDF.cc17
-rw-r--r--libqpdf/QPDFTokenizer.cc11
-rw-r--r--qpdf/qpdf.testcov1
5 files changed, 26 insertions, 9 deletions
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index 72e02754..e3cd24b6 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -671,7 +671,8 @@ class QPDF
PointerHolder<InputSource> input, int objid, int generation,
qpdf_offset_t stream_offset);
QPDFTokenizer::Token readToken(PointerHolder<InputSource>,
- bool allow_bad = false);
+ bool allow_bad = false,
+ size_t max_len = 0);
QPDFObjectHandle readObjectAtOffset(
bool attempt_recovery,
diff --git a/include/qpdf/QPDFTokenizer.hh b/include/qpdf/QPDFTokenizer.hh
index e24b7c43..23f7910d 100644
--- a/include/qpdf/QPDFTokenizer.hh
+++ b/include/qpdf/QPDFTokenizer.hh
@@ -139,7 +139,8 @@ class QPDFTokenizer
QPDF_DLL
Token readToken(PointerHolder<InputSource> input,
std::string const& context,
- bool allow_bad = false);
+ bool allow_bad = false,
+ size_t max_len = 0);
private:
void reset();
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index caf5ef7b..3cfb9a34 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -407,12 +407,14 @@ QPDF::reconstruct_xref(QPDFExc& e)
this->m->file->seek(0, SEEK_SET);
bool in_obj = false;
qpdf_offset_t line_start = 0;
+ // Don't allow very long tokens here during recovery.
+ static size_t const MAX_LEN = 100;
while (this->m->file->tell() < eof)
{
this->m->file->findAndSkipNextEOL();
qpdf_offset_t next_line_start = this->m->file->tell();
this->m->file->seek(line_start, SEEK_SET);
- QPDFTokenizer::Token t1 = readToken(this->m->file, true);
+ QPDFTokenizer::Token t1 = readToken(this->m->file, true, MAX_LEN);
qpdf_offset_t token_start =
this->m->file->tell() - t1.getValue().length();
if (token_start >= next_line_start)
@@ -430,8 +432,10 @@ QPDF::reconstruct_xref(QPDFExc& e)
{
if (t1.getType() == QPDFTokenizer::tt_integer)
{
- QPDFTokenizer::Token t2 = readToken(this->m->file, true);
- QPDFTokenizer::Token t3 = readToken(this->m->file, true);
+ QPDFTokenizer::Token t2 =
+ readToken(this->m->file, true, MAX_LEN);
+ QPDFTokenizer::Token t3 =
+ readToken(this->m->file, true, MAX_LEN);
if ((t2.getType() == QPDFTokenizer::tt_integer) &&
(t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")))
{
@@ -1411,7 +1415,7 @@ bool
QPDF::findEndstream()
{
// Find endstream or endobj. Position the input at that token.
- QPDFTokenizer::Token t = readToken(this->m->file, true);
+ QPDFTokenizer::Token t = readToken(this->m->file, true, 20);
if ((t.getType() == QPDFTokenizer::tt_word) &&
((t.getValue() == "endobj") ||
(t.getValue() == "endstream")))
@@ -1504,10 +1508,11 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
}
QPDFTokenizer::Token
-QPDF::readToken(PointerHolder<InputSource> input, bool allow_bad)
+QPDF::readToken(PointerHolder<InputSource> input,
+ bool allow_bad, size_t max_len)
{
return this->m->tokenizer.readToken(
- input, this->m->last_object_description, allow_bad);
+ input, this->m->last_object_description, allow_bad, max_len);
}
QPDFObjectHandle
diff --git a/libqpdf/QPDFTokenizer.cc b/libqpdf/QPDFTokenizer.cc
index 6447b93b..6cababfe 100644
--- a/libqpdf/QPDFTokenizer.cc
+++ b/libqpdf/QPDFTokenizer.cc
@@ -476,7 +476,8 @@ QPDFTokenizer::betweenTokens()
QPDFTokenizer::Token
QPDFTokenizer::readToken(PointerHolder<InputSource> input,
std::string const& context,
- bool allow_bad)
+ bool allow_bad,
+ size_t max_len)
{
qpdf_offset_t offset = input->tell();
Token token;
@@ -507,6 +508,14 @@ QPDFTokenizer::readToken(PointerHolder<InputSource> input,
++offset;
}
presentCharacter(ch);
+ if (max_len && (raw_val.length() >= max_len) &&
+ (this->state != st_token_ready))
+ {
+ // terminate this token now
+ QTC::TC("qpdf", "QPDFTokenizer block long token");
+ this->type = tt_bad;
+ this->state = st_token_ready;
+ }
}
}
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index c1355d59..4bc1ad0a 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -296,3 +296,4 @@ QPDF_encryption pad short parameter 0
QPDFWriter ignore self-referential object stream 0
QPDFObjectHandle found old angle 1
QPDF_Stream special filters 3
+QPDFTokenizer block long token 0