mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 15:17:29 +00:00
Protect against coding error of re-entrant parsing
This commit is contained in:
parent
ae5bd7102d
commit
225cd9dac2
@ -657,6 +657,31 @@ class QPDF
|
||||
};
|
||||
friend class Warner;
|
||||
|
||||
// ParseGuard class allows QPDFObjectHandle to detect re-entrant
|
||||
// resolution
|
||||
class ParseGuard
|
||||
{
|
||||
friend class QPDFObjectHandle;
|
||||
private:
|
||||
ParseGuard(QPDF* qpdf) :
|
||||
qpdf(qpdf)
|
||||
{
|
||||
if (qpdf)
|
||||
{
|
||||
qpdf->inParse(true);
|
||||
}
|
||||
}
|
||||
~ParseGuard()
|
||||
{
|
||||
if (qpdf)
|
||||
{
|
||||
qpdf->inParse(false);
|
||||
}
|
||||
}
|
||||
QPDF* qpdf;
|
||||
};
|
||||
friend class ParseGuard;
|
||||
|
||||
// Pipe class is restricted to QPDF_Stream
|
||||
class Pipe
|
||||
{
|
||||
@ -816,6 +841,7 @@ class QPDF
|
||||
friend class ResolveRecorder;
|
||||
|
||||
void parse(char const* password);
|
||||
void inParse(bool);
|
||||
void warn(QPDFExc const& e);
|
||||
void setTrailer(QPDFObjectHandle obj);
|
||||
void read_xref(qpdf_offset_t offset);
|
||||
@ -1352,6 +1378,7 @@ class QPDF
|
||||
bool reconstructed_xref;
|
||||
bool fixed_dangling_refs;
|
||||
bool immediate_copy_from;
|
||||
bool in_parse;
|
||||
|
||||
// Linearization data
|
||||
qpdf_offset_t first_xref_item_offset; // actual value from file
|
||||
|
@ -150,6 +150,7 @@ QPDF::Members::Members() :
|
||||
reconstructed_xref(false),
|
||||
fixed_dangling_refs(false),
|
||||
immediate_copy_from(false),
|
||||
in_parse(false),
|
||||
first_xref_item_offset(0),
|
||||
uncompressed_after_compressed(false)
|
||||
{
|
||||
@ -416,6 +417,20 @@ QPDF::parse(char const* password)
|
||||
findAttachmentStreams();
|
||||
}
|
||||
|
||||
void
|
||||
QPDF::inParse(bool v)
|
||||
{
|
||||
if (this->m->in_parse == v)
|
||||
{
|
||||
// This happens of QPDFObjectHandle::parseInternal tries to
|
||||
// resolve an indirect object while it is parsing.
|
||||
throw std::logic_error(
|
||||
"QPDF: re-entrant parsing detected. This is a qpdf bug."
|
||||
" Please report at https://github.com/qpdf/qpdf/issues.");
|
||||
}
|
||||
this->m->in_parse = v;
|
||||
}
|
||||
|
||||
void
|
||||
QPDF::warn(QPDFExc const& e)
|
||||
{
|
||||
|
@ -1714,7 +1714,11 @@ QPDFObjectHandle::parseInternal(PointerHolder<InputSource> input,
|
||||
// This method must take care not to resolve any objects. Don't
|
||||
// check the type of any object without first ensuring that it is
|
||||
// a direct object. Otherwise, doing so may have the side effect
|
||||
// of reading the object and changing the file pointer.
|
||||
// of reading the object and changing the file pointer. If you do
|
||||
// this, it will cause a logic error to be thrown from
|
||||
// QPDF::inParse().
|
||||
|
||||
QPDF::ParseGuard pg(context);
|
||||
|
||||
empty = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user