mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +00:00
Refactor the creation of unresolved objects
Create unresolved objects only for objects in the xref table (except during parsing of the xref table). Do not add indirect nulls into the the object cache as the result of a cache miss during a call to getObject except during parsing or creation/updating from JSON. To support this behaviour, add new private methods getObjectForParser and getObjectForJSON. As a result of this change, dangling references are treated as direct nulls rather than indirect nulls.
This commit is contained in:
parent
87ee8ad071
commit
06001ed25b
@ -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
|
||||
{
|
||||
friend class QPDFParser;
|
||||
@ -832,6 +833,13 @@ class QPDF
|
||||
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()
|
||||
{
|
||||
if (qpdf) {
|
||||
@ -900,8 +908,8 @@ class QPDF
|
||||
}
|
||||
ObjCache(
|
||||
std::shared_ptr<QPDFObject> object,
|
||||
qpdf_offset_t end_before_space,
|
||||
qpdf_offset_t end_after_space) :
|
||||
qpdf_offset_t end_before_space = 0,
|
||||
qpdf_offset_t end_after_space = 0) :
|
||||
object(object),
|
||||
end_before_space(end_before_space),
|
||||
end_after_space(end_after_space)
|
||||
@ -1065,13 +1073,14 @@ class QPDF
|
||||
QPDFObject* resolve(QPDFObjGen og);
|
||||
void resolveObjectsInStream(int obj_stream_number);
|
||||
void stopOnError(std::string const& message);
|
||||
QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og);
|
||||
QPDFObjectHandle reserveStream(QPDFObjGen const& og);
|
||||
QPDFObjGen nextObjGen();
|
||||
QPDFObjectHandle newIndirect(QPDFObjGen const&, std::shared_ptr<QPDFObject> const&);
|
||||
QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj);
|
||||
bool isCached(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 updateCache(
|
||||
QPDFObjGen const& og,
|
||||
|
@ -654,9 +654,11 @@ QPDF::reconstruct_xref(QPDFExc& e)
|
||||
}
|
||||
check_warnings();
|
||||
if (!m->parsed) {
|
||||
m->parsed = true;
|
||||
getAllPages();
|
||||
check_warnings();
|
||||
if (m->all_pages.empty()) {
|
||||
m->parsed = false;
|
||||
throw damagedPDF("", 0, "unable to find any pages while recovering damaged file");
|
||||
}
|
||||
}
|
||||
@ -2095,31 +2097,53 @@ QPDF::newStream(std::string const& data)
|
||||
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
|
||||
QPDF::reserveStream(QPDFObjGen const& og)
|
||||
{
|
||||
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
|
||||
QPDF::getObject(QPDFObjGen const& og)
|
||||
{
|
||||
// This method is called by the parser and therefore must not resolve any objects.
|
||||
if (!isCached(og)) {
|
||||
m->obj_cache[og] = ObjCache(QPDF_Unresolved::create(this, og), -1, -1);
|
||||
if (auto it = m->obj_cache.find(og); it != m->obj_cache.end()) {
|
||||
return {it->second.object};
|
||||
} 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
|
||||
|
@ -166,10 +166,7 @@ QPDFParser::parseRemainder(bool content_stream)
|
||||
auto id = QIntC::to_int(int_buffer[(int_count - 1) % 2]);
|
||||
auto gen = QIntC::to_int(int_buffer[(int_count) % 2]);
|
||||
if (!(id < 1 || gen < 0 || gen >= 65535)) {
|
||||
// This action has the desirable side effect of causing dangling references
|
||||
// (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));
|
||||
add(QPDF::ParseGuard::getObject(context, id, gen, parse_pdf));
|
||||
} else {
|
||||
QTC::TC("qpdf", "QPDFParser invalid objgen");
|
||||
addNull();
|
||||
|
@ -1237,7 +1237,7 @@ bool
|
||||
QPDFWriter::willFilterStream(
|
||||
QPDFObjectHandle stream,
|
||||
bool& compress_stream, // out only
|
||||
bool& is_metadata, // out only
|
||||
bool& is_metadata, // out only
|
||||
std::shared_ptr<Buffer>* stream_data)
|
||||
{
|
||||
compress_stream = false;
|
||||
|
@ -3,15 +3,15 @@
|
||||
#include <qpdf/JSON_writer.hh>
|
||||
#include <qpdf/QPDFObject_private.hh>
|
||||
|
||||
QPDF_Null::QPDF_Null() :
|
||||
QPDFValue(::ot_null, "null")
|
||||
QPDF_Null::QPDF_Null(QPDF* qpdf, QPDFObjGen og) :
|
||||
QPDFValue(::ot_null, "null", qpdf, og)
|
||||
{
|
||||
}
|
||||
|
||||
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>
|
||||
|
@ -240,11 +240,6 @@ class QPDF::JSONReactor: public JSON::Reactor
|
||||
descr(std::make_shared<QPDFValue::Description>(
|
||||
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;
|
||||
void dictionaryStart() override;
|
||||
@ -305,7 +300,6 @@ class QPDF::JSONReactor: public JSON::Reactor
|
||||
bool saw_data{false};
|
||||
bool saw_datafile{false};
|
||||
bool this_stream_needs_data{false};
|
||||
std::set<QPDFObjGen> reserved;
|
||||
std::vector<StackFrame> stack;
|
||||
QPDFObjectHandle next_obj;
|
||||
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()) {
|
||||
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)) {
|
||||
this->cur_object = key;
|
||||
if (setNextStateIfDictionary(key, value, st_object_top)) {
|
||||
next_obj = pdf.reserveObjectIfNotExists(QPDFObjGen(obj, gen));
|
||||
next_obj = pdf.getObjectForJSON(obj, gen);
|
||||
}
|
||||
} else {
|
||||
QTC::TC("qpdf", "QPDF_json bad object key");
|
||||
@ -767,7 +751,7 @@ QPDF::JSONReactor::makeObject(JSON const& value)
|
||||
int gen = 0;
|
||||
std::string str;
|
||||
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)) {
|
||||
result = QPDFObjectHandle::newUnicodeString(str);
|
||||
} else if (is_binary_string(str_v, str)) {
|
||||
|
@ -24,7 +24,8 @@ class QPDFParser
|
||||
decrypter(decrypter),
|
||||
context(context),
|
||||
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;
|
||||
@ -77,6 +78,8 @@ class QPDFParser
|
||||
QPDFObjectHandle::StringDecrypter* decrypter;
|
||||
QPDF* context;
|
||||
std::shared_ptr<QPDFValue::Description> description;
|
||||
bool parse_pdf;
|
||||
|
||||
std::vector<StackFrame> stack;
|
||||
StackFrame* frame;
|
||||
// Number of recent bad tokens.
|
||||
|
@ -7,7 +7,7 @@ class QPDF_Null: public QPDFValue
|
||||
{
|
||||
public:
|
||||
~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(
|
||||
std::shared_ptr<QPDFObject> parent,
|
||||
std::string_view const& static_descr,
|
||||
@ -21,7 +21,7 @@ class QPDF_Null: public QPDFValue
|
||||
void writeJSON(int json_version, JSON::Writer& p) override;
|
||||
|
||||
private:
|
||||
QPDF_Null();
|
||||
QPDF_Null(QPDF* qpdf = nullptr, QPDFObjGen og = QPDFObjGen());
|
||||
};
|
||||
|
||||
#endif // QPDF_NULL_HH
|
||||
|
@ -90,17 +90,17 @@ main()
|
||||
|
||||
obj = QPDF_Array::create({10, "null"_qpdf.getObj()}, true);
|
||||
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);
|
||||
assert(b.at(3).isNull());
|
||||
assert(b.at(8).isNull());
|
||||
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 d = b.copy(false);
|
||||
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(d->unparse() == "[ null null null null null 5 0 R null [ 0 1 2 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 3 0 R null [ 0 1 2 3 ] null null ]");
|
||||
|
||||
try {
|
||||
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 trailer 0
|
||||
QPDF_json ignore unknown key in stream 0
|
||||
QPDF_json non-trivial null reserved 0
|
||||
QPDF_json data and datafile 0
|
||||
QPDF_json no stream data in update mode 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 (object 7 0, offset 10000): expected n n obj
|
||||
WARNING: dangling-bad-xref.pdf: Attempting to reconstruct cross-reference table
|
||||
new object: 13 0 R
|
||||
new object: 12 0 R
|
||||
all objects
|
||||
1 0 R
|
||||
2 0 R
|
||||
@ -10,10 +10,6 @@ all objects
|
||||
5 0 R
|
||||
6 0 R
|
||||
7 0 R
|
||||
8 0 R
|
||||
9 0 R
|
||||
10 0 R
|
||||
11 0 R
|
||||
12 0 R
|
||||
13 0 R
|
||||
test 53 done
|
||||
|
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
new object: 11 0 R
|
||||
new object: 8 0 R
|
||||
all objects
|
||||
1 0 R
|
||||
2 0 R
|
||||
@ -8,7 +8,4 @@ all objects
|
||||
6 0 R
|
||||
7 0 R
|
||||
8 0 R
|
||||
9 0 R
|
||||
10 0 R
|
||||
11 0 R
|
||||
test 53 done
|
||||
|
@ -7,5 +7,5 @@
|
||||
/nesting is direct
|
||||
/strings is direct
|
||||
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
|
||||
|
@ -14,14 +14,14 @@ endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/dangling-ref-for-json-test [
|
||||
4 0 R
|
||||
null
|
||||
]
|
||||
/hex#20strings [
|
||||
(Potato)
|
||||
<01020300040560>
|
||||
(AB)
|
||||
]
|
||||
/indirect 5 0 R
|
||||
/indirect 4 0 R
|
||||
/names [
|
||||
/nesting
|
||||
/hex#20strings
|
||||
@ -71,27 +71,22 @@ endobj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
6 0 R
|
||||
5 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 9 0
|
||||
4 0 obj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Original object ID: 8 0
|
||||
5 0 obj
|
||||
4 0 obj
|
||||
(hello)
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 3 0
|
||||
6 0 obj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 7 0 R
|
||||
/Contents 6 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
@ -101,9 +96,9 @@ endobj
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
/F1 8 0 R
|
||||
>>
|
||||
/ProcSet 10 0 R
|
||||
/ProcSet 9 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
@ -111,9 +106,9 @@ endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 4 0
|
||||
7 0 obj
|
||||
6 0 obj
|
||||
<<
|
||||
/Length 8 0 R
|
||||
/Length 7 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
@ -124,12 +119,12 @@ ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
7 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
%% Original object ID: 6 0
|
||||
9 0 obj
|
||||
8 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
@ -140,7 +135,7 @@ endobj
|
||||
endobj
|
||||
|
||||
%% Original object ID: 5 0
|
||||
10 0 obj
|
||||
9 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
@ -148,24 +143,23 @@ endobj
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0 10
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000133 00000 n
|
||||
0000000756 00000 n
|
||||
0000000855 00000 n
|
||||
0000000903 00000 n
|
||||
0000000964 00000 n
|
||||
0000001207 00000 n
|
||||
0000001306 00000 n
|
||||
0000001352 00000 n
|
||||
0000001497 00000 n
|
||||
0000000755 00000 n
|
||||
0000000854 00000 n
|
||||
0000000915 00000 n
|
||||
0000001157 00000 n
|
||||
0000001256 00000 n
|
||||
0000001302 00000 n
|
||||
0000001447 00000 n
|
||||
trailer <<
|
||||
/QTest 2 0 R
|
||||
/Root 1 0 R
|
||||
/Size 11
|
||||
/Size 10
|
||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
1533
|
||||
1482
|
||||
%%EOF
|
||||
|
@ -5,7 +5,7 @@
|
||||
item 2 is direct
|
||||
item 3 is indirect
|
||||
item 4 is direct
|
||||
item 5 is indirect
|
||||
item 5 is direct
|
||||
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
|
||||
|
@ -18,7 +18,7 @@ endobj
|
||||
/indirect
|
||||
4 0 R
|
||||
/undefined
|
||||
5 0 R
|
||||
null
|
||||
]
|
||||
endobj
|
||||
|
||||
@ -27,7 +27,7 @@ endobj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
6 0 R
|
||||
5 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
@ -38,16 +38,11 @@ endobj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Original object ID: 10 0
|
||||
5 0 obj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 3 0
|
||||
6 0 obj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 7 0 R
|
||||
/Contents 6 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
@ -57,9 +52,9 @@ endobj
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
/F1 8 0 R
|
||||
>>
|
||||
/ProcSet 10 0 R
|
||||
/ProcSet 9 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
@ -67,9 +62,9 @@ endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 4 0
|
||||
7 0 obj
|
||||
6 0 obj
|
||||
<<
|
||||
/Length 8 0 R
|
||||
/Length 7 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
@ -80,12 +75,12 @@ ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
7 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
%% Original object ID: 6 0
|
||||
9 0 obj
|
||||
8 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
@ -96,7 +91,7 @@ endobj
|
||||
endobj
|
||||
|
||||
%% Original object ID: 7 0
|
||||
10 0 obj
|
||||
9 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
@ -104,24 +99,23 @@ endobj
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0 10
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000133 00000 n
|
||||
0000000239 00000 n
|
||||
0000000338 00000 n
|
||||
0000000387 00000 n
|
||||
0000000445 00000 n
|
||||
0000000688 00000 n
|
||||
0000000787 00000 n
|
||||
0000000833 00000 n
|
||||
0000000978 00000 n
|
||||
0000000238 00000 n
|
||||
0000000337 00000 n
|
||||
0000000395 00000 n
|
||||
0000000637 00000 n
|
||||
0000000736 00000 n
|
||||
0000000782 00000 n
|
||||
0000000927 00000 n
|
||||
trailer <<
|
||||
/QTest 2 0 R
|
||||
/Root 1 0 R
|
||||
/Size 11
|
||||
/Size 10
|
||||
/ID [<06c2c8fc54c5f9cc9246898e1e1a7146><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
1014
|
||||
962
|
||||
%%EOF
|
||||
|
@ -14,14 +14,14 @@ endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/dangling-ref-for-json-test [
|
||||
4 0 R
|
||||
null
|
||||
]
|
||||
/hex#20strings [
|
||||
(Potato)
|
||||
<01020300040560>
|
||||
(AB)
|
||||
]
|
||||
/indirect 5 0 R
|
||||
/indirect 4 0 R
|
||||
/names [
|
||||
/nesting
|
||||
/hex#20strings
|
||||
@ -71,27 +71,22 @@ endobj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
6 0 R
|
||||
5 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 9 0
|
||||
4 0 obj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Original object ID: 8 0
|
||||
5 0 obj
|
||||
4 0 obj
|
||||
(hello)
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 3 0
|
||||
6 0 obj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 7 0 R
|
||||
/Contents 6 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
@ -101,9 +96,9 @@ endobj
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
/F1 8 0 R
|
||||
>>
|
||||
/ProcSet 10 0 R
|
||||
/ProcSet 9 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
@ -111,9 +106,9 @@ endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 4 0
|
||||
7 0 obj
|
||||
6 0 obj
|
||||
<<
|
||||
/Length 8 0 R
|
||||
/Length 7 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
@ -124,12 +119,12 @@ ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
7 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
%% Original object ID: 6 0
|
||||
9 0 obj
|
||||
8 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
@ -140,7 +135,7 @@ endobj
|
||||
endobj
|
||||
|
||||
%% Original object ID: 5 0
|
||||
10 0 obj
|
||||
9 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
@ -148,24 +143,23 @@ endobj
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0 10
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000133 00000 n
|
||||
0000000752 00000 n
|
||||
0000000851 00000 n
|
||||
0000000899 00000 n
|
||||
0000000960 00000 n
|
||||
0000001203 00000 n
|
||||
0000001302 00000 n
|
||||
0000001348 00000 n
|
||||
0000001493 00000 n
|
||||
0000000751 00000 n
|
||||
0000000850 00000 n
|
||||
0000000911 00000 n
|
||||
0000001153 00000 n
|
||||
0000001252 00000 n
|
||||
0000001298 00000 n
|
||||
0000001443 00000 n
|
||||
trailer <<
|
||||
/QTest 2 0 R
|
||||
/Root 1 0 R
|
||||
/Size 11
|
||||
/Size 10
|
||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
1529
|
||||
1478
|
||||
%%EOF
|
||||
|
@ -14,14 +14,14 @@ endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/dangling-ref-for-json-test [
|
||||
4 0 R
|
||||
null
|
||||
]
|
||||
/hex#20strings [
|
||||
(Potato)
|
||||
<01020300040560>
|
||||
(AB)
|
||||
]
|
||||
/indirect 5 0 R
|
||||
/indirect 4 0 R
|
||||
/names [
|
||||
/nesting
|
||||
/hex#20strings
|
||||
@ -71,37 +71,32 @@ endobj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
7 0 R
|
||||
6 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 9 0
|
||||
4 0 obj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Original object ID: 8 0
|
||||
5 0 obj
|
||||
4 0 obj
|
||||
<<
|
||||
/K /V
|
||||
/Length 6 0 R
|
||||
/Length 5 0 R
|
||||
>>
|
||||
stream
|
||||
new-stream-here
|
||||
endstream
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
5 0 obj
|
||||
16
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 3 0
|
||||
7 0 obj
|
||||
6 0 obj
|
||||
<<
|
||||
/Contents 8 0 R
|
||||
/Contents 7 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
@ -111,9 +106,9 @@ endobj
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 10 0 R
|
||||
/F1 9 0 R
|
||||
>>
|
||||
/ProcSet 11 0 R
|
||||
/ProcSet 10 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
@ -121,9 +116,9 @@ endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 4 0
|
||||
8 0 obj
|
||||
7 0 obj
|
||||
<<
|
||||
/Length 9 0 R
|
||||
/Length 8 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
@ -134,12 +129,12 @@ ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
9 0 obj
|
||||
8 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
%% Original object ID: 6 0
|
||||
10 0 obj
|
||||
9 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
@ -150,7 +145,7 @@ endobj
|
||||
endobj
|
||||
|
||||
%% Original object ID: 5 0
|
||||
11 0 obj
|
||||
10 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
@ -158,25 +153,24 @@ endobj
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 12
|
||||
0 11
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000133 00000 n
|
||||
0000000756 00000 n
|
||||
0000000855 00000 n
|
||||
0000000903 00000 n
|
||||
0000000982 00000 n
|
||||
0000001038 00000 n
|
||||
0000001282 00000 n
|
||||
0000001381 00000 n
|
||||
0000001427 00000 n
|
||||
0000001573 00000 n
|
||||
0000000755 00000 n
|
||||
0000000854 00000 n
|
||||
0000000933 00000 n
|
||||
0000000989 00000 n
|
||||
0000001232 00000 n
|
||||
0000001331 00000 n
|
||||
0000001377 00000 n
|
||||
0000001522 00000 n
|
||||
trailer <<
|
||||
/QTest 2 0 R
|
||||
/Root 1 0 R
|
||||
/Size 12
|
||||
/Size 11
|
||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
1609
|
||||
1558
|
||||
%%EOF
|
||||
|
@ -14,14 +14,14 @@ endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/dangling-ref-for-json-test [
|
||||
4 0 R
|
||||
null
|
||||
]
|
||||
/hex#20strings [
|
||||
(Potato)
|
||||
<01020300040560>
|
||||
(AB)
|
||||
]
|
||||
/indirect 5 0 R
|
||||
/indirect 4 0 R
|
||||
/names [
|
||||
/nesting
|
||||
/hex#20strings
|
||||
@ -71,27 +71,22 @@ endobj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
6 0 R
|
||||
5 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 9 0
|
||||
4 0 obj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Original object ID: 8 0
|
||||
5 0 obj
|
||||
4 0 obj
|
||||
(hello)
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 3 0
|
||||
6 0 obj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 7 0 R
|
||||
/Contents 6 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
@ -101,9 +96,9 @@ endobj
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
/F1 8 0 R
|
||||
>>
|
||||
/ProcSet 10 0 R
|
||||
/ProcSet 9 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
@ -111,9 +106,9 @@ endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 4 0
|
||||
7 0 obj
|
||||
6 0 obj
|
||||
<<
|
||||
/Length 8 0 R
|
||||
/Length 7 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
@ -124,12 +119,12 @@ ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
7 0 obj
|
||||
43
|
||||
endobj
|
||||
|
||||
%% Original object ID: 6 0
|
||||
9 0 obj
|
||||
8 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
@ -140,7 +135,7 @@ endobj
|
||||
endobj
|
||||
|
||||
%% Original object ID: 5 0
|
||||
10 0 obj
|
||||
9 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
@ -148,24 +143,23 @@ endobj
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0 10
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000133 00000 n
|
||||
0000000756 00000 n
|
||||
0000000855 00000 n
|
||||
0000000903 00000 n
|
||||
0000000964 00000 n
|
||||
0000001207 00000 n
|
||||
0000001305 00000 n
|
||||
0000001351 00000 n
|
||||
0000001496 00000 n
|
||||
0000000755 00000 n
|
||||
0000000854 00000 n
|
||||
0000000915 00000 n
|
||||
0000001157 00000 n
|
||||
0000001255 00000 n
|
||||
0000001301 00000 n
|
||||
0000001446 00000 n
|
||||
trailer <<
|
||||
/QTest 2 0 R
|
||||
/Root 1 0 R
|
||||
/Size 11
|
||||
/Size 10
|
||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
1532
|
||||
1481
|
||||
%%EOF
|
||||
|
@ -14,14 +14,14 @@ endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/dangling-ref-for-json-test [
|
||||
4 0 R
|
||||
null
|
||||
]
|
||||
/hex#20strings [
|
||||
(Potato)
|
||||
<01020300040560>
|
||||
(AB)
|
||||
]
|
||||
/indirect 5 0 R
|
||||
/indirect 4 0 R
|
||||
/names [
|
||||
/nesting
|
||||
/hex#20strings
|
||||
@ -71,27 +71,22 @@ endobj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
6 0 R
|
||||
5 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 9 0
|
||||
4 0 obj
|
||||
null
|
||||
endobj
|
||||
|
||||
%% Original object ID: 8 0
|
||||
5 0 obj
|
||||
4 0 obj
|
||||
(hello)
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 3 0
|
||||
6 0 obj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 7 0 R
|
||||
/Contents 6 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
@ -101,9 +96,9 @@ endobj
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 9 0 R
|
||||
/F1 8 0 R
|
||||
>>
|
||||
/ProcSet 10 0 R
|
||||
/ProcSet 9 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
@ -111,10 +106,10 @@ endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 4 0
|
||||
7 0 obj
|
||||
6 0 obj
|
||||
<<
|
||||
/Potato (salad)
|
||||
/Length 8 0 R
|
||||
/Length 7 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
@ -125,12 +120,12 @@ ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
7 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
%% Original object ID: 6 0
|
||||
9 0 obj
|
||||
8 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
@ -141,7 +136,7 @@ endobj
|
||||
endobj
|
||||
|
||||
%% Original object ID: 5 0
|
||||
10 0 obj
|
||||
9 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
@ -149,24 +144,23 @@ endobj
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 11
|
||||
0 10
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000133 00000 n
|
||||
0000000756 00000 n
|
||||
0000000855 00000 n
|
||||
0000000903 00000 n
|
||||
0000000964 00000 n
|
||||
0000001207 00000 n
|
||||
0000001324 00000 n
|
||||
0000001370 00000 n
|
||||
0000001515 00000 n
|
||||
0000000755 00000 n
|
||||
0000000854 00000 n
|
||||
0000000915 00000 n
|
||||
0000001157 00000 n
|
||||
0000001274 00000 n
|
||||
0000001320 00000 n
|
||||
0000001465 00000 n
|
||||
trailer <<
|
||||
/QTest 2 0 R
|
||||
/Root 1 0 R
|
||||
/Size 11
|
||||
/Size 10
|
||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
1551
|
||||
1500
|
||||
%%EOF
|
||||
|
Loading…
Reference in New Issue
Block a user