origamindee 3.0.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.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +89 -0
  3. data/COPYING.LESSER +165 -0
  4. data/README.md +131 -0
  5. data/bin/config/pdfcop.conf.yml +236 -0
  6. data/bin/pdf2pdfa +87 -0
  7. data/bin/pdf2ruby +333 -0
  8. data/bin/pdfcop +476 -0
  9. data/bin/pdfdecompress +97 -0
  10. data/bin/pdfdecrypt +91 -0
  11. data/bin/pdfencrypt +113 -0
  12. data/bin/pdfexplode +223 -0
  13. data/bin/pdfextract +277 -0
  14. data/bin/pdfmetadata +143 -0
  15. data/bin/pdfsh +12 -0
  16. data/bin/shell/console.rb +128 -0
  17. data/bin/shell/hexdump.rb +59 -0
  18. data/bin/shell/irbrc +69 -0
  19. data/examples/README.md +34 -0
  20. data/examples/attachments/attachment.rb +38 -0
  21. data/examples/attachments/nested_document.rb +51 -0
  22. data/examples/encryption/encryption.rb +28 -0
  23. data/examples/events/events.rb +72 -0
  24. data/examples/flash/flash.rb +37 -0
  25. data/examples/flash/helloworld.swf +0 -0
  26. data/examples/forms/javascript.rb +54 -0
  27. data/examples/forms/xfa.rb +115 -0
  28. data/examples/javascript/hello_world.rb +22 -0
  29. data/examples/javascript/js_emulation.rb +54 -0
  30. data/examples/loop/goto.rb +32 -0
  31. data/examples/loop/named.rb +33 -0
  32. data/examples/signature/signature.rb +65 -0
  33. data/examples/uri/javascript.rb +56 -0
  34. data/examples/uri/open-uri.rb +21 -0
  35. data/examples/uri/submitform.rb +47 -0
  36. data/lib/origami/3d.rb +364 -0
  37. data/lib/origami/acroform.rb +321 -0
  38. data/lib/origami/actions.rb +318 -0
  39. data/lib/origami/annotations.rb +711 -0
  40. data/lib/origami/array.rb +242 -0
  41. data/lib/origami/boolean.rb +90 -0
  42. data/lib/origami/catalog.rb +418 -0
  43. data/lib/origami/collections.rb +144 -0
  44. data/lib/origami/compound.rb +161 -0
  45. data/lib/origami/destinations.rb +252 -0
  46. data/lib/origami/dictionary.rb +192 -0
  47. data/lib/origami/encryption.rb +1084 -0
  48. data/lib/origami/extensions/fdf.rb +347 -0
  49. data/lib/origami/extensions/ppklite.rb +422 -0
  50. data/lib/origami/filespec.rb +197 -0
  51. data/lib/origami/filters/ascii.rb +211 -0
  52. data/lib/origami/filters/ccitt/tables.rb +267 -0
  53. data/lib/origami/filters/ccitt.rb +357 -0
  54. data/lib/origami/filters/crypt.rb +38 -0
  55. data/lib/origami/filters/dct.rb +54 -0
  56. data/lib/origami/filters/flate.rb +69 -0
  57. data/lib/origami/filters/jbig2.rb +57 -0
  58. data/lib/origami/filters/jpx.rb +47 -0
  59. data/lib/origami/filters/lzw.rb +170 -0
  60. data/lib/origami/filters/predictors.rb +292 -0
  61. data/lib/origami/filters/runlength.rb +129 -0
  62. data/lib/origami/filters.rb +364 -0
  63. data/lib/origami/font.rb +196 -0
  64. data/lib/origami/functions.rb +79 -0
  65. data/lib/origami/graphics/colors.rb +230 -0
  66. data/lib/origami/graphics/instruction.rb +98 -0
  67. data/lib/origami/graphics/path.rb +182 -0
  68. data/lib/origami/graphics/patterns.rb +174 -0
  69. data/lib/origami/graphics/render.rb +62 -0
  70. data/lib/origami/graphics/state.rb +149 -0
  71. data/lib/origami/graphics/text.rb +225 -0
  72. data/lib/origami/graphics/xobject.rb +918 -0
  73. data/lib/origami/graphics.rb +38 -0
  74. data/lib/origami/header.rb +75 -0
  75. data/lib/origami/javascript.rb +713 -0
  76. data/lib/origami/linearization.rb +330 -0
  77. data/lib/origami/metadata.rb +172 -0
  78. data/lib/origami/name.rb +135 -0
  79. data/lib/origami/null.rb +65 -0
  80. data/lib/origami/numeric.rb +181 -0
  81. data/lib/origami/obfuscation.rb +245 -0
  82. data/lib/origami/object.rb +760 -0
  83. data/lib/origami/optionalcontent.rb +183 -0
  84. data/lib/origami/outline.rb +54 -0
  85. data/lib/origami/outputintents.rb +85 -0
  86. data/lib/origami/page.rb +722 -0
  87. data/lib/origami/parser.rb +269 -0
  88. data/lib/origami/parsers/fdf.rb +56 -0
  89. data/lib/origami/parsers/pdf/lazy.rb +176 -0
  90. data/lib/origami/parsers/pdf/linear.rb +122 -0
  91. data/lib/origami/parsers/pdf.rb +118 -0
  92. data/lib/origami/parsers/ppklite.rb +57 -0
  93. data/lib/origami/pdf.rb +1108 -0
  94. data/lib/origami/reference.rb +134 -0
  95. data/lib/origami/signature.rb +702 -0
  96. data/lib/origami/stream.rb +705 -0
  97. data/lib/origami/string.rb +444 -0
  98. data/lib/origami/template/patterns.rb +56 -0
  99. data/lib/origami/template/widgets.rb +151 -0
  100. data/lib/origami/trailer.rb +190 -0
  101. data/lib/origami/tree.rb +62 -0
  102. data/lib/origami/version.rb +23 -0
  103. data/lib/origami/webcapture.rb +100 -0
  104. data/lib/origami/xfa/config.rb +453 -0
  105. data/lib/origami/xfa/connectionset.rb +146 -0
  106. data/lib/origami/xfa/datasets.rb +49 -0
  107. data/lib/origami/xfa/localeset.rb +42 -0
  108. data/lib/origami/xfa/package.rb +59 -0
  109. data/lib/origami/xfa/pdf.rb +73 -0
  110. data/lib/origami/xfa/signature.rb +42 -0
  111. data/lib/origami/xfa/sourceset.rb +43 -0
  112. data/lib/origami/xfa/stylesheet.rb +44 -0
  113. data/lib/origami/xfa/template.rb +1691 -0
  114. data/lib/origami/xfa/xdc.rb +42 -0
  115. data/lib/origami/xfa/xfa.rb +146 -0
  116. data/lib/origami/xfa/xfdf.rb +43 -0
  117. data/lib/origami/xfa/xmpmeta.rb +43 -0
  118. data/lib/origami/xfa.rb +62 -0
  119. data/lib/origami/xreftable.rb +557 -0
  120. data/lib/origami.rb +47 -0
  121. data/test/dataset/calc.pdf +85 -0
  122. data/test/dataset/crypto.pdf +36 -0
  123. data/test/dataset/empty.pdf +49 -0
  124. data/test/test_actions.rb +27 -0
  125. data/test/test_annotations.rb +68 -0
  126. data/test/test_forms.rb +30 -0
  127. data/test/test_native_types.rb +83 -0
  128. data/test/test_object_tree.rb +33 -0
  129. data/test/test_pages.rb +60 -0
  130. data/test/test_pdf.rb +20 -0
  131. data/test/test_pdf_attachment.rb +34 -0
  132. data/test/test_pdf_create.rb +24 -0
  133. data/test/test_pdf_encrypt.rb +102 -0
  134. data/test/test_pdf_parse.rb +134 -0
  135. data/test/test_pdf_parse_lazy.rb +69 -0
  136. data/test/test_pdf_sign.rb +97 -0
  137. data/test/test_streams.rb +184 -0
  138. data/test/test_xrefs.rb +67 -0
  139. metadata +280 -0
