mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Merge pull request #1171 from m-holger/unresolved
Refactor the creation of unresolved objects
This commit is contained in:
commit
6aa6c01303
@ -133,6 +133,8 @@ set(CORPUS_OTHER
|
|||||||
70055.fuzz
|
70055.fuzz
|
||||||
70245.fuzz
|
70245.fuzz
|
||||||
70306.fuzz
|
70306.fuzz
|
||||||
|
70306a.fuzz
|
||||||
|
70306b.fuzz
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
|
set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus)
|
||||||
|
BIN
fuzz/qpdf_extra/70306a.fuzz
Normal file
BIN
fuzz/qpdf_extra/70306a.fuzz
Normal file
Binary file not shown.
BIN
fuzz/qpdf_extra/70306b.fuzz
Normal file
BIN
fuzz/qpdf_extra/70306b.fuzz
Normal file
Binary file not shown.
@ -21,7 +21,7 @@ my @fuzzers = (
|
|||||||
['pngpredictor' => 1],
|
['pngpredictor' => 1],
|
||||||
['runlength' => 6],
|
['runlength' => 6],
|
||||||
['tiffpredictor' => 2],
|
['tiffpredictor' => 2],
|
||||||
['qpdf' => 75], # increment when adding new files
|
['qpdf' => 77], # increment when adding new files
|
||||||
);
|
);
|
||||||
|
|
||||||
my $n_tests = 0;
|
my $n_tests = 0;
|
||||||
|
@ -819,7 +819,8 @@ class QPDF
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The ParseGuard class allows QPDFParser to detect re-entrant parsing.
|
// The ParseGuard class allows QPDFParser to detect re-entrant parsing. It also provides
|
||||||
|
// special access to allow the parser to create unresolved objects and dangling references.
|
||||||
class ParseGuard
|
class ParseGuard
|
||||||
{
|
{
|
||||||
friend class QPDFParser;
|
friend class QPDFParser;
|
||||||
@ -832,6 +833,13 @@ class QPDF
|
|||||||
qpdf->inParse(true);
|
qpdf->inParse(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<QPDFObject>
|
||||||
|
getObject(QPDF* qpdf, int id, int gen, bool parse_pdf)
|
||||||
|
{
|
||||||
|
return qpdf->getObjectForParser(id, gen, parse_pdf);
|
||||||
|
}
|
||||||
|
|
||||||
~ParseGuard()
|
~ParseGuard()
|
||||||
{
|
{
|
||||||
if (qpdf) {
|
if (qpdf) {
|
||||||
@ -900,8 +908,8 @@ class QPDF
|
|||||||
}
|
}
|
||||||
ObjCache(
|
ObjCache(
|
||||||
std::shared_ptr<QPDFObject> object,
|
std::shared_ptr<QPDFObject> object,
|
||||||
qpdf_offset_t end_before_space,
|
qpdf_offset_t end_before_space = 0,
|
||||||
qpdf_offset_t end_after_space) :
|
qpdf_offset_t end_after_space = 0) :
|
||||||
object(object),
|
object(object),
|
||||||
end_before_space(end_before_space),
|
end_before_space(end_before_space),
|
||||||
end_after_space(end_after_space)
|
end_after_space(end_after_space)
|
||||||
@ -1065,13 +1073,14 @@ class QPDF
|
|||||||
QPDFObject* resolve(QPDFObjGen og);
|
QPDFObject* resolve(QPDFObjGen og);
|
||||||
void resolveObjectsInStream(int obj_stream_number);
|
void resolveObjectsInStream(int obj_stream_number);
|
||||||
void stopOnError(std::string const& message);
|
void stopOnError(std::string const& message);
|
||||||
QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og);
|
|
||||||
QPDFObjectHandle reserveStream(QPDFObjGen const& og);
|
QPDFObjectHandle reserveStream(QPDFObjGen const& og);
|
||||||
QPDFObjGen nextObjGen();
|
QPDFObjGen nextObjGen();
|
||||||
QPDFObjectHandle newIndirect(QPDFObjGen const&, std::shared_ptr<QPDFObject> const&);
|
QPDFObjectHandle newIndirect(QPDFObjGen const&, std::shared_ptr<QPDFObject> const&);
|
||||||
QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj);
|
QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj);
|
||||||
bool isCached(QPDFObjGen const& og);
|
bool isCached(QPDFObjGen const& og);
|
||||||
bool isUnresolved(QPDFObjGen const& og);
|
bool isUnresolved(QPDFObjGen const& og);
|
||||||
|
std::shared_ptr<QPDFObject> getObjectForParser(int id, int gen, bool parse_pdf);
|
||||||
|
std::shared_ptr<QPDFObject> getObjectForJSON(int id, int gen);
|
||||||
void removeObject(QPDFObjGen og);
|
void removeObject(QPDFObjGen og);
|
||||||
void updateCache(
|
void updateCache(
|
||||||
QPDFObjGen const& og,
|
QPDFObjGen const& og,
|
||||||
|
@ -654,9 +654,11 @@ QPDF::reconstruct_xref(QPDFExc& e)
|
|||||||
}
|
}
|
||||||
check_warnings();
|
check_warnings();
|
||||||
if (!m->parsed) {
|
if (!m->parsed) {
|
||||||
|
m->parsed = true;
|
||||||
getAllPages();
|
getAllPages();
|
||||||
check_warnings();
|
check_warnings();
|
||||||
if (m->all_pages.empty()) {
|
if (m->all_pages.empty()) {
|
||||||
|
m->parsed = false;
|
||||||
throw damagedPDF("", 0, "unable to find any pages while recovering damaged file");
|
throw damagedPDF("", 0, "unable to find any pages while recovering damaged file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1462,7 +1464,8 @@ QPDF::readTrailer()
|
|||||||
{
|
{
|
||||||
qpdf_offset_t offset = m->file->tell();
|
qpdf_offset_t offset = m->file->tell();
|
||||||
bool empty = false;
|
bool empty = false;
|
||||||
auto object = QPDFParser(m->file, "trailer", m->tokenizer, nullptr, this).parse(empty, false);
|
auto object =
|
||||||
|
QPDFParser(m->file, "trailer", m->tokenizer, nullptr, this, true).parse(empty, false);
|
||||||
if (empty) {
|
if (empty) {
|
||||||
// Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
|
// Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
|
||||||
// actual PDF files and Adobe Reader appears to ignore them.
|
// actual PDF files and Adobe Reader appears to ignore them.
|
||||||
@ -1484,8 +1487,9 @@ QPDF::readObject(std::string const& description, QPDFObjGen og)
|
|||||||
|
|
||||||
StringDecrypter decrypter{this, og};
|
StringDecrypter decrypter{this, og};
|
||||||
StringDecrypter* decrypter_ptr = m->encp->encrypted ? &decrypter : nullptr;
|
StringDecrypter* decrypter_ptr = m->encp->encrypted ? &decrypter : nullptr;
|
||||||
auto object = QPDFParser(m->file, m->last_object_description, m->tokenizer, decrypter_ptr, this)
|
auto object =
|
||||||
.parse(empty, false);
|
QPDFParser(m->file, m->last_object_description, m->tokenizer, decrypter_ptr, this, true)
|
||||||
|
.parse(empty, false);
|
||||||
if (empty) {
|
if (empty) {
|
||||||
// Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
|
// Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
|
||||||
// actual PDF files and Adobe Reader appears to ignore them.
|
// actual PDF files and Adobe Reader appears to ignore them.
|
||||||
@ -1604,7 +1608,7 @@ QPDF::readObjectInStream(std::shared_ptr<InputSource>& input, int obj)
|
|||||||
m->last_object_description += " 0";
|
m->last_object_description += " 0";
|
||||||
|
|
||||||
bool empty = false;
|
bool empty = false;
|
||||||
auto object = QPDFParser(input, m->last_object_description, m->tokenizer, nullptr, this)
|
auto object = QPDFParser(input, m->last_object_description, m->tokenizer, nullptr, this, true)
|
||||||
.parse(empty, false);
|
.parse(empty, false);
|
||||||
if (empty) {
|
if (empty) {
|
||||||
// Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
|
// Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
|
||||||
@ -2093,31 +2097,53 @@ QPDF::newStream(std::string const& data)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
|
||||||
QPDF::reserveObjectIfNotExists(QPDFObjGen const& og)
|
|
||||||
{
|
|
||||||
if (!isCached(og) && m->xref_table.count(og) == 0) {
|
|
||||||
updateCache(og, QPDF_Reserved::create(), -1, -1);
|
|
||||||
return newIndirect(og, m->obj_cache[og].object);
|
|
||||||
} else {
|
|
||||||
return getObject(og);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDF::reserveStream(QPDFObjGen const& og)
|
QPDF::reserveStream(QPDFObjGen const& og)
|
||||||
{
|
{
|
||||||
return {QPDF_Stream::create(this, og, QPDFObjectHandle::newDictionary(), 0, 0)};
|
return {QPDF_Stream::create(this, og, QPDFObjectHandle::newDictionary(), 0, 0)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QPDFObject>
|
||||||
|
QPDF::getObjectForParser(int id, int gen, bool parse_pdf)
|
||||||
|
{
|
||||||
|
// This method is called by the parser and therefore must not resolve any objects.
|
||||||
|
auto og = QPDFObjGen(id, gen);
|
||||||
|
if (auto iter = m->obj_cache.find(og); iter != m->obj_cache.end()) {
|
||||||
|
return iter->second.object;
|
||||||
|
}
|
||||||
|
if (m->xref_table.count(og) || !m->parsed) {
|
||||||
|
return m->obj_cache.insert({og, QPDF_Unresolved::create(this, og)}).first->second.object;
|
||||||
|
}
|
||||||
|
if (parse_pdf) {
|
||||||
|
return QPDF_Null::create();
|
||||||
|
}
|
||||||
|
return m->obj_cache.insert({og, QPDF_Null::create(this, og)}).first->second.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QPDFObject>
|
||||||
|
QPDF::getObjectForJSON(int id, int gen)
|
||||||
|
{
|
||||||
|
auto og = QPDFObjGen(id, gen);
|
||||||
|
auto [it, inserted] = m->obj_cache.try_emplace(og);
|
||||||
|
auto& obj = it->second.object;
|
||||||
|
if (inserted) {
|
||||||
|
obj = (m->parsed && !m->xref_table.count(og)) ? QPDF_Null::create(this, og)
|
||||||
|
: QPDF_Unresolved::create(this, og);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDF::getObject(QPDFObjGen const& og)
|
QPDF::getObject(QPDFObjGen const& og)
|
||||||
{
|
{
|
||||||
// This method is called by the parser and therefore must not resolve any objects.
|
if (auto it = m->obj_cache.find(og); it != m->obj_cache.end()) {
|
||||||
if (!isCached(og)) {
|
return {it->second.object};
|
||||||
m->obj_cache[og] = ObjCache(QPDF_Unresolved::create(this, og), -1, -1);
|
} else if (m->parsed && !m->xref_table.count(og)) {
|
||||||
|
return QPDF_Null::create();
|
||||||
|
} else {
|
||||||
|
auto result = m->obj_cache.try_emplace(og, QPDF_Unresolved::create(this, og), -1, -1);
|
||||||
|
return {result.first->second.object};
|
||||||
}
|
}
|
||||||
return newIndirect(og, m->obj_cache[og].object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
|
@ -2146,7 +2146,8 @@ QPDFObjectHandle::parseContentStream_data(
|
|||||||
tokenizer.readToken(input, "content", true);
|
tokenizer.readToken(input, "content", true);
|
||||||
qpdf_offset_t offset = input->getLastOffset();
|
qpdf_offset_t offset = input->getLastOffset();
|
||||||
input->seek(offset, SEEK_SET);
|
input->seek(offset, SEEK_SET);
|
||||||
auto obj = QPDFParser(input, "content", tokenizer, nullptr, context).parse(empty, true);
|
auto obj =
|
||||||
|
QPDFParser(input, "content", tokenizer, nullptr, context, false).parse(empty, true);
|
||||||
if (!obj.isInitialized()) {
|
if (!obj.isInitialized()) {
|
||||||
// EOF
|
// EOF
|
||||||
break;
|
break;
|
||||||
@ -2205,7 +2206,8 @@ QPDFObjectHandle::parse(
|
|||||||
StringDecrypter* decrypter,
|
StringDecrypter* decrypter,
|
||||||
QPDF* context)
|
QPDF* context)
|
||||||
{
|
{
|
||||||
return QPDFParser(input, object_description, tokenizer, decrypter, context).parse(empty, false);
|
return QPDFParser(input, object_description, tokenizer, decrypter, context, false)
|
||||||
|
.parse(empty, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QPDF_FUTURE
|
#ifndef QPDF_FUTURE
|
||||||
|
@ -71,7 +71,7 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name)
|
|||||||
m->dest_dict = qpdf.getRoot().getKey("/Dests");
|
m->dest_dict = qpdf.getRoot().getKey("/Dests");
|
||||||
}
|
}
|
||||||
QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest");
|
QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest");
|
||||||
result= m->dest_dict.getKeyIfDict(name.getName());
|
result = m->dest_dict.getKeyIfDict(name.getName());
|
||||||
} else if (name.isString()) {
|
} else if (name.isString()) {
|
||||||
if (!m->names_dest) {
|
if (!m->names_dest) {
|
||||||
auto dests = qpdf.getRoot().getKey("/Names").getKeyIfDict("/Dests");
|
auto dests = qpdf.getRoot().getKey("/Names").getKeyIfDict("/Dests");
|
||||||
|
@ -166,10 +166,7 @@ QPDFParser::parseRemainder(bool content_stream)
|
|||||||
auto id = QIntC::to_int(int_buffer[(int_count - 1) % 2]);
|
auto id = QIntC::to_int(int_buffer[(int_count - 1) % 2]);
|
||||||
auto gen = QIntC::to_int(int_buffer[(int_count) % 2]);
|
auto gen = QIntC::to_int(int_buffer[(int_count) % 2]);
|
||||||
if (!(id < 1 || gen < 0 || gen >= 65535)) {
|
if (!(id < 1 || gen < 0 || gen >= 65535)) {
|
||||||
// This action has the desirable side effect of causing dangling references
|
add(QPDF::ParseGuard::getObject(context, id, gen, parse_pdf));
|
||||||
// (references to indirect objects that don't appear in the PDF) in any parsed
|
|
||||||
// object to appear in the object cache.
|
|
||||||
add(std::move(context->getObject(id, gen).obj));
|
|
||||||
} else {
|
} else {
|
||||||
QTC::TC("qpdf", "QPDFParser invalid objgen");
|
QTC::TC("qpdf", "QPDFParser invalid objgen");
|
||||||
addNull();
|
addNull();
|
||||||
|
@ -1237,7 +1237,7 @@ bool
|
|||||||
QPDFWriter::willFilterStream(
|
QPDFWriter::willFilterStream(
|
||||||
QPDFObjectHandle stream,
|
QPDFObjectHandle stream,
|
||||||
bool& compress_stream, // out only
|
bool& compress_stream, // out only
|
||||||
bool& is_metadata, // out only
|
bool& is_metadata, // out only
|
||||||
std::shared_ptr<Buffer>* stream_data)
|
std::shared_ptr<Buffer>* stream_data)
|
||||||
{
|
{
|
||||||
compress_stream = false;
|
compress_stream = false;
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
#include <qpdf/JSON_writer.hh>
|
#include <qpdf/JSON_writer.hh>
|
||||||
#include <qpdf/QPDFObject_private.hh>
|
#include <qpdf/QPDFObject_private.hh>
|
||||||
|
|
||||||
QPDF_Null::QPDF_Null() :
|
QPDF_Null::QPDF_Null(QPDF* qpdf, QPDFObjGen og) :
|
||||||
QPDFValue(::ot_null, "null")
|
QPDFValue(::ot_null, "null", qpdf, og)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QPDFObject>
|
std::shared_ptr<QPDFObject>
|
||||||
QPDF_Null::create()
|
QPDF_Null::create(QPDF* qpdf, QPDFObjGen og)
|
||||||
{
|
{
|
||||||
return do_create(new QPDF_Null());
|
return do_create(new QPDF_Null(qpdf, og));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QPDFObject>
|
std::shared_ptr<QPDFObject>
|
||||||
|
@ -240,11 +240,6 @@ class QPDF::JSONReactor: public JSON::Reactor
|
|||||||
descr(std::make_shared<QPDFValue::Description>(
|
descr(std::make_shared<QPDFValue::Description>(
|
||||||
QPDFValue::JSON_Descr(std::make_shared<std::string>(is->getName()), "")))
|
QPDFValue::JSON_Descr(std::make_shared<std::string>(is->getName()), "")))
|
||||||
{
|
{
|
||||||
for (auto& oc: pdf.m->obj_cache) {
|
|
||||||
if (oc.second.object->getTypeCode() == ::ot_reserved) {
|
|
||||||
reserved.insert(oc.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
~JSONReactor() override = default;
|
~JSONReactor() override = default;
|
||||||
void dictionaryStart() override;
|
void dictionaryStart() override;
|
||||||
@ -272,10 +267,10 @@ class QPDF::JSONReactor: public JSON::Reactor
|
|||||||
struct StackFrame
|
struct StackFrame
|
||||||
{
|
{
|
||||||
StackFrame(state_e state) :
|
StackFrame(state_e state) :
|
||||||
state(state){};
|
state(state) {};
|
||||||
StackFrame(state_e state, QPDFObjectHandle&& object) :
|
StackFrame(state_e state, QPDFObjectHandle&& object) :
|
||||||
state(state),
|
state(state),
|
||||||
object(object){};
|
object(object) {};
|
||||||
state_e state;
|
state_e state;
|
||||||
QPDFObjectHandle object;
|
QPDFObjectHandle object;
|
||||||
};
|
};
|
||||||
@ -305,7 +300,6 @@ class QPDF::JSONReactor: public JSON::Reactor
|
|||||||
bool saw_data{false};
|
bool saw_data{false};
|
||||||
bool saw_datafile{false};
|
bool saw_datafile{false};
|
||||||
bool this_stream_needs_data{false};
|
bool this_stream_needs_data{false};
|
||||||
std::set<QPDFObjGen> reserved;
|
|
||||||
std::vector<StackFrame> stack;
|
std::vector<StackFrame> stack;
|
||||||
QPDFObjectHandle next_obj;
|
QPDFObjectHandle next_obj;
|
||||||
state_e next_state{st_top};
|
state_e next_state{st_top};
|
||||||
@ -416,16 +410,6 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (from_state == st_qpdf) {
|
|
||||||
// Handle dangling indirect object references which the PDF spec says to treat as nulls.
|
|
||||||
// It's tempting to make this an error, but that would be wrong since valid input files may
|
|
||||||
// have these.
|
|
||||||
for (auto& oc: pdf.m->obj_cache) {
|
|
||||||
if (oc.second.object->getTypeCode() == ::ot_reserved && reserved.count(oc.first) == 0) {
|
|
||||||
QTC::TC("qpdf", "QPDF_json non-trivial null reserved");
|
|
||||||
pdf.updateCache(oc.first, QPDF_Null::create(), -1, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!stack.empty()) {
|
if (!stack.empty()) {
|
||||||
auto state = stack.back().state;
|
auto state = stack.back().state;
|
||||||
@ -565,7 +549,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
|
|||||||
} else if (is_obj_key(key, obj, gen)) {
|
} else if (is_obj_key(key, obj, gen)) {
|
||||||
this->cur_object = key;
|
this->cur_object = key;
|
||||||
if (setNextStateIfDictionary(key, value, st_object_top)) {
|
if (setNextStateIfDictionary(key, value, st_object_top)) {
|
||||||
next_obj = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen));
|
next_obj = pdf.getObjectForJSON(obj, gen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QTC::TC("qpdf", "QPDF_json bad object key");
|
QTC::TC("qpdf", "QPDF_json bad object key");
|
||||||
@ -767,7 +751,7 @@ QPDF::JSONReactor::makeObject(JSON const& value)
|
|||||||
int gen = 0;
|
int gen = 0;
|
||||||
std::string str;
|
std::string str;
|
||||||
if (is_indirect_object(str_v, obj, gen)) {
|
if (is_indirect_object(str_v, obj, gen)) {
|
||||||
result = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen));
|
result = pdf.getObjectForJSON(obj, gen);
|
||||||
} else if (is_unicode_string(str_v, str)) {
|
} else if (is_unicode_string(str_v, str)) {
|
||||||
result = QPDFObjectHandle::newUnicodeString(str);
|
result = QPDFObjectHandle::newUnicodeString(str);
|
||||||
} else if (is_binary_string(str_v, str)) {
|
} else if (is_binary_string(str_v, str)) {
|
||||||
|
@ -16,14 +16,16 @@ class QPDFParser
|
|||||||
std::string const& object_description,
|
std::string const& object_description,
|
||||||
QPDFTokenizer& tokenizer,
|
QPDFTokenizer& tokenizer,
|
||||||
QPDFObjectHandle::StringDecrypter* decrypter,
|
QPDFObjectHandle::StringDecrypter* decrypter,
|
||||||
QPDF* context) :
|
QPDF* context,
|
||||||
|
bool parse_pdf) :
|
||||||
input(input),
|
input(input),
|
||||||
object_description(object_description),
|
object_description(object_description),
|
||||||
tokenizer(tokenizer),
|
tokenizer(tokenizer),
|
||||||
decrypter(decrypter),
|
decrypter(decrypter),
|
||||||
context(context),
|
context(context),
|
||||||
description(std::make_shared<QPDFValue::Description>(
|
description(std::make_shared<QPDFValue::Description>(
|
||||||
std::string(input->getName() + ", " + object_description + " at offset $PO")))
|
std::string(input->getName() + ", " + object_description + " at offset $PO"))),
|
||||||
|
parse_pdf(parse_pdf)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~QPDFParser() = default;
|
virtual ~QPDFParser() = default;
|
||||||
@ -76,6 +78,8 @@ class QPDFParser
|
|||||||
QPDFObjectHandle::StringDecrypter* decrypter;
|
QPDFObjectHandle::StringDecrypter* decrypter;
|
||||||
QPDF* context;
|
QPDF* context;
|
||||||
std::shared_ptr<QPDFValue::Description> description;
|
std::shared_ptr<QPDFValue::Description> description;
|
||||||
|
bool parse_pdf;
|
||||||
|
|
||||||
std::vector<StackFrame> stack;
|
std::vector<StackFrame> stack;
|
||||||
StackFrame* frame;
|
StackFrame* frame;
|
||||||
// Number of recent bad tokens.
|
// Number of recent bad tokens.
|
||||||
|
@ -7,7 +7,7 @@ class QPDF_Null: public QPDFValue
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~QPDF_Null() override = default;
|
~QPDF_Null() override = default;
|
||||||
static std::shared_ptr<QPDFObject> create();
|
static std::shared_ptr<QPDFObject> create(QPDF* qpdf = nullptr, QPDFObjGen og = QPDFObjGen());
|
||||||
static std::shared_ptr<QPDFObject> create(
|
static std::shared_ptr<QPDFObject> create(
|
||||||
std::shared_ptr<QPDFObject> parent,
|
std::shared_ptr<QPDFObject> parent,
|
||||||
std::string_view const& static_descr,
|
std::string_view const& static_descr,
|
||||||
@ -21,7 +21,7 @@ class QPDF_Null: public QPDFValue
|
|||||||
void writeJSON(int json_version, JSON::Writer& p) override;
|
void writeJSON(int json_version, JSON::Writer& p) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPDF_Null();
|
QPDF_Null(QPDF* qpdf = nullptr, QPDFObjGen og = QPDFObjGen());
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QPDF_NULL_HH
|
#endif // QPDF_NULL_HH
|
||||||
|
@ -16,7 +16,7 @@ struct _qpdf_data
|
|||||||
_qpdf_data() = default;
|
_qpdf_data() = default;
|
||||||
|
|
||||||
_qpdf_data(std::unique_ptr<QPDF>&& qpdf) :
|
_qpdf_data(std::unique_ptr<QPDF>&& qpdf) :
|
||||||
qpdf(std::move(qpdf)){};
|
qpdf(std::move(qpdf)) {};
|
||||||
|
|
||||||
~_qpdf_data() = default;
|
~_qpdf_data() = default;
|
||||||
|
|
||||||
|
@ -90,17 +90,17 @@ main()
|
|||||||
|
|
||||||
obj = QPDF_Array::create({10, "null"_qpdf.getObj()}, true);
|
obj = QPDF_Array::create({10, "null"_qpdf.getObj()}, true);
|
||||||
QPDF_Array& b = *obj->as<QPDF_Array>();
|
QPDF_Array& b = *obj->as<QPDF_Array>();
|
||||||
b.setAt(5, pdf.getObject(5, 0));
|
b.setAt(5, pdf.newIndirectNull());
|
||||||
b.setAt(7, "[0 1 2 3]"_qpdf);
|
b.setAt(7, "[0 1 2 3]"_qpdf);
|
||||||
assert(b.at(3).isNull());
|
assert(b.at(3).isNull());
|
||||||
assert(b.at(8).isNull());
|
assert(b.at(8).isNull());
|
||||||
assert(b.at(5).isIndirect());
|
assert(b.at(5).isIndirect());
|
||||||
assert(b.unparse() == "[ null null null null null 5 0 R null [ 0 1 2 3 ] null null ]");
|
assert(b.unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
|
||||||
auto c = b.copy(true);
|
auto c = b.copy(true);
|
||||||
auto d = b.copy(false);
|
auto d = b.copy(false);
|
||||||
b.at(7).setArrayItem(2, "42"_qpdf);
|
b.at(7).setArrayItem(2, "42"_qpdf);
|
||||||
assert(c->unparse() == "[ null null null null null 5 0 R null [ 0 1 42 3 ] null null ]");
|
assert(c->unparse() == "[ null null null null null 3 0 R null [ 0 1 42 3 ] null null ]");
|
||||||
assert(d->unparse() == "[ null null null null null 5 0 R null [ 0 1 2 3 ] null null ]");
|
assert(d->unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
b.setAt(3, {});
|
b.setAt(3, {});
|
||||||
|
@ -675,7 +675,6 @@ QPDF_json ignore second-level key 0
|
|||||||
QPDF_json ignore unknown key in object_top 0
|
QPDF_json ignore unknown key in object_top 0
|
||||||
QPDF_json ignore unknown key in trailer 0
|
QPDF_json ignore unknown key in trailer 0
|
||||||
QPDF_json ignore unknown key in stream 0
|
QPDF_json ignore unknown key in stream 0
|
||||||
QPDF_json non-trivial null reserved 0
|
|
||||||
QPDF_json data and datafile 0
|
QPDF_json data and datafile 0
|
||||||
QPDF_json no stream data in update mode 0
|
QPDF_json no stream data in update mode 0
|
||||||
QPDF_json updating existing stream 0
|
QPDF_json updating existing stream 0
|
||||||
|
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
WARNING: dangling-bad-xref.pdf: file is damaged
|
WARNING: dangling-bad-xref.pdf: file is damaged
|
||||||
WARNING: dangling-bad-xref.pdf (object 7 0, offset 10000): expected n n obj
|
WARNING: dangling-bad-xref.pdf (object 7 0, offset 10000): expected n n obj
|
||||||
WARNING: dangling-bad-xref.pdf: Attempting to reconstruct cross-reference table
|
WARNING: dangling-bad-xref.pdf: Attempting to reconstruct cross-reference table
|
||||||
new object: 13 0 R
|
new object: 12 0 R
|
||||||
all objects
|
all objects
|
||||||
1 0 R
|
1 0 R
|
||||||
2 0 R
|
2 0 R
|
||||||
@ -10,10 +10,6 @@ all objects
|
|||||||
5 0 R
|
5 0 R
|
||||||
6 0 R
|
6 0 R
|
||||||
7 0 R
|
7 0 R
|
||||||
8 0 R
|
|
||||||
9 0 R
|
|
||||||
10 0 R
|
|
||||||
11 0 R
|
11 0 R
|
||||||
12 0 R
|
12 0 R
|
||||||
13 0 R
|
|
||||||
test 53 done
|
test 53 done
|
||||||
|
Binary file not shown.
@ -1,4 +1,4 @@
|
|||||||
new object: 11 0 R
|
new object: 8 0 R
|
||||||
all objects
|
all objects
|
||||||
1 0 R
|
1 0 R
|
||||||
2 0 R
|
2 0 R
|
||||||
@ -8,7 +8,4 @@ all objects
|
|||||||
6 0 R
|
6 0 R
|
||||||
7 0 R
|
7 0 R
|
||||||
8 0 R
|
8 0 R
|
||||||
9 0 R
|
|
||||||
10 0 R
|
|
||||||
11 0 R
|
|
||||||
test 53 done
|
test 53 done
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
/nesting is direct
|
/nesting is direct
|
||||||
/strings is direct
|
/strings is direct
|
||||||
unparse: 7 0 R
|
unparse: 7 0 R
|
||||||
unparseResolved: << /dangling-ref-for-json-test [ 9 0 R ] /hex#20strings [ (Potato) <01020300040560> (AB) ] /indirect 8 0 R /names [ /nesting /hex#20strings /text#2fplain ] /nesting << /a [ 1 2 << /x (y) >> [ (z) ] ] /b << / (legal) /a [ 1 2 ] >> >> /strings [ (one) <24a2> () (\(\)) (\() (\)) (a\f\b\t\r\nb) (") ("") ("\("\)") <410042> (a\nb) (a b) <efbbbfcf80> <efbbbff09fa594> ] >>
|
unparseResolved: << /dangling-ref-for-json-test [ null ] /hex#20strings [ (Potato) <01020300040560> (AB) ] /indirect 8 0 R /names [ /nesting /hex#20strings /text#2fplain ] /nesting << /a [ 1 2 << /x (y) >> [ (z) ] ] /b << / (legal) /a [ 1 2 ] >> >> /strings [ (one) <24a2> () (\(\)) (\() (\)) (a\f\b\t\r\nb) (") ("") ("\("\)") <410042> (a\nb) (a b) <efbbbfcf80> <efbbbff09fa594> ] >>
|
||||||
test 1 done
|
test 1 done
|
||||||
|
@ -14,14 +14,14 @@ endobj
|
|||||||
2 0 obj
|
2 0 obj
|
||||||
<<
|
<<
|
||||||
/dangling-ref-for-json-test [
|
/dangling-ref-for-json-test [
|
||||||
4 0 R
|
null
|
||||||
]
|
]
|
||||||
/hex#20strings [
|
/hex#20strings [
|
||||||
(Potato)
|
(Potato)
|
||||||
<01020300040560>
|
<01020300040560>
|
||||||
(AB)
|
(AB)
|
||||||
]
|
]
|
||||||
/indirect 5 0 R
|
/indirect 4 0 R
|
||||||
/names [
|
/names [
|
||||||
/nesting
|
/nesting
|
||||||
/hex#20strings
|
/hex#20strings
|
||||||
@ -71,27 +71,22 @@ endobj
|
|||||||
<<
|
<<
|
||||||
/Count 1
|
/Count 1
|
||||||
/Kids [
|
/Kids [
|
||||||
6 0 R
|
5 0 R
|
||||||
]
|
]
|
||||||
/Type /Pages
|
/Type /Pages
|
||||||
>>
|
>>
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 9 0
|
|
||||||
4 0 obj
|
|
||||||
null
|
|
||||||
endobj
|
|
||||||
|
|
||||||
%% Original object ID: 8 0
|
%% Original object ID: 8 0
|
||||||
5 0 obj
|
4 0 obj
|
||||||
(hello)
|
(hello)
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Page 1
|
%% Page 1
|
||||||
%% Original object ID: 3 0
|
%% Original object ID: 3 0
|
||||||
6 0 obj
|
5 0 obj
|
||||||
<<
|
<<
|
||||||
/Contents 7 0 R
|
/Contents 6 0 R
|
||||||
/MediaBox [
|
/MediaBox [
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
@ -101,9 +96,9 @@ endobj
|
|||||||
/Parent 3 0 R
|
/Parent 3 0 R
|
||||||
/Resources <<
|
/Resources <<
|
||||||
/Font <<
|
/Font <<
|
||||||
/F1 9 0 R
|
/F1 8 0 R
|
||||||
>>
|
>>
|
||||||
/ProcSet 10 0 R
|
/ProcSet 9 0 R
|
||||||
>>
|
>>
|
||||||
/Type /Page
|
/Type /Page
|
||||||
>>
|
>>
|
||||||
@ -111,9 +106,9 @@ endobj
|
|||||||
|
|
||||||
%% Contents for page 1
|
%% Contents for page 1
|
||||||
%% Original object ID: 4 0
|
%% Original object ID: 4 0
|
||||||
7 0 obj
|
6 0 obj
|
||||||
<<
|
<<
|
||||||
/Length 8 0 R
|
/Length 7 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
BT
|
BT
|
||||||
@ -124,12 +119,12 @@ ET
|
|||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
8 0 obj
|
7 0 obj
|
||||||
44
|
44
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 6 0
|
%% Original object ID: 6 0
|
||||||
9 0 obj
|
8 0 obj
|
||||||
<<
|
<<
|
||||||
/BaseFont /Helvetica
|
/BaseFont /Helvetica
|
||||||
/Encoding /WinAnsiEncoding
|
/Encoding /WinAnsiEncoding
|
||||||
@ -140,7 +135,7 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 5 0
|
%% Original object ID: 5 0
|
||||||
10 0 obj
|
9 0 obj
|
||||||
[
|
[
|
||||||
/PDF
|
/PDF
|
||||||
/Text
|
/Text
|
||||||
@ -148,24 +143,23 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
xref
|
xref
|
||||||
0 11
|
0 10
|
||||||
0000000000 65535 f
|
0000000000 65535 f
|
||||||
0000000052 00000 n
|
0000000052 00000 n
|
||||||
0000000133 00000 n
|
0000000133 00000 n
|
||||||
0000000756 00000 n
|
0000000755 00000 n
|
||||||
0000000855 00000 n
|
0000000854 00000 n
|
||||||
0000000903 00000 n
|
0000000915 00000 n
|
||||||
0000000964 00000 n
|
0000001157 00000 n
|
||||||
0000001207 00000 n
|
0000001256 00000 n
|
||||||
0000001306 00000 n
|
0000001302 00000 n
|
||||||
0000001352 00000 n
|
0000001447 00000 n
|
||||||
0000001497 00000 n
|
|
||||||
trailer <<
|
trailer <<
|
||||||
/QTest 2 0 R
|
/QTest 2 0 R
|
||||||
/Root 1 0 R
|
/Root 1 0 R
|
||||||
/Size 11
|
/Size 10
|
||||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||||
>>
|
>>
|
||||||
startxref
|
startxref
|
||||||
1533
|
1482
|
||||||
%%EOF
|
%%EOF
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
item 2 is direct
|
item 2 is direct
|
||||||
item 3 is indirect
|
item 3 is indirect
|
||||||
item 4 is direct
|
item 4 is direct
|
||||||
item 5 is indirect
|
item 5 is direct
|
||||||
unparse: 9 0 R
|
unparse: 9 0 R
|
||||||
unparseResolved: [ /literal null /indirect 8 0 R /undefined 10 0 R ]
|
unparseResolved: [ /literal null /indirect 8 0 R /undefined null ]
|
||||||
test 1 done
|
test 1 done
|
||||||
|
@ -18,7 +18,7 @@ endobj
|
|||||||
/indirect
|
/indirect
|
||||||
4 0 R
|
4 0 R
|
||||||
/undefined
|
/undefined
|
||||||
5 0 R
|
null
|
||||||
]
|
]
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ endobj
|
|||||||
<<
|
<<
|
||||||
/Count 1
|
/Count 1
|
||||||
/Kids [
|
/Kids [
|
||||||
6 0 R
|
5 0 R
|
||||||
]
|
]
|
||||||
/Type /Pages
|
/Type /Pages
|
||||||
>>
|
>>
|
||||||
@ -38,16 +38,11 @@ endobj
|
|||||||
null
|
null
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 10 0
|
|
||||||
5 0 obj
|
|
||||||
null
|
|
||||||
endobj
|
|
||||||
|
|
||||||
%% Page 1
|
%% Page 1
|
||||||
%% Original object ID: 3 0
|
%% Original object ID: 3 0
|
||||||
6 0 obj
|
5 0 obj
|
||||||
<<
|
<<
|
||||||
/Contents 7 0 R
|
/Contents 6 0 R
|
||||||
/MediaBox [
|
/MediaBox [
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
@ -57,9 +52,9 @@ endobj
|
|||||||
/Parent 3 0 R
|
/Parent 3 0 R
|
||||||
/Resources <<
|
/Resources <<
|
||||||
/Font <<
|
/Font <<
|
||||||
/F1 9 0 R
|
/F1 8 0 R
|
||||||
>>
|
>>
|
||||||
/ProcSet 10 0 R
|
/ProcSet 9 0 R
|
||||||
>>
|
>>
|
||||||
/Type /Page
|
/Type /Page
|
||||||
>>
|
>>
|
||||||
@ -67,9 +62,9 @@ endobj
|
|||||||
|
|
||||||
%% Contents for page 1
|
%% Contents for page 1
|
||||||
%% Original object ID: 4 0
|
%% Original object ID: 4 0
|
||||||
7 0 obj
|
6 0 obj
|
||||||
<<
|
<<
|
||||||
/Length 8 0 R
|
/Length 7 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
BT
|
BT
|
||||||
@ -80,12 +75,12 @@ ET
|
|||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
8 0 obj
|
7 0 obj
|
||||||
44
|
44
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 6 0
|
%% Original object ID: 6 0
|
||||||
9 0 obj
|
8 0 obj
|
||||||
<<
|
<<
|
||||||
/BaseFont /Helvetica
|
/BaseFont /Helvetica
|
||||||
/Encoding /WinAnsiEncoding
|
/Encoding /WinAnsiEncoding
|
||||||
@ -96,7 +91,7 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 7 0
|
%% Original object ID: 7 0
|
||||||
10 0 obj
|
9 0 obj
|
||||||
[
|
[
|
||||||
/PDF
|
/PDF
|
||||||
/Text
|
/Text
|
||||||
@ -104,24 +99,23 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
xref
|
xref
|
||||||
0 11
|
0 10
|
||||||
0000000000 65535 f
|
0000000000 65535 f
|
||||||
0000000052 00000 n
|
0000000052 00000 n
|
||||||
0000000133 00000 n
|
0000000133 00000 n
|
||||||
0000000239 00000 n
|
0000000238 00000 n
|
||||||
0000000338 00000 n
|
0000000337 00000 n
|
||||||
0000000387 00000 n
|
0000000395 00000 n
|
||||||
0000000445 00000 n
|
0000000637 00000 n
|
||||||
0000000688 00000 n
|
0000000736 00000 n
|
||||||
0000000787 00000 n
|
0000000782 00000 n
|
||||||
0000000833 00000 n
|
0000000927 00000 n
|
||||||
0000000978 00000 n
|
|
||||||
trailer <<
|
trailer <<
|
||||||
/QTest 2 0 R
|
/QTest 2 0 R
|
||||||
/Root 1 0 R
|
/Root 1 0 R
|
||||||
/Size 11
|
/Size 10
|
||||||
/ID [<06c2c8fc54c5f9cc9246898e1e1a7146><31415926535897932384626433832795>]
|
/ID [<06c2c8fc54c5f9cc9246898e1e1a7146><31415926535897932384626433832795>]
|
||||||
>>
|
>>
|
||||||
startxref
|
startxref
|
||||||
1014
|
962
|
||||||
%%EOF
|
%%EOF
|
||||||
|
@ -14,14 +14,14 @@ endobj
|
|||||||
2 0 obj
|
2 0 obj
|
||||||
<<
|
<<
|
||||||
/dangling-ref-for-json-test [
|
/dangling-ref-for-json-test [
|
||||||
4 0 R
|
null
|
||||||
]
|
]
|
||||||
/hex#20strings [
|
/hex#20strings [
|
||||||
(Potato)
|
(Potato)
|
||||||
<01020300040560>
|
<01020300040560>
|
||||||
(AB)
|
(AB)
|
||||||
]
|
]
|
||||||
/indirect 5 0 R
|
/indirect 4 0 R
|
||||||
/names [
|
/names [
|
||||||
/nesting
|
/nesting
|
||||||
/hex#20strings
|
/hex#20strings
|
||||||
@ -71,27 +71,22 @@ endobj
|
|||||||
<<
|
<<
|
||||||
/Count 1
|
/Count 1
|
||||||
/Kids [
|
/Kids [
|
||||||
6 0 R
|
5 0 R
|
||||||
]
|
]
|
||||||
/Type /Pages
|
/Type /Pages
|
||||||
>>
|
>>
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 9 0
|
|
||||||
4 0 obj
|
|
||||||
null
|
|
||||||
endobj
|
|
||||||
|
|
||||||
%% Original object ID: 8 0
|
%% Original object ID: 8 0
|
||||||
5 0 obj
|
4 0 obj
|
||||||
(hello)
|
(hello)
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Page 1
|
%% Page 1
|
||||||
%% Original object ID: 3 0
|
%% Original object ID: 3 0
|
||||||
6 0 obj
|
5 0 obj
|
||||||
<<
|
<<
|
||||||
/Contents 7 0 R
|
/Contents 6 0 R
|
||||||
/MediaBox [
|
/MediaBox [
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
@ -101,9 +96,9 @@ endobj
|
|||||||
/Parent 3 0 R
|
/Parent 3 0 R
|
||||||
/Resources <<
|
/Resources <<
|
||||||
/Font <<
|
/Font <<
|
||||||
/F1 9 0 R
|
/F1 8 0 R
|
||||||
>>
|
>>
|
||||||
/ProcSet 10 0 R
|
/ProcSet 9 0 R
|
||||||
>>
|
>>
|
||||||
/Type /Page
|
/Type /Page
|
||||||
>>
|
>>
|
||||||
@ -111,9 +106,9 @@ endobj
|
|||||||
|
|
||||||
%% Contents for page 1
|
%% Contents for page 1
|
||||||
%% Original object ID: 4 0
|
%% Original object ID: 4 0
|
||||||
7 0 obj
|
6 0 obj
|
||||||
<<
|
<<
|
||||||
/Length 8 0 R
|
/Length 7 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
BT
|
BT
|
||||||
@ -124,12 +119,12 @@ ET
|
|||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
8 0 obj
|
7 0 obj
|
||||||
44
|
44
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 6 0
|
%% Original object ID: 6 0
|
||||||
9 0 obj
|
8 0 obj
|
||||||
<<
|
<<
|
||||||
/BaseFont /Helvetica
|
/BaseFont /Helvetica
|
||||||
/Encoding /WinAnsiEncoding
|
/Encoding /WinAnsiEncoding
|
||||||
@ -140,7 +135,7 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 5 0
|
%% Original object ID: 5 0
|
||||||
10 0 obj
|
9 0 obj
|
||||||
[
|
[
|
||||||
/PDF
|
/PDF
|
||||||
/Text
|
/Text
|
||||||
@ -148,24 +143,23 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
xref
|
xref
|
||||||
0 11
|
0 10
|
||||||
0000000000 65535 f
|
0000000000 65535 f
|
||||||
0000000052 00000 n
|
0000000052 00000 n
|
||||||
0000000133 00000 n
|
0000000133 00000 n
|
||||||
0000000752 00000 n
|
0000000751 00000 n
|
||||||
0000000851 00000 n
|
0000000850 00000 n
|
||||||
0000000899 00000 n
|
0000000911 00000 n
|
||||||
0000000960 00000 n
|
0000001153 00000 n
|
||||||
0000001203 00000 n
|
0000001252 00000 n
|
||||||
0000001302 00000 n
|
0000001298 00000 n
|
||||||
0000001348 00000 n
|
0000001443 00000 n
|
||||||
0000001493 00000 n
|
|
||||||
trailer <<
|
trailer <<
|
||||||
/QTest 2 0 R
|
/QTest 2 0 R
|
||||||
/Root 1 0 R
|
/Root 1 0 R
|
||||||
/Size 11
|
/Size 10
|
||||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||||
>>
|
>>
|
||||||
startxref
|
startxref
|
||||||
1529
|
1478
|
||||||
%%EOF
|
%%EOF
|
||||||
|
@ -14,14 +14,14 @@ endobj
|
|||||||
2 0 obj
|
2 0 obj
|
||||||
<<
|
<<
|
||||||
/dangling-ref-for-json-test [
|
/dangling-ref-for-json-test [
|
||||||
4 0 R
|
null
|
||||||
]
|
]
|
||||||
/hex#20strings [
|
/hex#20strings [
|
||||||
(Potato)
|
(Potato)
|
||||||
<01020300040560>
|
<01020300040560>
|
||||||
(AB)
|
(AB)
|
||||||
]
|
]
|
||||||
/indirect 5 0 R
|
/indirect 4 0 R
|
||||||
/names [
|
/names [
|
||||||
/nesting
|
/nesting
|
||||||
/hex#20strings
|
/hex#20strings
|
||||||
@ -71,37 +71,32 @@ endobj
|
|||||||
<<
|
<<
|
||||||
/Count 1
|
/Count 1
|
||||||
/Kids [
|
/Kids [
|
||||||
7 0 R
|
6 0 R
|
||||||
]
|
]
|
||||||
/Type /Pages
|
/Type /Pages
|
||||||
>>
|
>>
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 9 0
|
|
||||||
4 0 obj
|
|
||||||
null
|
|
||||||
endobj
|
|
||||||
|
|
||||||
%% Original object ID: 8 0
|
%% Original object ID: 8 0
|
||||||
5 0 obj
|
4 0 obj
|
||||||
<<
|
<<
|
||||||
/K /V
|
/K /V
|
||||||
/Length 6 0 R
|
/Length 5 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
new-stream-here
|
new-stream-here
|
||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
6 0 obj
|
5 0 obj
|
||||||
16
|
16
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Page 1
|
%% Page 1
|
||||||
%% Original object ID: 3 0
|
%% Original object ID: 3 0
|
||||||
7 0 obj
|
6 0 obj
|
||||||
<<
|
<<
|
||||||
/Contents 8 0 R
|
/Contents 7 0 R
|
||||||
/MediaBox [
|
/MediaBox [
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
@ -111,9 +106,9 @@ endobj
|
|||||||
/Parent 3 0 R
|
/Parent 3 0 R
|
||||||
/Resources <<
|
/Resources <<
|
||||||
/Font <<
|
/Font <<
|
||||||
/F1 10 0 R
|
/F1 9 0 R
|
||||||
>>
|
>>
|
||||||
/ProcSet 11 0 R
|
/ProcSet 10 0 R
|
||||||
>>
|
>>
|
||||||
/Type /Page
|
/Type /Page
|
||||||
>>
|
>>
|
||||||
@ -121,9 +116,9 @@ endobj
|
|||||||
|
|
||||||
%% Contents for page 1
|
%% Contents for page 1
|
||||||
%% Original object ID: 4 0
|
%% Original object ID: 4 0
|
||||||
8 0 obj
|
7 0 obj
|
||||||
<<
|
<<
|
||||||
/Length 9 0 R
|
/Length 8 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
BT
|
BT
|
||||||
@ -134,12 +129,12 @@ ET
|
|||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
9 0 obj
|
8 0 obj
|
||||||
44
|
44
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 6 0
|
%% Original object ID: 6 0
|
||||||
10 0 obj
|
9 0 obj
|
||||||
<<
|
<<
|
||||||
/BaseFont /Helvetica
|
/BaseFont /Helvetica
|
||||||
/Encoding /WinAnsiEncoding
|
/Encoding /WinAnsiEncoding
|
||||||
@ -150,7 +145,7 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 5 0
|
%% Original object ID: 5 0
|
||||||
11 0 obj
|
10 0 obj
|
||||||
[
|
[
|
||||||
/PDF
|
/PDF
|
||||||
/Text
|
/Text
|
||||||
@ -158,25 +153,24 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
xref
|
xref
|
||||||
0 12
|
0 11
|
||||||
0000000000 65535 f
|
0000000000 65535 f
|
||||||
0000000052 00000 n
|
0000000052 00000 n
|
||||||
0000000133 00000 n
|
0000000133 00000 n
|
||||||
0000000756 00000 n
|
0000000755 00000 n
|
||||||
0000000855 00000 n
|
0000000854 00000 n
|
||||||
0000000903 00000 n
|
0000000933 00000 n
|
||||||
0000000982 00000 n
|
0000000989 00000 n
|
||||||
0000001038 00000 n
|
0000001232 00000 n
|
||||||
0000001282 00000 n
|
0000001331 00000 n
|
||||||
0000001381 00000 n
|
0000001377 00000 n
|
||||||
0000001427 00000 n
|
0000001522 00000 n
|
||||||
0000001573 00000 n
|
|
||||||
trailer <<
|
trailer <<
|
||||||
/QTest 2 0 R
|
/QTest 2 0 R
|
||||||
/Root 1 0 R
|
/Root 1 0 R
|
||||||
/Size 12
|
/Size 11
|
||||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||||
>>
|
>>
|
||||||
startxref
|
startxref
|
||||||
1609
|
1558
|
||||||
%%EOF
|
%%EOF
|
||||||
|
@ -14,14 +14,14 @@ endobj
|
|||||||
2 0 obj
|
2 0 obj
|
||||||
<<
|
<<
|
||||||
/dangling-ref-for-json-test [
|
/dangling-ref-for-json-test [
|
||||||
4 0 R
|
null
|
||||||
]
|
]
|
||||||
/hex#20strings [
|
/hex#20strings [
|
||||||
(Potato)
|
(Potato)
|
||||||
<01020300040560>
|
<01020300040560>
|
||||||
(AB)
|
(AB)
|
||||||
]
|
]
|
||||||
/indirect 5 0 R
|
/indirect 4 0 R
|
||||||
/names [
|
/names [
|
||||||
/nesting
|
/nesting
|
||||||
/hex#20strings
|
/hex#20strings
|
||||||
@ -71,27 +71,22 @@ endobj
|
|||||||
<<
|
<<
|
||||||
/Count 1
|
/Count 1
|
||||||
/Kids [
|
/Kids [
|
||||||
6 0 R
|
5 0 R
|
||||||
]
|
]
|
||||||
/Type /Pages
|
/Type /Pages
|
||||||
>>
|
>>
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 9 0
|
|
||||||
4 0 obj
|
|
||||||
null
|
|
||||||
endobj
|
|
||||||
|
|
||||||
%% Original object ID: 8 0
|
%% Original object ID: 8 0
|
||||||
5 0 obj
|
4 0 obj
|
||||||
(hello)
|
(hello)
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Page 1
|
%% Page 1
|
||||||
%% Original object ID: 3 0
|
%% Original object ID: 3 0
|
||||||
6 0 obj
|
5 0 obj
|
||||||
<<
|
<<
|
||||||
/Contents 7 0 R
|
/Contents 6 0 R
|
||||||
/MediaBox [
|
/MediaBox [
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
@ -101,9 +96,9 @@ endobj
|
|||||||
/Parent 3 0 R
|
/Parent 3 0 R
|
||||||
/Resources <<
|
/Resources <<
|
||||||
/Font <<
|
/Font <<
|
||||||
/F1 9 0 R
|
/F1 8 0 R
|
||||||
>>
|
>>
|
||||||
/ProcSet 10 0 R
|
/ProcSet 9 0 R
|
||||||
>>
|
>>
|
||||||
/Type /Page
|
/Type /Page
|
||||||
>>
|
>>
|
||||||
@ -111,9 +106,9 @@ endobj
|
|||||||
|
|
||||||
%% Contents for page 1
|
%% Contents for page 1
|
||||||
%% Original object ID: 4 0
|
%% Original object ID: 4 0
|
||||||
7 0 obj
|
6 0 obj
|
||||||
<<
|
<<
|
||||||
/Length 8 0 R
|
/Length 7 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
BT
|
BT
|
||||||
@ -124,12 +119,12 @@ ET
|
|||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
8 0 obj
|
7 0 obj
|
||||||
43
|
43
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 6 0
|
%% Original object ID: 6 0
|
||||||
9 0 obj
|
8 0 obj
|
||||||
<<
|
<<
|
||||||
/BaseFont /Helvetica
|
/BaseFont /Helvetica
|
||||||
/Encoding /WinAnsiEncoding
|
/Encoding /WinAnsiEncoding
|
||||||
@ -140,7 +135,7 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 5 0
|
%% Original object ID: 5 0
|
||||||
10 0 obj
|
9 0 obj
|
||||||
[
|
[
|
||||||
/PDF
|
/PDF
|
||||||
/Text
|
/Text
|
||||||
@ -148,24 +143,23 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
xref
|
xref
|
||||||
0 11
|
0 10
|
||||||
0000000000 65535 f
|
0000000000 65535 f
|
||||||
0000000052 00000 n
|
0000000052 00000 n
|
||||||
0000000133 00000 n
|
0000000133 00000 n
|
||||||
0000000756 00000 n
|
0000000755 00000 n
|
||||||
0000000855 00000 n
|
0000000854 00000 n
|
||||||
0000000903 00000 n
|
0000000915 00000 n
|
||||||
0000000964 00000 n
|
0000001157 00000 n
|
||||||
0000001207 00000 n
|
0000001255 00000 n
|
||||||
0000001305 00000 n
|
0000001301 00000 n
|
||||||
0000001351 00000 n
|
0000001446 00000 n
|
||||||
0000001496 00000 n
|
|
||||||
trailer <<
|
trailer <<
|
||||||
/QTest 2 0 R
|
/QTest 2 0 R
|
||||||
/Root 1 0 R
|
/Root 1 0 R
|
||||||
/Size 11
|
/Size 10
|
||||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||||
>>
|
>>
|
||||||
startxref
|
startxref
|
||||||
1532
|
1481
|
||||||
%%EOF
|
%%EOF
|
||||||
|
@ -14,14 +14,14 @@ endobj
|
|||||||
2 0 obj
|
2 0 obj
|
||||||
<<
|
<<
|
||||||
/dangling-ref-for-json-test [
|
/dangling-ref-for-json-test [
|
||||||
4 0 R
|
null
|
||||||
]
|
]
|
||||||
/hex#20strings [
|
/hex#20strings [
|
||||||
(Potato)
|
(Potato)
|
||||||
<01020300040560>
|
<01020300040560>
|
||||||
(AB)
|
(AB)
|
||||||
]
|
]
|
||||||
/indirect 5 0 R
|
/indirect 4 0 R
|
||||||
/names [
|
/names [
|
||||||
/nesting
|
/nesting
|
||||||
/hex#20strings
|
/hex#20strings
|
||||||
@ -71,27 +71,22 @@ endobj
|
|||||||
<<
|
<<
|
||||||
/Count 1
|
/Count 1
|
||||||
/Kids [
|
/Kids [
|
||||||
6 0 R
|
5 0 R
|
||||||
]
|
]
|
||||||
/Type /Pages
|
/Type /Pages
|
||||||
>>
|
>>
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 9 0
|
|
||||||
4 0 obj
|
|
||||||
null
|
|
||||||
endobj
|
|
||||||
|
|
||||||
%% Original object ID: 8 0
|
%% Original object ID: 8 0
|
||||||
5 0 obj
|
4 0 obj
|
||||||
(hello)
|
(hello)
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Page 1
|
%% Page 1
|
||||||
%% Original object ID: 3 0
|
%% Original object ID: 3 0
|
||||||
6 0 obj
|
5 0 obj
|
||||||
<<
|
<<
|
||||||
/Contents 7 0 R
|
/Contents 6 0 R
|
||||||
/MediaBox [
|
/MediaBox [
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
@ -101,9 +96,9 @@ endobj
|
|||||||
/Parent 3 0 R
|
/Parent 3 0 R
|
||||||
/Resources <<
|
/Resources <<
|
||||||
/Font <<
|
/Font <<
|
||||||
/F1 9 0 R
|
/F1 8 0 R
|
||||||
>>
|
>>
|
||||||
/ProcSet 10 0 R
|
/ProcSet 9 0 R
|
||||||
>>
|
>>
|
||||||
/Type /Page
|
/Type /Page
|
||||||
>>
|
>>
|
||||||
@ -111,10 +106,10 @@ endobj
|
|||||||
|
|
||||||
%% Contents for page 1
|
%% Contents for page 1
|
||||||
%% Original object ID: 4 0
|
%% Original object ID: 4 0
|
||||||
7 0 obj
|
6 0 obj
|
||||||
<<
|
<<
|
||||||
/Potato (salad)
|
/Potato (salad)
|
||||||
/Length 8 0 R
|
/Length 7 0 R
|
||||||
>>
|
>>
|
||||||
stream
|
stream
|
||||||
BT
|
BT
|
||||||
@ -125,12 +120,12 @@ ET
|
|||||||
endstream
|
endstream
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
8 0 obj
|
7 0 obj
|
||||||
44
|
44
|
||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 6 0
|
%% Original object ID: 6 0
|
||||||
9 0 obj
|
8 0 obj
|
||||||
<<
|
<<
|
||||||
/BaseFont /Helvetica
|
/BaseFont /Helvetica
|
||||||
/Encoding /WinAnsiEncoding
|
/Encoding /WinAnsiEncoding
|
||||||
@ -141,7 +136,7 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
%% Original object ID: 5 0
|
%% Original object ID: 5 0
|
||||||
10 0 obj
|
9 0 obj
|
||||||
[
|
[
|
||||||
/PDF
|
/PDF
|
||||||
/Text
|
/Text
|
||||||
@ -149,24 +144,23 @@ endobj
|
|||||||
endobj
|
endobj
|
||||||
|
|
||||||
xref
|
xref
|
||||||
0 11
|
0 10
|
||||||
0000000000 65535 f
|
0000000000 65535 f
|
||||||
0000000052 00000 n
|
0000000052 00000 n
|
||||||
0000000133 00000 n
|
0000000133 00000 n
|
||||||
0000000756 00000 n
|
0000000755 00000 n
|
||||||
0000000855 00000 n
|
0000000854 00000 n
|
||||||
0000000903 00000 n
|
0000000915 00000 n
|
||||||
0000000964 00000 n
|
0000001157 00000 n
|
||||||
0000001207 00000 n
|
0000001274 00000 n
|
||||||
0000001324 00000 n
|
0000001320 00000 n
|
||||||
0000001370 00000 n
|
0000001465 00000 n
|
||||||
0000001515 00000 n
|
|
||||||
trailer <<
|
trailer <<
|
||||||
/QTest 2 0 R
|
/QTest 2 0 R
|
||||||
/Root 1 0 R
|
/Root 1 0 R
|
||||||
/Size 11
|
/Size 10
|
||||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||||
>>
|
>>
|
||||||
startxref
|
startxref
|
||||||
1551
|
1500
|
||||||
%%EOF
|
%%EOF
|
||||||
|
Loading…
Reference in New Issue
Block a user