origami-docspring 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/examples/attachments/attachment.rb +7 -8
- data/examples/attachments/nested_document.rb +6 -5
- data/examples/encryption/encryption.rb +5 -4
- data/examples/events/events.rb +7 -6
- data/examples/flash/flash.rb +10 -9
- data/examples/forms/javascript.rb +14 -13
- data/examples/forms/xfa.rb +67 -66
- data/examples/javascript/hello_world.rb +6 -5
- data/examples/javascript/js_emulation.rb +26 -26
- data/examples/loop/goto.rb +12 -11
- data/examples/loop/named.rb +17 -16
- data/examples/signature/signature.rb +11 -11
- data/examples/uri/javascript.rb +25 -24
- data/examples/uri/open-uri.rb +5 -4
- data/examples/uri/submitform.rb +11 -10
- data/lib/origami/3d.rb +330 -334
- data/lib/origami/acroform.rb +267 -268
- data/lib/origami/actions.rb +266 -278
- data/lib/origami/annotations.rb +659 -670
- data/lib/origami/array.rb +192 -196
- data/lib/origami/boolean.rb +66 -70
- data/lib/origami/catalog.rb +360 -363
- data/lib/origami/collections.rb +132 -133
- data/lib/origami/compound.rb +125 -129
- data/lib/origami/destinations.rb +226 -237
- data/lib/origami/dictionary.rb +155 -154
- data/lib/origami/encryption.rb +967 -923
- data/lib/origami/extensions/fdf.rb +270 -275
- data/lib/origami/extensions/ppklite.rb +323 -328
- data/lib/origami/filespec.rb +170 -173
- data/lib/origami/filters/ascii.rb +162 -167
- data/lib/origami/filters/ccitt/tables.rb +248 -252
- data/lib/origami/filters/ccitt.rb +309 -312
- data/lib/origami/filters/crypt.rb +31 -34
- data/lib/origami/filters/dct.rb +47 -50
- data/lib/origami/filters/flate.rb +57 -60
- data/lib/origami/filters/jbig2.rb +50 -53
- data/lib/origami/filters/jpx.rb +40 -43
- data/lib/origami/filters/lzw.rb +151 -155
- data/lib/origami/filters/predictors.rb +250 -255
- data/lib/origami/filters/runlength.rb +111 -115
- data/lib/origami/filters.rb +319 -325
- data/lib/origami/font.rb +173 -177
- data/lib/origami/functions.rb +62 -66
- data/lib/origami/graphics/colors.rb +203 -208
- data/lib/origami/graphics/instruction.rb +79 -81
- data/lib/origami/graphics/path.rb +141 -144
- data/lib/origami/graphics/patterns.rb +156 -160
- data/lib/origami/graphics/render.rb +51 -47
- data/lib/origami/graphics/state.rb +144 -142
- data/lib/origami/graphics/text.rb +185 -188
- data/lib/origami/graphics/xobject.rb +818 -804
- data/lib/origami/graphics.rb +25 -26
- data/lib/origami/header.rb +63 -65
- data/lib/origami/javascript.rb +718 -651
- data/lib/origami/linearization.rb +284 -285
- data/lib/origami/metadata.rb +156 -135
- data/lib/origami/name.rb +98 -100
- data/lib/origami/null.rb +49 -51
- data/lib/origami/numeric.rb +133 -135
- data/lib/origami/obfuscation.rb +180 -182
- data/lib/origami/object.rb +634 -631
- data/lib/origami/optionalcontent.rb +147 -149
- data/lib/origami/outline.rb +46 -48
- data/lib/origami/outputintents.rb +76 -77
- data/lib/origami/page.rb +637 -596
- data/lib/origami/parser.rb +214 -221
- data/lib/origami/parsers/fdf.rb +44 -45
- data/lib/origami/parsers/pdf/lazy.rb +147 -154
- data/lib/origami/parsers/pdf/linear.rb +104 -109
- data/lib/origami/parsers/pdf.rb +109 -107
- data/lib/origami/parsers/ppklite.rb +44 -46
- data/lib/origami/pdf.rb +886 -896
- data/lib/origami/reference.rb +116 -120
- data/lib/origami/signature.rb +617 -625
- data/lib/origami/stream.rb +560 -558
- data/lib/origami/string.rb +366 -368
- data/lib/origami/template/patterns.rb +50 -52
- data/lib/origami/template/widgets.rb +111 -114
- data/lib/origami/trailer.rb +153 -157
- data/lib/origami/tree.rb +55 -57
- data/lib/origami/version.rb +19 -19
- data/lib/origami/webcapture.rb +87 -90
- data/lib/origami/xfa/config.rb +409 -414
- data/lib/origami/xfa/connectionset.rb +113 -117
- data/lib/origami/xfa/datasets.rb +38 -42
- data/lib/origami/xfa/localeset.rb +33 -37
- data/lib/origami/xfa/package.rb +49 -52
- data/lib/origami/xfa/pdf.rb +54 -59
- data/lib/origami/xfa/signature.rb +33 -37
- data/lib/origami/xfa/sourceset.rb +34 -38
- data/lib/origami/xfa/stylesheet.rb +35 -39
- data/lib/origami/xfa/template.rb +1630 -1634
- data/lib/origami/xfa/xdc.rb +33 -37
- data/lib/origami/xfa/xfa.rb +132 -123
- data/lib/origami/xfa/xfdf.rb +34 -38
- data/lib/origami/xfa/xmpmeta.rb +34 -38
- data/lib/origami/xfa.rb +50 -53
- data/lib/origami/xreftable.rb +462 -462
- data/lib/origami.rb +37 -38
- data/test/test_actions.rb +22 -20
- data/test/test_annotations.rb +54 -52
- data/test/test_forms.rb +23 -21
- data/test/test_native_types.rb +82 -78
- data/test/test_object_tree.rb +25 -24
- data/test/test_pages.rb +43 -41
- data/test/test_pdf.rb +2 -0
- data/test/test_pdf_attachment.rb +23 -21
- data/test/test_pdf_create.rb +16 -15
- data/test/test_pdf_encrypt.rb +69 -66
- data/test/test_pdf_parse.rb +131 -129
- data/test/test_pdf_parse_lazy.rb +53 -53
- data/test/test_pdf_sign.rb +67 -67
- data/test/test_streams.rb +145 -143
- data/test/test_xrefs.rb +46 -45
- metadata +64 -8
data/test/test_pdf_sign.rb
CHANGED
@@ -1,97 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'minitest/autorun'
|
2
4
|
require 'stringio'
|
3
5
|
require 'openssl'
|
4
6
|
|
5
7
|
class TestSign < Minitest::Test
|
8
|
+
def create_self_signed_ca_certificate(key_size, expires)
|
9
|
+
key = OpenSSL::PKey::RSA.new key_size
|
6
10
|
|
7
|
-
|
8
|
-
key = OpenSSL::PKey::RSA.new key_size
|
9
|
-
|
10
|
-
name = OpenSSL::X509::Name.parse 'CN=origami/DC=example'
|
11
|
+
name = OpenSSL::X509::Name.parse 'CN=origami/DC=example'
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
cert = OpenSSL::X509::Certificate.new
|
14
|
+
cert.version = 2
|
15
|
+
cert.serial = 0
|
16
|
+
cert.not_before = Time.now
|
17
|
+
cert.not_after = Time.now + expires
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
cert.public_key = key.public_key
|
20
|
+
cert.subject = name
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
extension_factory = OpenSSL::X509::ExtensionFactory.new
|
23
|
+
extension_factory.issuer_certificate = cert
|
24
|
+
extension_factory.subject_certificate = cert
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
cert.add_extension extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
|
27
|
+
cert.add_extension extension_factory.create_extension('keyUsage', 'digitalSignature,keyCertSign')
|
28
|
+
cert.add_extension extension_factory.create_extension('subjectKeyIdentifier', 'hash')
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
cert.issuer = name
|
31
|
+
cert.sign key, OpenSSL::Digest.new('SHA256')
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def setup
|
36
|
-
@cert, @key = create_self_signed_ca_certificate(1024, 3600)
|
37
|
-
@other_cert, @other_key = create_self_signed_ca_certificate(1024, 3600)
|
38
|
-
end
|
33
|
+
[cert, key]
|
34
|
+
end
|
39
35
|
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
def setup
|
37
|
+
@cert, @key = create_self_signed_ca_certificate(1024, 3600)
|
38
|
+
@other_cert, @other_key = create_self_signed_ca_certificate(1024, 3600)
|
39
|
+
end
|
43
40
|
|
44
|
-
|
45
|
-
|
41
|
+
def setup_document_with_annotation
|
42
|
+
document = PDF.read(File.join(__dir__, "dataset/calc.pdf"),
|
43
|
+
ignore_errors: false, verbosity: Parser::VERBOSE_QUIET)
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
45
|
+
annotation = Annotation::Widget::Signature.new.set_indirect(true)
|
46
|
+
annotation.Rect = Rectangle[llx: 89.0, lly: 386.0, urx: 190.0, ury: 353.0]
|
50
47
|
|
51
|
-
|
48
|
+
document.append_page do |page|
|
49
|
+
page.add_annotation(annotation)
|
52
50
|
end
|
53
51
|
|
54
|
-
|
55
|
-
|
52
|
+
[document, annotation]
|
53
|
+
end
|
56
54
|
|
57
|
-
|
58
|
-
|
59
|
-
annotation: annotation,
|
60
|
-
issuer: "Guillaume Delugré",
|
61
|
-
location: "France",
|
62
|
-
contact: "origami@localhost",
|
63
|
-
reason: "Example"
|
64
|
-
)
|
55
|
+
def sign_document_with_method(method)
|
56
|
+
document, annotation = setup_document_with_annotation
|
65
57
|
|
66
|
-
|
67
|
-
|
58
|
+
document.sign(@cert, @key,
|
59
|
+
method: method,
|
60
|
+
annotation: annotation,
|
61
|
+
issuer: "Guillaume Delugré",
|
62
|
+
location: "France",
|
63
|
+
contact: "origami@localhost",
|
64
|
+
reason: "Example")
|
68
65
|
|
69
|
-
|
70
|
-
|
66
|
+
assert document.frozen?
|
67
|
+
assert document.signed?
|
71
68
|
|
72
|
-
|
69
|
+
output = StringIO.new
|
70
|
+
document.save(output)
|
73
71
|
|
74
|
-
|
75
|
-
assert document.verify(allow_self_signed: true)
|
76
|
-
assert document.verify(trusted_certs: [@cert])
|
77
|
-
refute document.verify(trusted_certs: [@other_cert])
|
72
|
+
document = PDF.read(output.reopen(output.string, 'r'), verbosity: Parser::VERBOSE_QUIET)
|
78
73
|
|
79
|
-
|
80
|
-
|
81
|
-
|
74
|
+
refute document.verify
|
75
|
+
assert document.verify(allow_self_signed: true)
|
76
|
+
assert document.verify(trusted_certs: [@cert])
|
77
|
+
refute document.verify(trusted_certs: [@other_cert])
|
82
78
|
|
83
|
-
|
79
|
+
result = document.verify do |ctx|
|
80
|
+
ctx.error == OpenSSL::X509::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT and ctx.current_cert.to_pem == @cert.to_pem
|
84
81
|
end
|
85
82
|
|
86
|
-
|
87
|
-
|
88
|
-
end
|
83
|
+
assert result
|
84
|
+
end
|
89
85
|
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
def test_sign_pkcs7_sha1
|
87
|
+
sign_document_with_method(Signature::PKCS7_SHA1)
|
88
|
+
end
|
93
89
|
|
94
|
-
|
95
|
-
|
96
|
-
|
90
|
+
def test_sign_pkcs7_detached
|
91
|
+
sign_document_with_method(Signature::PKCS7_DETACHED)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_sign_x509_sha1
|
95
|
+
sign_document_with_method(Signature::PKCS1_RSA_SHA1)
|
96
|
+
end
|
97
97
|
end
|
data/test/test_streams.rb
CHANGED
@@ -1,184 +1,186 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'minitest/autorun'
|
2
4
|
require 'stringio'
|
3
5
|
|
4
6
|
class TestStreams < Minitest::Test
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def setup
|
8
|
+
@target = PDF.new
|
9
|
+
@output = StringIO.new
|
10
|
+
@data = "0123456789" * 1024
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_predictors
|
14
|
+
stm = Stream.new(@data, Filter: :FlateDecode)
|
15
|
+
stm.set_predictor(Filter::Predictor::TIFF)
|
16
|
+
raw = stm.encoded_data
|
17
|
+
stm.data = nil
|
18
|
+
stm.encoded_data = raw
|
19
|
+
|
20
|
+
assert_equal @data, stm.data
|
21
|
+
|
22
|
+
stm = Stream.new(@data, Filter: :FlateDecode)
|
23
|
+
stm.set_predictor(Filter::Predictor::PNG_SUB)
|
24
|
+
raw = stm.encoded_data
|
25
|
+
stm.data = nil
|
26
|
+
stm.encoded_data = raw
|
27
|
+
|
28
|
+
assert_equal @data, stm.data
|
29
|
+
|
30
|
+
stm = Stream.new(@data, Filter: :FlateDecode)
|
31
|
+
stm.set_predictor(Filter::Predictor::PNG_UP)
|
32
|
+
raw = stm.encoded_data
|
33
|
+
stm.data = nil
|
34
|
+
stm.encoded_data = raw
|
35
|
+
|
36
|
+
assert_equal stm.data, @data
|
37
|
+
|
38
|
+
stm = Stream.new(@data, Filter: :FlateDecode)
|
39
|
+
stm.set_predictor(Filter::Predictor::PNG_AVERAGE)
|
40
|
+
raw = stm.encoded_data
|
41
|
+
stm.data = nil
|
42
|
+
stm.encoded_data = raw
|
43
|
+
|
44
|
+
assert_equal stm.data, @data
|
45
|
+
|
46
|
+
stm = Stream.new(@data, Filter: :FlateDecode)
|
47
|
+
stm.set_predictor(Filter::Predictor::PNG_PAETH)
|
48
|
+
raw = stm.encoded_data
|
49
|
+
stm.data = nil
|
50
|
+
stm.encoded_data = raw
|
51
|
+
|
52
|
+
assert_equal stm.data, @data
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_filter_flate
|
56
|
+
stm = Stream.new(@data, Filter: :FlateDecode)
|
57
|
+
raw = stm.encoded_data
|
58
|
+
stm.data = nil
|
59
|
+
stm.encoded_data = raw
|
60
|
+
|
61
|
+
assert_equal stm.data, @data
|
62
|
+
|
63
|
+
assert_equal Filter::Flate.decode(Filter::Flate.encode("")), ""
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_filter_asciihex
|
67
|
+
stm = Stream.new(@data, Filter: :ASCIIHexDecode)
|
68
|
+
raw = stm.encoded_data
|
69
|
+
stm.data = nil
|
70
|
+
stm.encoded_data = raw
|
71
|
+
|
72
|
+
assert_equal stm.data, @data
|
73
|
+
|
74
|
+
assert_raises(Filter::InvalidASCIIHexStringError) do
|
75
|
+
Filter::ASCIIHex.decode("123456789ABCDEFGHIJKL")
|
9
76
|
end
|
10
77
|
|
11
|
-
|
12
|
-
|
13
|
-
stm.set_predictor(Filter::Predictor::TIFF)
|
14
|
-
raw = stm.encoded_data
|
15
|
-
stm.data = nil
|
16
|
-
stm.encoded_data = raw
|
17
|
-
|
18
|
-
assert_equal @data, stm.data
|
19
|
-
|
20
|
-
stm = Stream.new(@data, :Filter => :FlateDecode)
|
21
|
-
stm.set_predictor(Filter::Predictor::PNG_SUB)
|
22
|
-
raw = stm.encoded_data
|
23
|
-
stm.data = nil
|
24
|
-
stm.encoded_data = raw
|
25
|
-
|
26
|
-
assert_equal @data, stm.data
|
27
|
-
|
28
|
-
stm = Stream.new(@data, :Filter => :FlateDecode)
|
29
|
-
stm.set_predictor(Filter::Predictor::PNG_UP)
|
30
|
-
raw = stm.encoded_data
|
31
|
-
stm.data = nil
|
32
|
-
stm.encoded_data = raw
|
33
|
-
|
34
|
-
assert_equal stm.data, @data
|
78
|
+
assert_equal Filter::ASCIIHex.decode(Filter::ASCIIHex.encode("")), ""
|
79
|
+
end
|
35
80
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
81
|
+
def test_filter_ascii85
|
82
|
+
stm = Stream.new(@data, Filter: :ASCII85Decode)
|
83
|
+
raw = stm.encoded_data
|
84
|
+
stm.data = nil
|
85
|
+
stm.encoded_data = raw
|
41
86
|
|
42
|
-
|
87
|
+
assert_equal stm.data, @data
|
43
88
|
|
44
|
-
|
45
|
-
|
46
|
-
raw = stm.encoded_data
|
47
|
-
stm.data = nil
|
48
|
-
stm.encoded_data = raw
|
49
|
-
|
50
|
-
assert_equal stm.data, @data
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_filter_flate
|
54
|
-
stm = Stream.new(@data, :Filter => :FlateDecode)
|
55
|
-
raw = stm.encoded_data
|
56
|
-
stm.data = nil
|
57
|
-
stm.encoded_data = raw
|
58
|
-
|
59
|
-
assert_equal stm.data, @data
|
60
|
-
|
61
|
-
assert_equal Filter::Flate.decode(Filter::Flate.encode("")), ""
|
89
|
+
assert_raises(Filter::InvalidASCII85StringError) do
|
90
|
+
Filter::ASCII85.decode("ABCD\x01")
|
62
91
|
end
|
63
92
|
|
64
|
-
|
65
|
-
|
66
|
-
raw = stm.encoded_data
|
67
|
-
stm.data = nil
|
68
|
-
stm.encoded_data = raw
|
93
|
+
assert_equal Filter::ASCII85.decode(Filter::ASCII85.encode("")), ""
|
94
|
+
end
|
69
95
|
|
70
|
-
|
96
|
+
def test_filter_rle
|
97
|
+
stm = Stream.new(@data, Filter: :RunLengthDecode)
|
98
|
+
raw = stm.encoded_data
|
99
|
+
stm.data = nil
|
100
|
+
stm.encoded_data = raw
|
71
101
|
|
72
|
-
|
73
|
-
Filter::ASCIIHex.decode("123456789ABCDEFGHIJKL")
|
74
|
-
end
|
102
|
+
assert_equal stm.data, @data
|
75
103
|
|
76
|
-
|
104
|
+
assert_raises(Filter::InvalidRunLengthDataError) do
|
105
|
+
Filter::RunLength.decode("\x7f")
|
77
106
|
end
|
78
107
|
|
79
|
-
|
80
|
-
|
81
|
-
raw = stm.encoded_data
|
82
|
-
stm.data = nil
|
83
|
-
stm.encoded_data = raw
|
108
|
+
assert_equal Filter::RunLength.decode(Filter::RunLength.encode("")), ""
|
109
|
+
end
|
84
110
|
|
85
|
-
|
111
|
+
def test_filter_lzw
|
112
|
+
stm = Stream.new(@data, Filter: :LZWDecode)
|
113
|
+
raw = stm.encoded_data
|
114
|
+
stm.data = nil
|
115
|
+
stm.encoded_data = raw
|
86
116
|
|
87
|
-
|
88
|
-
Filter::ASCII85.decode("ABCD\x01")
|
89
|
-
end
|
117
|
+
assert_equal stm.data, @data
|
90
118
|
|
91
|
-
|
119
|
+
assert_raises(Filter::InvalidLZWDataError) do
|
120
|
+
Filter::LZW.decode("abcd")
|
92
121
|
end
|
93
122
|
|
94
|
-
|
95
|
-
|
96
|
-
raw = stm.encoded_data
|
97
|
-
stm.data = nil
|
98
|
-
stm.encoded_data = raw
|
123
|
+
assert_equal Filter::LZW.decode(Filter::LZW.encode("")), ""
|
124
|
+
end
|
99
125
|
|
100
|
-
|
126
|
+
def test_filter_ccittfax
|
127
|
+
stm = Stream.new(@data[0, 216], Filter: :CCITTFaxDecode)
|
101
128
|
|
102
|
-
|
103
|
-
|
104
|
-
|
129
|
+
raw = stm.encoded_data
|
130
|
+
stm.data = nil
|
131
|
+
stm.encoded_data = raw
|
105
132
|
|
106
|
-
|
107
|
-
end
|
133
|
+
assert_equal stm.data, @data[0, 216]
|
108
134
|
|
109
|
-
|
110
|
-
|
111
|
-
raw = stm.encoded_data
|
112
|
-
stm.data = nil
|
113
|
-
stm.encoded_data = raw
|
114
|
-
|
115
|
-
assert_equal stm.data, @data
|
116
|
-
|
117
|
-
assert_raises(Filter::InvalidLZWDataError) do
|
118
|
-
Filter::LZW.decode("abcd")
|
119
|
-
end
|
120
|
-
|
121
|
-
assert_equal Filter::LZW.decode(Filter::LZW.encode("")), ""
|
135
|
+
assert_raises(Filter::InvalidCCITTFaxDataError) do
|
136
|
+
Filter::CCITTFax.decode("abcd")
|
122
137
|
end
|
123
138
|
|
124
|
-
|
125
|
-
|
139
|
+
assert_equal Filter::CCITTFax.decode(Filter::CCITTFax.encode("")), ""
|
140
|
+
end
|
126
141
|
|
127
|
-
|
128
|
-
|
129
|
-
stm.encoded_data = raw
|
142
|
+
def test_stream
|
143
|
+
chain = %i[FlateDecode LZWDecode ASCIIHexDecode]
|
130
144
|
|
131
|
-
|
145
|
+
stm = Stream.new(@data, Filter: chain)
|
146
|
+
@target << stm
|
147
|
+
@target.save(@output)
|
132
148
|
|
133
|
-
|
134
|
-
|
135
|
-
|
149
|
+
assert stm.Length == stm.encoded_data.length
|
150
|
+
assert_equal stm.filters, chain
|
151
|
+
assert_equal stm.data, @data
|
152
|
+
end
|
136
153
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
def test_stream
|
141
|
-
chain = %i[FlateDecode LZWDecode ASCIIHexDecode]
|
154
|
+
def test_object_stream
|
155
|
+
objstm = ObjectStream.new
|
156
|
+
objstm.Filter = %i[FlateDecode ASCIIHexDecode RunLengthDecode]
|
142
157
|
|
143
|
-
|
144
|
-
@target << stm
|
145
|
-
@target.save(@output)
|
158
|
+
@target << objstm
|
146
159
|
|
147
|
-
|
148
|
-
|
149
|
-
assert_equal stm.data, @data
|
160
|
+
assert_raises(InvalidObjectError) do
|
161
|
+
objstm.insert Stream.new
|
150
162
|
end
|
151
163
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
@target << objstm
|
157
|
-
|
158
|
-
assert_raises(InvalidObjectError) do
|
159
|
-
objstm.insert Stream.new
|
160
|
-
end
|
161
|
-
|
162
|
-
3.times do
|
163
|
-
objstm.insert HexaString.new(@data)
|
164
|
-
end
|
164
|
+
3.times do
|
165
|
+
objstm.insert HexaString.new(@data)
|
166
|
+
end
|
165
167
|
|
166
|
-
|
168
|
+
assert_equal objstm.objects.size, 3
|
167
169
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
170
|
+
objstm.each_object do |object|
|
171
|
+
assert_instance_of HexaString, object
|
172
|
+
assert_equal object.parent, objstm
|
173
|
+
assert objstm.include?(object.no)
|
174
|
+
assert_equal objstm.extract(object.no), object
|
175
|
+
assert_equal objstm.extract_by_index(objstm.index(object.no)), object
|
176
|
+
end
|
175
177
|
|
176
|
-
|
177
|
-
|
178
|
+
objstm.delete(objstm.objects.first.no)
|
179
|
+
assert_equal objstm.objects.size, 2
|
178
180
|
|
179
|
-
|
181
|
+
@target.save(@output)
|
180
182
|
|
181
|
-
|
182
|
-
|
183
|
-
|
183
|
+
assert_instance_of Origami::Integer, objstm.N
|
184
|
+
assert_equal objstm.N, objstm.objects.size
|
185
|
+
end
|
184
186
|
end
|
data/test/test_xrefs.rb
CHANGED
@@ -1,67 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'minitest/autorun'
|
2
4
|
require 'stringio'
|
3
5
|
require 'strscan'
|
4
6
|
|
5
|
-
class TestXrefs <
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
class TestXrefs < Minitest::Test
|
8
|
+
def setup
|
9
|
+
@target = PDF.new
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
def test_xreftable
|
13
|
+
output = StringIO.new
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
@target.save(output)
|
16
|
+
output.reopen(output.string, 'r')
|
16
17
|
|
17
|
-
|
18
|
+
pdf = PDF.read(output, verbosity: Parser::VERBOSE_QUIET, ignore_errors: false)
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
xreftable = pdf.revisions.last.xreftable
|
21
|
+
assert_instance_of XRef::Section, xreftable
|
21
22
|
|
22
|
-
|
23
|
-
|
23
|
+
pdf.root_objects.each do |object|
|
24
|
+
xref = xreftable.find(object.no)
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
assert_instance_of XRef, xref
|
27
|
+
assert xref.used?
|
27
28
|
|
28
|
-
|
29
|
-
end
|
29
|
+
assert_equal xref.offset, object.file_offset
|
30
30
|
end
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def test_xrefstream
|
34
|
+
output = StringIO.new
|
35
|
+
objstm = ObjectStream.new
|
36
|
+
objstm.Filter = :FlateDecode
|
36
37
|
|
37
|
-
|
38
|
+
@target.insert objstm
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@target.save(output)
|
44
|
-
output = output.reopen(output.string, 'r')
|
40
|
+
3.times do
|
41
|
+
objstm.insert Null.new
|
42
|
+
end
|
45
43
|
|
46
|
-
|
47
|
-
|
44
|
+
@target.save(output)
|
45
|
+
output = output.reopen(output.string, 'r')
|
48
46
|
|
49
|
-
|
50
|
-
|
47
|
+
pdf = PDF.read(output, verbosity: Parser::VERBOSE_QUIET, ignore_errors: false)
|
48
|
+
xrefstm = pdf.revisions.last.xrefstm
|
51
49
|
|
52
|
-
|
53
|
-
|
50
|
+
assert_instance_of XRefStream, xrefstm
|
51
|
+
assert xrefstm.entries.all? { |xref| xref.is_a?(XRef) or xref.is_a?(XRefToCompressedObject) }
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
assert_equal xref.objstmno, object.parent.no
|
58
|
-
assert_equal xref.index, object.parent.index(object.no)
|
59
|
-
else
|
60
|
-
assert_instance_of XRef, xref
|
61
|
-
assert_equal xref.offset, object.file_offset
|
62
|
-
end
|
63
|
-
end
|
53
|
+
pdf.each_object(compressed: true) do |object|
|
54
|
+
xref = xrefstm.find(object.no)
|
64
55
|
|
65
|
-
|
56
|
+
if object.parent.is_a?(ObjectStream)
|
57
|
+
assert_instance_of XRefToCompressedObject, xref
|
58
|
+
assert_equal xref.objstmno, object.parent.no
|
59
|
+
assert_equal xref.index, object.parent.index(object.no)
|
60
|
+
else
|
61
|
+
assert_instance_of XRef, xref
|
62
|
+
assert_equal xref.offset, object.file_offset
|
63
|
+
end
|
66
64
|
end
|
65
|
+
|
66
|
+
assert_instance_of Catalog, xrefstm.Root
|
67
|
+
end
|
67
68
|
end
|