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/lib/origami/obfuscation.rb
CHANGED
@@ -1,245 +1,243 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# This file is part of Origami, PDF manipulation framework for Ruby
|
5
|
+
# Copyright (C) 2016 Guillaume Delugré.
|
6
|
+
#
|
7
|
+
# Origami is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# Origami is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Lesser General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
18
|
+
# along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
20
|
|
21
21
|
module Origami
|
22
|
+
module Obfuscator
|
23
|
+
using TypeConversion
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
MAX_INT = 0xFFFFFFFF
|
29
|
-
PRINTABLE = ("!".."9").to_a + (':'..'Z').to_a + ('['..'z').to_a + ('{'..'~').to_a
|
30
|
-
FILTERS = [ :FlateDecode, :RunLengthDecode, :LZWDecode, :ASCIIHexDecode, :ASCII85Decode ]
|
25
|
+
WHITECHARS = [" ", "\t", "\r", "\n", "\0"]
|
26
|
+
OBJECTS = [Array, Boolean, Dictionary, Integer, Name, Null, Stream, String, Real, Reference]
|
27
|
+
MAX_INT = 0xFFFFFFFF
|
28
|
+
PRINTABLE = ("!".."9").to_a + (':'..'Z').to_a + ('['..'z').to_a + ('{'..'~').to_a
|
29
|
+
FILTERS = [:FlateDecode, :RunLengthDecode, :LZWDecode, :ASCIIHexDecode, :ASCII85Decode]
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
::Array.new(length) { WHITECHARS[rand(WHITECHARS.size)] }.join
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.junk_comment(max_size = 15)
|
39
|
-
length = rand(max_size) + 1
|
40
|
-
|
41
|
-
junk_comment = ::Array.new(length) {
|
42
|
-
byte = rand(256).chr until (not byte.nil? and byte != "\n" and byte != "\r"); byte
|
43
|
-
}.join
|
44
|
-
|
45
|
-
"%#{junk_comment}#{$/}"
|
46
|
-
end
|
31
|
+
def self.junk_spaces(max_size = 3)
|
32
|
+
length = rand(max_size) + 1
|
47
33
|
|
48
|
-
|
49
|
-
|
50
|
-
type = OBJECTS[rand(OBJECTS.size)]
|
51
|
-
end
|
34
|
+
::Array.new(length) { WHITECHARS[rand(WHITECHARS.size)] }.join
|
35
|
+
end
|
52
36
|
|
53
|
-
|
54
|
-
|
55
|
-
end
|
37
|
+
def self.junk_comment(max_size = 15)
|
38
|
+
length = rand(max_size) + 1
|
56
39
|
|
57
|
-
|
58
|
-
|
40
|
+
junk_comment = ::Array.new(length) {
|
41
|
+
byte = rand(256).chr until !byte.nil? && (byte != "\n") && (byte != "\r")
|
42
|
+
byte
|
43
|
+
}.join
|
59
44
|
|
60
|
-
|
61
|
-
|
45
|
+
"%#{junk_comment}#{$/}"
|
46
|
+
end
|
62
47
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
48
|
+
def self.junk_object(type = nil)
|
49
|
+
if type.nil?
|
50
|
+
type = OBJECTS[rand(OBJECTS.size)]
|
51
|
+
end
|
67
52
|
|
68
|
-
|
69
|
-
|
70
|
-
|
53
|
+
unless type.include?(Origami::Object)
|
54
|
+
raise TypeError, "Not a valid object type"
|
55
|
+
end
|
71
56
|
|
72
|
-
|
73
|
-
|
57
|
+
Obfuscator.send("junk_#{type.to_s.split("::").last.downcase}")
|
58
|
+
end
|
74
59
|
|
75
|
-
|
76
|
-
|
77
|
-
obj = Obfuscator.junk_object
|
78
|
-
hash[Obfuscator.junk_name] = obj unless obj.is_a?(Stream)
|
79
|
-
end
|
60
|
+
def self.junk_array(max_size = 5)
|
61
|
+
length = rand(max_size) + 1
|
80
62
|
|
81
|
-
|
82
|
-
|
63
|
+
::Array.new(length) {
|
64
|
+
obj = Obfuscator.junk_object until !obj.nil? && !obj.is_a?(Stream)
|
65
|
+
obj
|
66
|
+
}.to_o
|
67
|
+
end
|
83
68
|
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
def self.junk_boolean
|
70
|
+
Boolean.new(rand(2).zero?)
|
71
|
+
end
|
87
72
|
|
88
|
-
|
89
|
-
|
73
|
+
def self.junk_dictionary(max_size = 5)
|
74
|
+
length = rand(max_size) + 1
|
90
75
|
|
91
|
-
|
92
|
-
|
76
|
+
hash = {}
|
77
|
+
length.times do
|
78
|
+
obj = Obfuscator.junk_object
|
79
|
+
hash[Obfuscator.junk_name] = obj unless obj.is_a?(Stream)
|
80
|
+
end
|
93
81
|
|
94
|
-
|
95
|
-
|
96
|
-
end
|
82
|
+
hash.to_o
|
83
|
+
end
|
97
84
|
|
98
|
-
|
85
|
+
def self.junk_integer(max = MAX_INT)
|
86
|
+
Integer.new(rand(max + 1))
|
87
|
+
end
|
99
88
|
|
100
|
-
|
101
|
-
|
89
|
+
def self.junk_name(max_size = 8)
|
90
|
+
length = rand(max_size) + 1
|
102
91
|
|
103
|
-
|
104
|
-
|
92
|
+
Name.new(::Array.new(length) { PRINTABLE[rand(PRINTABLE.size)] }.join)
|
93
|
+
end
|
105
94
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
stm.data = junk_data
|
95
|
+
def self.junk_null
|
96
|
+
Null.new
|
97
|
+
end
|
110
98
|
|
111
|
-
|
112
|
-
|
99
|
+
def self.junk_stream(max_data_size = 200)
|
100
|
+
chainlen = rand(1..2)
|
101
|
+
chain = ::Array.new(chainlen) { FILTERS[rand(FILTERS.size)] }
|
113
102
|
|
114
|
-
|
115
|
-
|
103
|
+
length = rand(max_data_size) + 1
|
104
|
+
junk_data = ::Array.new(length) { rand(256).chr }.join
|
116
105
|
|
117
|
-
|
106
|
+
stm = Stream.new
|
107
|
+
stm.dictionary = Obfuscator.junk_dictionary(5)
|
108
|
+
stm.setFilter(chain)
|
109
|
+
stm.data = junk_data
|
118
110
|
|
119
|
-
|
120
|
-
|
111
|
+
stm
|
112
|
+
end
|
121
113
|
|
122
|
-
|
123
|
-
|
124
|
-
end
|
114
|
+
def self.junk_string(max_size = 10)
|
115
|
+
length = rand(max_size) + 1
|
125
116
|
|
126
|
-
|
127
|
-
no = rand(max_no) + 1
|
128
|
-
gen = rand(max_gen)
|
117
|
+
strtype = rand(2).zero? ? LiteralString : HexaString
|
129
118
|
|
130
|
-
|
131
|
-
end
|
119
|
+
strtype.new(::Array.new(length) { PRINTABLE[rand(PRINTABLE.size)] }.join)
|
132
120
|
end
|
133
121
|
|
134
|
-
|
122
|
+
def self.junk_real
|
123
|
+
Real.new(rand * rand(MAX_INT + 1))
|
124
|
+
end
|
135
125
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
content << Obfuscator.junk_spaces +
|
140
|
-
key.to_obfuscated_str + Obfuscator.junk_spaces +
|
141
|
-
value.to_obfuscated_str + Obfuscator.junk_spaces
|
142
|
-
end
|
126
|
+
def self.junk_reference(max_no = 300, max_gen = 1)
|
127
|
+
no = rand(max_no) + 1
|
128
|
+
gen = rand(max_gen)
|
143
129
|
|
144
|
-
|
145
|
-
super(content)
|
146
|
-
end
|
130
|
+
Reference.new(no, gen)
|
147
131
|
end
|
148
|
-
|
149
|
-
|
150
|
-
|
132
|
+
end
|
133
|
+
|
134
|
+
class Dictionary
|
135
|
+
def to_obfuscated_str
|
136
|
+
content = TOKENS.first + Obfuscator.junk_spaces
|
137
|
+
each_pair do |key, value|
|
138
|
+
content << Obfuscator.junk_spaces +
|
139
|
+
key.to_obfuscated_str + Obfuscator.junk_spaces +
|
140
|
+
value.to_obfuscated_str + Obfuscator.junk_spaces
|
141
|
+
end
|
142
|
+
|
143
|
+
content << TOKENS.last
|
144
|
+
super(content)
|
151
145
|
end
|
146
|
+
end
|
152
147
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
self.each do |entry|
|
157
|
-
content << entry.to_o.to_obfuscated_str + Obfuscator.junk_spaces
|
158
|
-
end
|
148
|
+
module Object
|
149
|
+
alias_method :to_obfuscated_str, :to_s
|
150
|
+
end
|
159
151
|
|
160
|
-
|
152
|
+
class Array
|
153
|
+
def to_obfuscated_str
|
154
|
+
content = TOKENS.first + Obfuscator.junk_spaces
|
155
|
+
each do |entry|
|
156
|
+
content << entry.to_o.to_obfuscated_str + Obfuscator.junk_spaces
|
157
|
+
end
|
161
158
|
|
162
|
-
|
163
|
-
end
|
164
|
-
end
|
159
|
+
content << TOKENS.last
|
165
160
|
|
166
|
-
|
167
|
-
alias :to_obfuscated_str :to_s
|
161
|
+
super(content)
|
168
162
|
end
|
163
|
+
end
|
169
164
|
|
170
|
-
|
171
|
-
|
172
|
-
|
165
|
+
class Null
|
166
|
+
alias_method :to_obfuscated_str, :to_s
|
167
|
+
end
|
173
168
|
|
174
|
-
|
175
|
-
|
176
|
-
|
169
|
+
class Boolean
|
170
|
+
alias_method :to_obfuscated_str, :to_s
|
171
|
+
end
|
177
172
|
|
178
|
-
|
179
|
-
|
180
|
-
|
173
|
+
class Integer
|
174
|
+
alias_method :to_obfuscated_str, :to_s
|
175
|
+
end
|
181
176
|
|
182
|
-
|
183
|
-
|
184
|
-
|
177
|
+
class Real
|
178
|
+
alias_method :to_obfuscated_str, :to_s
|
179
|
+
end
|
185
180
|
|
186
|
-
|
187
|
-
|
188
|
-
|
181
|
+
class Reference
|
182
|
+
def to_obfuscated_str
|
183
|
+
refstr = refno.to_s + Obfuscator.junk_spaces + refgen.to_s + Obfuscator.junk_spaces + "R"
|
189
184
|
|
190
|
-
|
191
|
-
alias :to_obfuscated_str :to_s
|
185
|
+
super(refstr)
|
192
186
|
end
|
187
|
+
end
|
193
188
|
|
194
|
-
|
195
|
-
|
196
|
-
|
189
|
+
class LiteralString
|
190
|
+
alias_method :to_obfuscated_str, :to_s
|
191
|
+
end
|
197
192
|
|
198
|
-
|
199
|
-
|
200
|
-
|
193
|
+
class HexaString
|
194
|
+
alias_method :to_obfuscated_str, :to_s
|
195
|
+
end
|
201
196
|
|
202
|
-
|
197
|
+
class Name
|
198
|
+
def to_obfuscated_str(prop = 2)
|
199
|
+
name = @value.dup
|
203
200
|
|
204
|
-
|
205
|
-
if rand(prop) == 0 or forbiddenchars.include?(c)
|
206
|
-
hexchar = c.ord.to_s(16)
|
207
|
-
hexchar = "0" + hexchar if hexchar.length < 2
|
201
|
+
forbiddenchars = [" ", "#", "\t", "\r", "\n", "\0", "[", "]", "<", ">", "(", ")", "%", "/", "\\"]
|
208
202
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
end
|
203
|
+
name.gsub!(/./) do |c|
|
204
|
+
if (rand(prop) == 0) || forbiddenchars.include?(c)
|
205
|
+
hexchar = c.ord.to_s(16)
|
206
|
+
hexchar = "0" + hexchar if hexchar.length < 2
|
214
207
|
|
215
|
-
|
208
|
+
'#' + hexchar
|
209
|
+
else
|
210
|
+
c
|
216
211
|
end
|
212
|
+
end
|
213
|
+
|
214
|
+
super(TOKENS.first + name)
|
217
215
|
end
|
216
|
+
end
|
218
217
|
|
219
|
-
|
220
|
-
|
221
|
-
|
218
|
+
class Stream
|
219
|
+
def to_obfuscated_str
|
220
|
+
content = ""
|
222
221
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
222
|
+
content << @dictionary.to_obfuscated_str
|
223
|
+
content << "stream" + $/
|
224
|
+
content << encoded_data
|
225
|
+
content << $/ << TOKENS.last
|
227
226
|
|
228
|
-
|
229
|
-
end
|
227
|
+
super(content)
|
230
228
|
end
|
229
|
+
end
|
231
230
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
231
|
+
class Trailer
|
232
|
+
def to_obfuscated_str
|
233
|
+
content = ""
|
234
|
+
if dictionary?
|
235
|
+
content << TOKENS.first << $/ << @dictionary.to_obfuscated_str << $/
|
236
|
+
end
|
238
237
|
|
239
|
-
|
238
|
+
content << XREF_TOKEN << $/ << @startxref.to_s << $/ << TOKENS.last << $/
|
240
239
|
|
241
|
-
|
242
|
-
end
|
240
|
+
content
|
243
241
|
end
|
244
|
-
|
242
|
+
end
|
245
243
|
end
|