summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO14
-rw-r--r--include/qpdf/QPDFObjectHandle.hh7
-rw-r--r--libqpdf/QPDFObjectHandle.cc23
-rw-r--r--libqpdf/QPDF_Stream.cc16
-rw-r--r--libqpdf/QPDF_encryption.cc25
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/qtest/qpdf.test10
-rw-r--r--qpdf/qtest/qpdf/decrypted-crypt-filter.pdfbin0 -> 14383 bytes
-rw-r--r--qpdf/qtest/qpdf/metadata-crypt-filter.pdf411
9 files changed, 483 insertions, 24 deletions
diff --git a/TODO b/TODO
index ee52b38f..1f63c646 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,6 @@
2.1
===
- * Really need to handle /Crypt filter for Metadata. Search for crypt
- below.
-
* Update documentation to reflect new command line flags and any
other relevant changes. Should read through ChangeLog and the
manual before releasing 2.1.
@@ -83,10 +80,13 @@ General
filters. There is an example in the spec of using a crypt filter
on a metadata stream.
- When we write encrypted files, we must remember to omit any
- encryption filter settings from original streams.
-
- We need a way to test this.
+ For now, we notice /Crypt filters and decode parameters consistent
+ with the example in the PDF specification, and the right thing
+ happens for metadata filters that happen to be uncompressed or
+ otherwise compressed in a way we can filter. This should handle
+ all normal cases, but it's more or less just a guess since I don't
+ have any test files that actually use stream-specific crypt filters
+ in them.
* The second xref stream for linearized files has to be padded only
because we need file_size as computed in pass 1 to be accurate. If
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index 348aef6b..0a277384 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -77,14 +77,14 @@ class DLL_EXPORT QPDFObjectHandle
bool isNumber();
double getNumericValue();
- // Methods for name objects
+ // Methods for name objects; see also name and array objects
std::string getName();
// Methods for string objects
std::string getStringValue();
std::string getUTF8Value();
- // Methods for array objects
+ // Methods for array objects; see also name and array objects
int getArrayNItems();
QPDFObjectHandle getArrayItem(int n);
@@ -93,6 +93,9 @@ class DLL_EXPORT QPDFObjectHandle
QPDFObjectHandle getKey(std::string const&);
std::set<std::string> getKeys();
+ // Methods for name and array objects
+ bool isOrHasName(std::string const&);
+
// Mutator methods. Use with caution.
// Recursively copy this object, making it direct. Throws an
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 08d648bd..c3a7167b 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -258,6 +258,29 @@ QPDFObjectHandle::getKeys()
return dynamic_cast<QPDF_Dictionary*>(obj.getPointer())->getKeys();
}
+// Array and Name accessors
+bool
+QPDFObjectHandle::isOrHasName(std::string const& value)
+{
+ if (isName() && (getName() == value))
+ {
+ return true;
+ }
+ else if (isArray())
+ {
+ int n = getArrayNItems();
+ for (int i = 0; i < n; ++i)
+ {
+ QPDFObjectHandle item = getArrayItem(0);
+ if (item.isName() && (item.getName() == value))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
// Dictionary mutators
void
diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc
index a9e2ec51..6642a06e 100644
--- a/libqpdf/QPDF_Stream.cc
+++ b/libqpdf/QPDF_Stream.cc
@@ -136,6 +136,13 @@ QPDF_Stream::filterable(std::vector<std::string>& filters,
filterable = false;
}
}
+ else if (((key == "/Type") || (key == "/Name")) &&
+ decode_obj.getKey("/Type").isName() &&
+ (decode_obj.getKey("/Type").getName() ==
+ "/CryptFilterDecodeParms"))
+ {
+ // we handle this in decryptStream
+ }
else
{
filterable = false;
@@ -212,7 +219,8 @@ QPDF_Stream::filterable(std::vector<std::string>& filters,
iter != filters.end(); ++iter)
{
std::string const& filter = *iter;
- if (! ((filter == "/FlateDecode") ||
+ if (! ((filter == "/Crypt") ||
+ (filter == "/FlateDecode") ||
(filter == "/LZWDecode") ||
(filter == "/ASCII85Decode") ||
(filter == "/ASCIIHexDecode")))
@@ -266,7 +274,11 @@ QPDF_Stream::pipeStreamData(Pipeline* pipeline, bool filter,
iter != filters.rend(); ++iter)
{
std::string const& filter = *iter;
- if (filter == "/FlateDecode")
+ if (filter == "/Crypt")
+ {
+ // Ignore -- handled by pipeStreamData
+ }
+ else if (filter == "/FlateDecode")
{
if (predictor == 12)
{
diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc
index fa16f55d..8962624d 100644
--- a/libqpdf/QPDF_encryption.cc
+++ b/libqpdf/QPDF_encryption.cc
@@ -600,18 +600,19 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
encryption_method_e method = e_unknown;
std::string method_source = "/StmF from /Encrypt dictionary";
- // NOTE: the section in the PDF specification on crypt filters
- // seems to suggest that there might be a /Crypt key in
- // /DecodeParms whose value is a crypt filter (.e.g., << /Name
- // /StdCF >>), but implementation notes suggest this can only
- // happen for metadata streams, and emperical observation
- // suggests that they are otherwise ignored. Not having been
- // able to find a sample file that uses crypt filters in any
- // way other than /StrF and /StmF, I'm not really sure what to
- // do about this. If we were to override the encryption on a
- // per-stream basis using crypt filters, set method_source to
- // something useful in the error message for unknown
- // encryption methods (search for method_source).
+ if (stream_dict.getKey("/Filter").isOrHasName("/Crypt") &&
+ stream_dict.getKey("/DecodeParms").isDictionary())
+ {
+ QPDFObjectHandle decode_parms = stream_dict.getKey("/DecodeParms");
+ if (decode_parms.getKey("/Type").isName() &&
+ (decode_parms.getKey("/Type").getName() ==
+ "/CryptFilterDecodeParms"))
+ {
+ QTC::TC("qpdf", "QPDF_encryption stream crypt filter");
+ method = interpretCF(decode_parms.getKey("/Name"));
+ method_source = "stream's Crypt decode parameters";
+ }
+ }
if (method == e_unknown)
{
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index dd9ec5b1..6246e8e1 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -170,3 +170,4 @@ QPDFWriter forcing object stream disable 0
QPDFWriter forced version disabled encryption 0
qpdf-c called qpdf_set_r4_encryption_parameters 0
qpdf-c called qpdf_set_static_aes_IV 0
+QPDF_encryption stream crypt filter 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index f1f2cc53..0c05121b 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -1079,7 +1079,7 @@ $td->runtest("make sure there is no xref stream",
$td->NORMALIZE_NEWLINES);
# Look at some actual V4 files
-$n_tests += 8;
+$n_tests += 10;
foreach my $d (['--force-V4', 'V4'],
['--cleartext-metadata', 'V4-clearmeta'],
['--use-aes=y', 'V4-aes'],
@@ -1094,6 +1094,14 @@ foreach my $d (['--force-V4', 'V4'],
{$td->FILE => "a.pdf"},
{$td->FILE => "$out.pdf"});
}
+# Crypt Filter
+$td->runtest("decrypt with crypt filter",
+ {$td->COMMAND => "qpdf --decrypt --static-id" .
+ " metadata-crypt-filter.pdf a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("check output",
+ {$td->FILE => 'a.pdf'},
+ {$td->FILE => 'decrypted-crypt-filter.pdf'});
show_ntests();
# ----------
diff --git a/qpdf/qtest/qpdf/decrypted-crypt-filter.pdf b/qpdf/qtest/qpdf/decrypted-crypt-filter.pdf
new file mode 100644
index 00000000..75e7f788
--- /dev/null
+++ b/qpdf/qtest/qpdf/decrypted-crypt-filter.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdf/metadata-crypt-filter.pdf b/qpdf/qtest/qpdf/metadata-crypt-filter.pdf
new file mode 100644
index 00000000..39ed3d81
--- /dev/null
+++ b/qpdf/qtest/qpdf/metadata-crypt-filter.pdf
@@ -0,0 +1,411 @@
+%PDF-1.5
+%
+1 0 obj
+<< /Metadata 3 0 R /Outlines 4 0 R /PageLabels << /Nums [ 0 << /P () >> 2 << /S /r /St 1 >> 7 << /P () >> 9 << /S /r /St 6 >> 11 << /P () >> 12 << /S /D /St 2 >> 15 << /S /D /St 6 >> 19 << /P () >> 20 << /S /D /St 12 >> 22 << /S /D /St 16059 >> 23 << /S /r /St 50 >> 29 << /S /r /St 54 >> ] >> /PageMode /UseOutlines /Pages 5 0 R /Type /Catalog >>
+endobj
+2 0 obj
+<< /CreationDate <f8c3152b7dae7ddf2053e239403136310f29cba5913562> /ModDate <f8c3152b7dae7ddf2053e239403136310f29cba5913562> >>
+endobj
+3 0 obj
+<< /Subtype /XML /Type /Metadata /DecodeParms << /Name /Identity /Type /CryptFilterDecodeParms >> /Filter /Crypt /Length 770 >>
+stream
+<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d' bytes='770'?>
+
+<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
+ xmlns:iX='http://ns.adobe.com/iX/1.0/'>
+
+ <rdf:Description about=''
+ xmlns='http://ns.adobe.com/pdf/1.3/'
+ xmlns:pdf='http://ns.adobe.com/pdf/1.3/'>
+ <pdf:ModDate>2003-10-10T18:04:32-03:00</pdf:ModDate>
+ <pdf:CreationDate>2003-10-10T18:04:32-03:00</pdf:CreationDate>
+ </rdf:Description>
+
+ <rdf:Description about=''
+ xmlns='http://ns.adobe.com/xap/1.0/'
+ xmlns:xap='http://ns.adobe.com/xap/1.0/'>
+ <xap:ModifyDate>2003-10-10T18:04:32-03:00</xap:ModifyDate>
+ <xap:CreateDate>2003-10-10T18:04:32-03:00</xap:CreateDate>
+ <xap:MetadataDate>2003-10-10T18:04:32-03:00</xap:MetadataDate>
+ </rdf:Description>
+
+</rdf:RDF>
+<?xpacket end='r'?>endstream
+endobj
+4 0 obj
+<< /Count 6 /First 6 0 R /Last 7 0 R /Type /Outlines >>
+endobj
+5 0 obj
+<< /Count 30 /Kids [ 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R 23 0 R 24 0 R 25 0 R 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R 32 0 R 33 0 R 34 0 R 35 0 R 36 0 R 37 0 R ] /Type /Pages >>
+endobj
+6 0 obj
+<< /Count 4 /Dest [ 13 0 R /XYZ null null null ] /First 38 0 R /Last 39 0 R /Next 7 0 R /Parent 4 0 R /Title <0bace566042e35f13ccb00496b6552b92c0c4c87ca4a8cbe11761a3c9718c8c0> /Type /Outline >>
+endobj
+7 0 obj
+<< /Dest [ 23 0 R /XYZ 66 756 3 ] /Parent 4 0 R /Prev 6 0 R /Title <de6e91d54a014a73abf7fea3607575fd7f38e880456d41d9797c9978ad> /Type /Outline >>
+endobj
+8 0 obj
+<< /Contents 40 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+9 0 obj
+<< /Contents 43 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+10 0 obj
+<< /Contents 44 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+11 0 obj
+<< /Contents 45 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+12 0 obj
+<< /Contents 46 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+13 0 obj
+<< /Contents 47 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+14 0 obj
+<< /Contents 48 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+15 0 obj
+<< /Contents 49 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+16 0 obj
+<< /Contents 50 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+17 0 obj
+<< /Contents 51 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+18 0 obj
+<< /Contents 52 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+19 0 obj
+<< /Contents 53 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+20 0 obj
+<< /Contents 54 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+21 0 obj
+<< /Contents 55 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+22 0 obj
+<< /Contents 56 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+23 0 obj
+<< /Contents 57 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+24 0 obj
+<< /Contents 58 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+25 0 obj
+<< /Contents 59 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+26 0 obj
+<< /Contents 60 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+27 0 obj
+<< /Contents 61 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+28 0 obj
+<< /Contents 62 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+29 0 obj
+<< /Contents 63 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+30 0 obj
+<< /Contents 64 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+31 0 obj
+<< /Contents 65 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+32 0 obj
+<< /Contents 66 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+33 0 obj
+<< /Contents 67 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+34 0 obj
+<< /Contents 68 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+35 0 obj
+<< /Contents 69 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+36 0 obj
+<< /Contents 70 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+37 0 obj
+<< /Contents 71 0 R /CropBox [ 0 0 612 792 ] /MediaBox [ 0 0 612 792 ] /Parent 5 0 R /Resources << /Font << /F1 41 0 R >> /ProcSet 42 0 R >> /Rotate 0 /Type /Page >>
+endobj
+38 0 obj
+<< /Count -3 /Dest [ 19 0 R /Fit ] /First 72 0 R /Last 73 0 R /Next 39 0 R /Parent 6 0 R /Title <3fb30ac89234ff057e20814f60a034d2e5025f8cc58e> /Type /Outline >>
+endobj
+39 0 obj
+<< /Count 2 /Dest [ 21 0 R /FitH 792 ] /First 74 0 R /Last 75 0 R /Parent 6 0 R /Prev 38 0 R /Title <bf084bb6b3083e2d8a1c22e0388e67c14cc1cf0b7d176c49601b> /Type /Outline >>
+endobj
+40 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+ tv4R
+endobj
+41 0 obj
+<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
+endobj
+42 0 obj
+[ /PDF /Text ]
+endobj
+43 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+
+endobj
+44 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+ę|qsg:/IƸҐQ,V;Ukb{Ԝ,endstream
+endobj
+45 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+Cv=J@VޥI>Ht5y{7ݢK٪Py˨h_endstream
+endobj
+46 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+FKEnADov8 ,J;4J؇am"endstream
+endobj
+47 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+1'[1fi:l:S$GʮD1:]Ѩiendstream
+endobj
+48 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+2d#[ߑ)Oŵ j)^iNmOʢf}endstream
+endobj
+49 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+&;PG2fs@[Ԡy<Tsͳz!6NO><Yendstream
+endobj
+50 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+7ۥsIT!ݔ%ÞXjIdMVQ+{65fendstream
+endobj
+51 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+l∿q kO vѪ[F3D{CAp,endstream
+endobj
+52 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+bǕM+|f.Ѥ8|{o#-&t%ca|Tendstream
+endobj
+53 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+Nc&fFuy4e.X\X"Kp;E[hzKcbendstream
+endobj
+54 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+}s+8QH}zM >i|v&&|!endstream
+endobj
+55 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+&hyu8iҐ̈́qSQ #.P5)
+endobj
+56 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+X$Q$ B2.`e\tVw'q#E(~Yހd}endstream
+endobj
+57 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+_|Y9-n
+endobj
+58 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+_ZţH#!ެk39$/m?ڦl/Z/}@6@Vve7endstream
+endobj
+59 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+Fl+y'k`2orfY%1endstream
+endobj
+60 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+D%MXe=F( Iv_enҩVb! r!Iendstream
+endobj
+61 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+}
+endobj
+62 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+!Ӂ7aJ8c1[
+endobj
+63 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+nqbv0X:V|b毕hmG0۔<s Vyendstream
+endobj
+64 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+@UYX#`[sS?*f( HuhByendstream
+endobj
+65 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+dq[!r09 F)hBQcGS`E)6
+endobj
+66 0 obj
+<< /Length 50 /Filter /FlateDecode >>
+stream
+p*-$
+>v
+endobj
+67 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+WSX\,^Mʵ2A" p]>|/X,P3endstream
+endobj
+68 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+օU=MŢNSgϮݏX
+#߀}`*?h6Pss{Vendstream
+endobj
+69 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+!h
+endobj
+70 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+7ZSL0=ƻ./
+|:&_! s*u#endstream
+endobj
+71 0 obj
+<< /Length 51 /Filter /FlateDecode >>
+stream
+P+@Y( {?g]lvR9UŒ?-wOendstream
+endobj
+72 0 obj
+<< /Count -2 /Dest [ 20 0 R /FitV 100 ] /First 76 0 R /Last 77 0 R /Next 73 0 R /Parent 38 0 R /Title <ce776528865f1181cf50312ccedc07021f8affe67476df8184f127c9fc8dbc> /Type /Outline >>
+endobj
+73 0 obj
+<< /Count 1 /Dest [ 20 0 R /XYZ null null null ] /First 78 0 R /Last 78 0 R /Parent 38 0 R /Prev 72 0 R /Title (輧:8\226v\)N\(\210\035NT\036mvj\tnl\212;o.\2113) /Type /Outline >>
+endobj
+74 0 obj
+<< /Dest [ 9 0 R /FitR 66 714 180 770 ] /Next 75 0 R /Parent 39 0 R /Title <498fe6ebfb28be416edddb53c1a63ffee3887fce2a7a2e34043792493f5a7c1f8818fa24a81dbbd055212dae> /Type /Outline >>
+endobj
+75 0 obj
+<< /Dest [ 8 0 R /XYZ null null null ] /Parent 39 0 R /Prev 74 0 R /Title <69fb82b1b1b8833e343e5f401879d3083e0cd738a3f54342e881ead5b6bc1816e7e3b431d48b1c0a14> /Type /Outline >>
+endobj
+76 0 obj
+<< /Dest [ 26 0 R /XYZ null null null ] /Next 77 0 R /Parent 72 0 R /Title <1433a18038fcd41d81200f85f0f942caedcce35a9fddde851dd1b70def5f196aeac27ccf5f5b725ecc89be> /Type /Outline >>
+endobj
+77 0 obj
+<< /Dest [ 27 0 R /XYZ null null null ] /Parent 72 0 R /Prev 76 0 R /Title <9028484736aaf8f0b5eedc521a7169cc9e2295cfd80eed0c2e41c44c26ba7c6ff586a290be701394f7e5ad> /Type /Outline >>
+endobj
+78 0 obj
+<< /Dest [ 30 0 R /XYZ null null null ] /Parent 73 0 R /Title <6c21f1d776e7e20cadb7be7247c9856e4da1fbaded20b1596cc68c35e8c7f5c2ebd4a242796ea858837daa> /Type /Outline >>
+endobj
+79 0 obj
+<< /CF << /StdCF << /AuthEvent /DocOpen /CFM /V2 >> >> /EncryptMetadata false /Filter /Standard /Length 128 /O <566fa873ee33c797cd3b904fdadf814afa34df9a38f6ed41b984e2c6da2aa6f5> /P -4 /R 4 /StmF /StdCF /StrF /StdCF /U <3a40816f776fccd39a9c505a9d4110e60122456a91bae5134273a6db134c87c4> /V 4 >>
+endobj
+xref
+0 80
+0000000000 65535 f
+0000000015 00000 n
+0000000378 00000 n
+0000000520 00000 n
+0000001450 00000 n
+0000001521 00000 n
+0000001783 00000 n
+0000001992 00000 n
+0000002153 00000 n
+0000002334 00000 n
+0000002515 00000 n
+0000002697 00000 n
+0000002879 00000 n
+0000003061 00000 n
+0000003243 00000 n
+0000003425 00000 n
+0000003607 00000 n
+0000003789 00000 n
+0000003971 00000 n
+0000004153 00000 n
+0000004335 00000 n
+0000004517 00000 n
+0000004699 00000 n
+0000004881 00000 n
+0000005063 00000 n
+0000005245 00000 n
+0000005427 00000 n
+0000005609 00000 n
+0000005791 00000 n
+0000005973 00000 n
+0000006155 00000 n
+0000006337 00000 n
+0000006519 00000 n
+0000006701 00000 n
+0000006883 00000 n
+0000007065 00000 n
+0000007247 00000 n
+0000007429 00000 n
+0000007611 00000 n
+0000007788 00000 n
+0000007977 00000 n
+0000008098 00000 n
+0000008206 00000 n
+0000008237 00000 n
+0000008358 00000 n
+0000008479 00000 n
+0000008600 00000 n
+0000008721 00000 n
+0000008842 00000 n
+0000008963 00000 n
+0000009084 00000 n
+0000009205 00000 n
+0000009326 00000 n
+0000009448 00000 n
+0000009570 00000 n
+0000009692 00000 n
+0000009814 00000 n
+0000009936 00000 n
+0000010058 00000 n
+0000010180 00000 n
+0000010302 00000 n
+0000010424 00000 n
+0000010546 00000 n
+0000010668 00000 n
+0000010790 00000 n
+0000010912 00000 n
+0000011034 00000 n
+0000011155 00000 n
+0000011277 00000 n
+0000011399 00000 n
+0000011521 00000 n
+0000011643 00000 n
+0000011765 00000 n
+0000011966 00000 n
+0000012176 00000 n
+0000012376 00000 n
+0000012569 00000 n
+0000012767 00000 n
+0000012965 00000 n
+0000013150 00000 n
+trailer << /Info 2 0 R /Root 1 0 R /Size 80 /ID [<66d36a30a97e0f16f39955c6221e0c2a><31415926535897932384626433832795>] /Encrypt 79 0 R >>
+startxref
+13459
+%%EOF