@@ -0,0 +1,181 @@
1
+ =begin
2
+
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
5
+
6
+ Origami is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Lesser General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Origami is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public License
17
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ =end
20
+
21
+ require 'delegate'
22
+
23
+ module Origami
24
+
25
+ class InvalidIntegerObjectError < InvalidObjectError #:nodoc:
26
+ end
27
+
28
+ #
29
+ # Class representing a PDF number (Integer, or Real).
30
+ #
31
+ module Number
32
+ include Origami::Object
33
+
34
+ def ~
35
+ self.class.new(~self.value)
36
+ end
37
+
38
+ def |(val)
39
+ self.class.new(self.value | val)
40
+ end
41
+
42
+ def &(val)
43
+ self.class.new(self.value & val)
44
+ end
45
+
46
+ def ^(val)
47
+ self.class.new(self.value ^ val)
48
+ end
49
+
50
+ def <<(val)
51
+ self.class.new(self.value << val)
52
+ end
53
+
54
+ def >>(val)
55
+ self.class.new(self.value >> val)
56
+ end
57
+
58
+ def +(val)
59
+ self.class.new(self.value + val)
60
+ end
61
+
62
+ def -(val)
63
+ self.class.new(self.value - val)
64
+ end
65
+
66
+ def -@
67
+ self.class.new(-self.value)
68
+ end
69
+
70
+ def *(val)
71
+ self.class.new(self.value * val)
72
+ end
73
+
74
+ def /(val)
75
+ self.class.new(self.value / val)
76
+ end
77
+
78
+ def abs
79
+ self.class.new(self.value.abs)
80
+ end
81
+
82
+ def **(val)
83
+ self.class.new(self.value ** val)
84
+ end
85
+ end
86
+
87
+ #
88
+ # Class representing an Integer Object.
89
+ #
90
+ class Integer < DelegateClass(::Integer)
91
+ include Number
92
+
93
+ TOKENS = [ "(\\+|-)?[\\d]+[^.]?" ] #:nodoc:
94
+ REGEXP_TOKEN = Regexp.new(TOKENS.first)
95
+
96
+ @@regexp = Regexp.new(WHITESPACES + "(?<int>(\\+|-)?[\\d]+)")
97
+
98
+ #
99
+ # Creates a new Integer from a Ruby Fixnum / Bignum.
100
+ # _i_:: The Integer value.
101
+ #
102
+ def initialize(i = 0)
103
+ unless i.is_a?(::Integer)
104
+ raise TypeError, "Expected type Fixnum or Bignum, received #{i.class}."
105
+ end
106
+
107
+ super(i)
108
+ end
109
+
110
+ def self.parse(stream, _parser = nil) #:nodoc:
111
+ scanner = Parser.init_scanner(stream)
112
+ offset = scanner.pos
113
+
114
+ if not scanner.scan(@@regexp)
115
+ raise InvalidIntegerObjectError, "Invalid integer format"
116
+ end
117
+
118
+ value = scanner['int'].to_i
119
+ int = Integer.new(value)
120
+ int.file_offset = offset
121
+
122
+ int
123
+ end
124
+
125
+ def to_s(eol: $/) #:nodoc:
126
+ super(self.value.to_s, eol: eol)
127
+ end
128
+
129
+ alias value to_i
130
+ end
131
+
132
+ class InvalidRealObjectError < InvalidObjectError #:nodoc:
133
+ end
134
+
135
+ #
136
+ # Class representing a Real number Object.
137
+ # PDF real numbers are arbitrary precision numbers, depending on architectures.
138
+ #
139
+ class Real < DelegateClass(Float)
140
+ include Number
141
+
142
+ TOKENS = [ "(\\+|-)?([\\d]*\\.[\\d]+|[\\d]+\\.[\\d]*)([eE](\\+|-)?[\\d]+)?" ] #:nodoc:
143
+ REGEXP_TOKEN = Regexp.new(TOKENS.first)
144
+
145
+ @@regexp = Regexp.new(WHITESPACES + "(?<real>#{TOKENS.first})")
146
+
147
+ #
148
+ # Creates a new Real from a Ruby Float.
149
+ # _f_:: The new Real value.
150
+ #
151
+ def initialize(f = 0)
152
+ unless f.is_a?(Float)
153
+ raise TypeError, "Expected type Float, received #{f.class}."
154
+ end
155
+
156
+ super(f)
157
+ end
158
+
159
+ def self.parse(stream, _parser = nil) #:nodoc:
160
+ scanner = Parser.init_scanner(stream)
161
+ offset = scanner.pos
162
+
163
+ if not scanner.scan(@@regexp)
164
+ raise InvalidRealObjectError, "Invalid real number format"
165
+ end
166
+
167
+ value = scanner['real'].to_f
168
+ real = Real.new(value)
169
+ real.file_offset = offset
170
+
171
+ real
172
+ end
173
+
174
+ alias value to_f
175
+
176
+ def to_s(eol: $/) #:nodoc:
177
+ super(sprintf("%f", self).sub(/\.0*$|(\.\d*[^0])0*$/, '\1'), eol: eol)
178
+ end
179
+ end
180
+
181
+ end
@@ -0,0 +1,245 @@
1
+ =begin
2
+
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
5
+
6
+ Origami is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Lesser General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ Origami is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public License
17
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ =end
20
+
21
+ module Origami
22
+
23
+ module Obfuscator
24
+ using TypeConversion
25
+
26
+ WHITECHARS = [ " ", "\t", "\r", "\n", "\0" ]
27
+ OBJECTS = [ Array, Boolean, Dictionary, Integer, Name, Null, Stream, String, Real, Reference ]
28
+ MAX_INT = 0xFFFFFFFF
29
+ PRINTABLE = ("!".."9").to_a + (':'..'Z').to_a + ('['..'z').to_a + ('{'..'~').to_a
30
+ FILTERS = [ :FlateDecode, :RunLengthDecode, :LZWDecode, :ASCIIHexDecode, :ASCII85Decode ]
31
+
32
+ def self.junk_spaces(max_size = 3)
33
+ length = rand(max_size) + 1
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
47
+
48
+ def self.junk_object(type = nil)
49
+ if type.nil?
50
+ type = OBJECTS[rand(OBJECTS.size)]
51
+ end
52
+
53
+ unless type.include?(Origami::Object)
54
+ raise TypeError, "Not a valid object type"
55
+ end
56
+
57
+ Obfuscator.send("junk_#{type.to_s.split('::').last.downcase}")
58
+ end
59
+
60
+ def self.junk_array(max_size = 5)
61
+ length = rand(max_size) + 1
62
+
63
+ ::Array.new(length) {
64
+ obj = Obfuscator.junk_object until (not obj.nil? and not obj.is_a?(Stream)) ; obj
65
+ }.to_o
66
+ end
67
+
68
+ def self.junk_boolean
69
+ Boolean.new(rand(2).zero?)
70
+ end
71
+
72
+ def self.junk_dictionary(max_size = 5)
73
+ length = rand(max_size) + 1
74
+
75
+ hash = Hash.new
76
+ length.times do
77
+ obj = Obfuscator.junk_object
78
+ hash[Obfuscator.junk_name] = obj unless obj.is_a?(Stream)
79
+ end
80
+
81
+ hash.to_o
82
+ end
83
+
84
+ def self.junk_integer(max = MAX_INT)
85
+ Integer.new(rand(max + 1))
86
+ end
87
+
88
+ def self.junk_name(max_size = 8)
89
+ length = rand(max_size) + 1
90
+
91
+ Name.new(::Array.new(length) { PRINTABLE[rand(PRINTABLE.size)] }.join)
92
+ end
93
+
94
+ def self.junk_null
95
+ Null.new
96
+ end
97
+
98
+ def self.junk_stream(max_data_size = 200)
99
+
100
+ chainlen = rand(2) + 1
101
+ chain = ::Array.new(chainlen) { FILTERS[rand(FILTERS.size)] }
102
+
103
+ length = rand(max_data_size) + 1
104
+ junk_data = ::Array.new(length) { rand(256).chr }.join
105
+
106
+ stm = Stream.new
107
+ stm.dictionary = Obfuscator.junk_dictionary(5)
108
+ stm.setFilter(chain)
109
+ stm.data = junk_data
110
+
111
+ stm
112
+ end
113
+
114
+ def self.junk_string(max_size = 10)
115
+ length = rand(max_size) + 1
116
+
117
+ strtype = (rand(2).zero?) ? LiteralString : HexaString
118
+
119
+ strtype.new(::Array.new(length) { PRINTABLE[rand(PRINTABLE.size)] }.join)
120
+ end
121
+
122
+ def self.junk_real
123
+ Real.new(rand * rand(MAX_INT + 1))
124
+ end
125
+
126
+ def self.junk_reference(max_no = 300, max_gen = 1)
127
+ no = rand(max_no) + 1
128
+ gen = rand(max_gen)
129
+
130
+ Reference.new(no, gen)
131
+ end
132
+ end
133
+
134
+ class Dictionary
135
+
136
+ def to_obfuscated_str
137
+ content = TOKENS.first + Obfuscator.junk_spaces
138
+ self.each_pair do |key, value|
139
+ content << Obfuscator.junk_spaces +
140
+ key.to_obfuscated_str + Obfuscator.junk_spaces +
141
+ value.to_obfuscated_str + Obfuscator.junk_spaces
142
+ end
143
+
144
+ content << TOKENS.last
145
+ super(content)
146
+ end
147
+ end
148
+
149
+ module Object
150
+ alias :to_obfuscated_str :to_s
151
+ end
152
+
153
+ class Array
154
+ def to_obfuscated_str
155
+ content = TOKENS.first + Obfuscator.junk_spaces
156
+ self.each do |entry|
157
+ content << entry.to_o.to_obfuscated_str + Obfuscator.junk_spaces
158
+ end
159
+
160
+ content << TOKENS.last
161
+
162
+ super(content)
163
+ end
164
+ end
165
+
166
+ class Null
167
+ alias :to_obfuscated_str :to_s
168
+ end
169
+
170
+ class Boolean
171
+ alias :to_obfuscated_str :to_s
172
+ end
173
+
174
+ class Integer
175
+ alias :to_obfuscated_str :to_s
176
+ end
177
+
178
+ class Real
179
+ alias :to_obfuscated_str :to_s
180
+ end
181
+
182
+ class Reference
183
+ def to_obfuscated_str
184
+ refstr = refno.to_s + Obfuscator.junk_spaces + refgen.to_s + Obfuscator.junk_spaces + "R"
185
+
186
+ super(refstr)
187
+ end
188
+ end
189
+
190
+ class LiteralString
191
+ alias :to_obfuscated_str :to_s
192
+ end
193
+
194
+ class HexaString
195
+ alias :to_obfuscated_str :to_s
196
+ end
197
+
198
+ class Name
199
+ def to_obfuscated_str(prop = 2)
200
+ name = @value.dup
201
+
202
+ forbiddenchars = [ " ","#","\t","\r","\n","\0","[","]","<",">","(",")","%","/","\\" ]
203
+
204
+ name.gsub!(/./) do |c|
205
+ if rand(prop) == 0 or forbiddenchars.include?(c)
206
+ hexchar = c.ord.to_s(16)
207
+ hexchar = "0" + hexchar if hexchar.length < 2
208
+
209
+ '#' + hexchar
210
+ else
211
+ c
212
+ end
213
+ end
214
+
215
+ super(TOKENS.first + name)
216
+ end
217
+ end
218
+
219
+ class Stream
220
+ def to_obfuscated_str
221
+ content = ""
222
+
223
+ content << @dictionary.to_obfuscated_str
224
+ content << "stream" + $/
225
+ content << self.encoded_data
226
+ content << $/ << TOKENS.last
227
+
228
+ super(content)
229
+ end
230
+ end
231
+
232
+ class Trailer
233
+ def to_obfuscated_str
234
+ content = ""
235
+ if self.dictionary?
236
+ content << TOKENS.first << $/ << @dictionary.to_obfuscated_str << $/
237
+ end
238
+
239
+ content << XREF_TOKEN << $/ << @startxref.to_s << $/ << TOKENS.last << $/
240
+
241
+ content
242
+ end
243
+ end
244
+
245
+ end