origami 1.2.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +112 -0
  4. data/bin/config/pdfcop.conf.yml +232 -233
  5. data/bin/gui/about.rb +27 -37
  6. data/bin/gui/config.rb +108 -117
  7. data/bin/gui/file.rb +416 -365
  8. data/bin/gui/gtkhex.rb +1138 -1153
  9. data/bin/gui/hexview.rb +55 -57
  10. data/bin/gui/imgview.rb +48 -51
  11. data/bin/gui/menu.rb +388 -386
  12. data/bin/gui/properties.rb +114 -130
  13. data/bin/gui/signing.rb +571 -617
  14. data/bin/gui/textview.rb +77 -95
  15. data/bin/gui/treeview.rb +382 -387
  16. data/bin/gui/walker.rb +227 -232
  17. data/bin/gui/xrefs.rb +56 -60
  18. data/bin/pdf2pdfa +53 -57
  19. data/bin/pdf2ruby +212 -228
  20. data/bin/pdfcop +338 -348
  21. data/bin/pdfdecompress +58 -65
  22. data/bin/pdfdecrypt +56 -60
  23. data/bin/pdfencrypt +75 -80
  24. data/bin/pdfexplode +185 -182
  25. data/bin/pdfextract +201 -218
  26. data/bin/pdfmetadata +83 -82
  27. data/bin/pdfsh +4 -5
  28. data/bin/pdfwalker +1 -2
  29. data/bin/shell/.irbrc +45 -82
  30. data/bin/shell/console.rb +105 -130
  31. data/bin/shell/hexdump.rb +40 -64
  32. data/examples/README.md +34 -0
  33. data/examples/attachments/attachment.rb +38 -0
  34. data/examples/attachments/nested_document.rb +51 -0
  35. data/examples/encryption/encryption.rb +28 -0
  36. data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
  37. data/examples/flash/flash.rb +37 -0
  38. data/{samples → examples}/flash/helloworld.swf +0 -0
  39. data/examples/forms/javascript.rb +54 -0
  40. data/examples/forms/xfa.rb +115 -0
  41. data/examples/javascript/hello_world.rb +22 -0
  42. data/examples/javascript/js_emulation.rb +54 -0
  43. data/examples/loop/goto.rb +32 -0
  44. data/examples/loop/named.rb +33 -0
  45. data/examples/signature/signature.rb +65 -0
  46. data/examples/uri/javascript.rb +56 -0
  47. data/examples/uri/open-uri.rb +21 -0
  48. data/examples/uri/submitform.rb +47 -0
  49. data/lib/origami.rb +29 -42
  50. data/lib/origami/3d.rb +350 -225
  51. data/lib/origami/acroform.rb +262 -288
  52. data/lib/origami/actions.rb +268 -288
  53. data/lib/origami/annotations.rb +697 -722
  54. data/lib/origami/array.rb +258 -184
  55. data/lib/origami/boolean.rb +74 -84
  56. data/lib/origami/catalog.rb +397 -434
  57. data/lib/origami/collections.rb +144 -0
  58. data/lib/origami/destinations.rb +233 -194
  59. data/lib/origami/dictionary.rb +253 -232
  60. data/lib/origami/encryption.rb +1274 -1243
  61. data/lib/origami/export.rb +232 -268
  62. data/lib/origami/extensions/fdf.rb +307 -220
  63. data/lib/origami/extensions/ppklite.rb +368 -435
  64. data/lib/origami/filespec.rb +197 -0
  65. data/lib/origami/filters.rb +301 -295
  66. data/lib/origami/filters/ascii.rb +177 -180
  67. data/lib/origami/filters/ccitt.rb +528 -535
  68. data/lib/origami/filters/crypt.rb +26 -35
  69. data/lib/origami/filters/dct.rb +46 -52
  70. data/lib/origami/filters/flate.rb +95 -94
  71. data/lib/origami/filters/jbig2.rb +49 -55
  72. data/lib/origami/filters/jpx.rb +38 -44
  73. data/lib/origami/filters/lzw.rb +189 -183
  74. data/lib/origami/filters/predictors.rb +221 -235
  75. data/lib/origami/filters/runlength.rb +103 -104
  76. data/lib/origami/font.rb +173 -186
  77. data/lib/origami/functions.rb +67 -81
  78. data/lib/origami/graphics.rb +25 -21
  79. data/lib/origami/graphics/colors.rb +178 -187
  80. data/lib/origami/graphics/instruction.rb +79 -85
  81. data/lib/origami/graphics/path.rb +142 -148
  82. data/lib/origami/graphics/patterns.rb +160 -167
  83. data/lib/origami/graphics/render.rb +43 -50
  84. data/lib/origami/graphics/state.rb +138 -153
  85. data/lib/origami/graphics/text.rb +188 -205
  86. data/lib/origami/graphics/xobject.rb +819 -815
  87. data/lib/origami/header.rb +63 -78
  88. data/lib/origami/javascript.rb +596 -597
  89. data/lib/origami/linearization.rb +285 -290
  90. data/lib/origami/metadata.rb +139 -148
  91. data/lib/origami/name.rb +112 -148
  92. data/lib/origami/null.rb +53 -62
  93. data/lib/origami/numeric.rb +162 -175
  94. data/lib/origami/obfuscation.rb +186 -174
  95. data/lib/origami/object.rb +593 -573
  96. data/lib/origami/outline.rb +42 -47
  97. data/lib/origami/outputintents.rb +73 -82
  98. data/lib/origami/page.rb +703 -592
  99. data/lib/origami/parser.rb +238 -290
  100. data/lib/origami/parsers/fdf.rb +41 -33
  101. data/lib/origami/parsers/pdf.rb +75 -95
  102. data/lib/origami/parsers/pdf/lazy.rb +137 -0
  103. data/lib/origami/parsers/pdf/linear.rb +64 -66
  104. data/lib/origami/parsers/ppklite.rb +34 -70
  105. data/lib/origami/pdf.rb +1030 -1005
  106. data/lib/origami/reference.rb +102 -102
  107. data/lib/origami/signature.rb +591 -609
  108. data/lib/origami/stream.rb +668 -551
  109. data/lib/origami/string.rb +397 -373
  110. data/lib/origami/template/patterns.rb +56 -0
  111. data/lib/origami/template/widgets.rb +151 -0
  112. data/lib/origami/trailer.rb +144 -158
  113. data/lib/origami/tree.rb +62 -0
  114. data/lib/origami/version.rb +23 -0
  115. data/lib/origami/webcapture.rb +88 -79
  116. data/lib/origami/xfa.rb +2863 -2882
  117. data/lib/origami/xreftable.rb +472 -384
  118. data/test/dataset/calc.pdf +85 -0
  119. data/test/dataset/crypto.pdf +82 -0
  120. data/test/dataset/empty.pdf +49 -0
  121. data/test/test_actions.rb +27 -0
  122. data/test/test_annotations.rb +90 -0
  123. data/test/test_pages.rb +31 -0
  124. data/test/test_pdf.rb +16 -0
  125. data/test/test_pdf_attachment.rb +34 -0
  126. data/test/test_pdf_create.rb +24 -0
  127. data/test/test_pdf_encrypt.rb +95 -0
  128. data/test/test_pdf_parse.rb +96 -0
  129. data/test/test_pdf_sign.rb +58 -0
  130. data/test/test_streams.rb +182 -0
  131. data/test/test_xrefs.rb +67 -0
  132. metadata +88 -58
  133. data/README +0 -67
  134. data/bin/pdf2graph +0 -121
  135. data/bin/pdfcocoon +0 -104
  136. data/lib/origami/file.rb +0 -233
  137. data/samples/README.txt +0 -45
  138. data/samples/actions/launch/calc.rb +0 -87
  139. data/samples/actions/launch/winparams.rb +0 -22
  140. data/samples/actions/loop/loopgoto.rb +0 -24
  141. data/samples/actions/loop/loopnamed.rb +0 -21
  142. data/samples/actions/named/named.rb +0 -31
  143. data/samples/actions/samba/smbrelay.rb +0 -26
  144. data/samples/actions/webbug/submitform.js +0 -26
  145. data/samples/actions/webbug/webbug-browser.rb +0 -68
  146. data/samples/actions/webbug/webbug-js.rb +0 -67
  147. data/samples/actions/webbug/webbug-reader.rb +0 -90
  148. data/samples/attachments/attach.rb +0 -40
  149. data/samples/attachments/attached.txt +0 -1
  150. data/samples/crypto/crypto.rb +0 -28
  151. data/samples/digsig/signed.rb +0 -46
  152. data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
  153. data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
  154. data/samples/exploits/exploit_customdictopen.rb +0 -55
  155. data/samples/exploits/getannots.rb +0 -69
  156. data/samples/flash/flash.rb +0 -31
  157. data/samples/javascript/attached.txt +0 -1
  158. data/samples/javascript/js.rb +0 -52
  159. data/templates/patterns.rb +0 -66
  160. data/templates/widgets.rb +0 -173
  161. data/templates/xdp.rb +0 -92
  162. data/test/ts_pdf.rb +0 -50
@@ -1,79 +1,75 @@
1
1
  =begin
2
2
 
3
- = File
4
- xrefs.rb
5
-
6
- = Info
7
- This file is part of PDF Walker, a graphical PDF file browser
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- PDF Walker is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU General Public License as published by
13
- the Free Software Foundation, either version 3 of the License, or
14
- (at your option) any later version.
15
-
16
- PDF Walker is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU General Public License for more details.
20
-
21
- You should have received a copy of the GNU General Public License
22
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
3
+ This file is part of PDF Walker, a graphical PDF file browser
4
+ Copyright (C) 2016 Guillaume Delugré.
23
5
 
24
- =end
6
+ PDF Walker is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU 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
+ PDF Walker 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 General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
25
18
 
26
- require 'origami'
27
- include Origami
19
+ =end
28
20
 
29
21
  module PDFWalker
30
22
 
31
- class Walker < Window
32
-
33
- def show_xrefs(target)
34
- XrefsDialog.new(self, target)
23
+ class Walker < Window
24
+ def show_xrefs(target)
25
+ XrefsDialog.new(self, target)
26
+ end
35
27
  end
36
28
 
37
- end
29
+ class XrefsDialog < Dialog
30
+ OBJCOL = 0
31
+ REFCOL = 1
32
+ NAMECOL = 2
38
33
 
39
- class XrefsDialog < Dialog
40
-
41
- OBJCOL = 0
42
- TEXTCOL = 1
34
+ def initialize(parent, target)
35
+ super("Xrefs to #{target.reference}", parent, Dialog::MODAL, [Stock::CLOSE, Dialog::RESPONSE_NONE])
36
+ @parent = parent
43
37
 
44
- def initialize(parent, target)
45
-
46
- super("Xrefs to #{target.reference}", parent, Dialog::MODAL, [Stock::CLOSE, Dialog::RESPONSE_NONE])
47
- @parent = parent
38
+ @list = ListStore.new(Object, String, String)
39
+ @view = TreeView.new(@list)
48
40
 
49
- @list = ListStore.new(Object, String)
50
- @view = TreeView.new(@list)
41
+ column = Gtk::TreeViewColumn.new("Origin", Gtk::CellRendererText.new, text: REFCOL)
42
+ @view.append_column(column)
51
43
 
52
- column = Gtk::TreeViewColumn.new("Objects", Gtk::CellRendererText.new, :text => TEXTCOL)
53
- @view.append_column(column)
44
+ column = Gtk::TreeViewColumn.new("Objects", Gtk::CellRendererText.new, text: NAMECOL)
45
+ @view.append_column(column)
54
46
 
55
- target.xrefs.each { |obj|
56
- str = obj.class.to_s
57
- iter = @list.append
58
- @list.set_value(iter, OBJCOL, obj)
59
- @list.set_value(iter, TEXTCOL, str)
60
- }
47
+ target.xrefs.each { |obj|
48
+ str = obj.type.to_s
49
+ iter = @list.append
50
+ @list.set_value(iter, OBJCOL, obj)
61
51
 
62
- @view.signal_connect("row_activated") { |tree, path, column|
63
- if @view.selection.selected
64
- from = @list.get_value(@view.selection.selected, OBJCOL)
65
- @parent.treeview.goto(from)
66
- end
67
- }
52
+ obj = obj.parent until obj.indirect?
53
+ @list.set_value(iter, REFCOL, obj.reference.to_s)
68
54
 
69
- scroll = ScrolledWindow.new.set_policy(POLICY_NEVER, POLICY_AUTOMATIC)
70
- scroll.add(@view)
71
- vbox.add(scroll)
55
+ @list.set_value(iter, NAMECOL, str)
56
+ }
72
57
 
73
- signal_connect('response') { destroy }
74
- show_all
75
- end
76
-
77
- end
58
+ @view.signal_connect("row_activated") { |tree, path, _column|
59
+ if @view.selection.selected
60
+ from = @list.get_value(@view.selection.selected, OBJCOL)
61
+ @parent.treeview.goto(from)
62
+ end
63
+ }
64
+
65
+ scroll = ScrolledWindow.new.set_policy(POLICY_NEVER, POLICY_AUTOMATIC)
66
+ scroll.add(@view)
67
+ vbox.add(scroll)
68
+
69
+ set_default_size(200, 200)
78
70
 
71
+ signal_connect('response') { destroy }
72
+ show_all
73
+ end
74
+ end
79
75
  end
@@ -1,91 +1,87 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  =begin
4
4
 
5
- = Author:
6
- Guillaume Delugré <guillaume/at/security-labs.org>
5
+ = Info
6
+ Enforces a document to be rendered as PDF/A.
7
+ This will disable multimedia features and JavaScript execution in Adobe Reader.
7
8
 
8
- = Info:
9
- Enforces a document to be rendered as PDF/A.
10
- This will disable multimedia features and JavaScript execution in Adobe Reader.
9
+ = License
10
+ Copyright (C) 2016 Guillaume Delugré.
11
11
 
12
- = License:
13
- Origami is free software: you can redistribute it and/or modify
14
- it under the terms of the GNU Lesser General Public License as published by
15
- the Free Software Foundation, either version 3 of the License, or
16
- (at your option) any later version.
12
+ Origami is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU Lesser General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
17
16
 
18
- Origami is distributed in the hope that it will be useful,
19
- but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- GNU Lesser General Public License for more details.
17
+ Origami is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU Lesser General Public License for more details.
22
21
 
23
- You should have received a copy of the GNU Lesser General Public License
24
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
22
+ You should have received a copy of the GNU Lesser General Public License
23
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
25
24
 
26
25
  =end
27
26
 
28
27
  begin
29
- require 'origami'
28
+ require 'origami'
30
29
  rescue LoadError
31
- ORIGAMIDIR = "#{File.dirname(__FILE__)}/../lib"
32
- $: << ORIGAMIDIR
33
- require 'origami'
30
+ $: << File.join(__dir__, '../lib')
31
+ require 'origami'
34
32
  end
35
33
  include Origami
36
34
 
37
35
  require 'optparse'
38
36
 
39
37
  class OptParser
40
- BANNER = <<USAGE
38
+ BANNER = <<USAGE
41
39
  Usage: #{$0} [<PDF-file>] [-o <output-file>]
42
- Enforces a document to be rendered as PDF/A.
40
+ Enforces a document to be rendered as PDF/A.
43
41
  This will disable multimedia features and JavaScript execution in Adobe Reader.
44
- Bug reports or feature requests at: http://origami-pdf.googlecode.com/
42
+ Bug reports or feature requests at: http://github.com/gdelugre/origami
45
43
 
46
44
  Options:
47
45
  USAGE
48
46
 
49
- def self.parser(options)
50
- OptionParser.new do |opts|
51
- opts.banner = BANNER
47
+ def self.parser(options)
48
+ OptionParser.new do |opts|
49
+ opts.banner = BANNER
52
50
 
53
- opts.on("-o", "--output FILE", "Output PDF file (stdout by default)") do |o|
54
- options[:output] = o
55
- end
51
+ opts.on("-o", "--output FILE", "Output PDF file (stdout by default)") do |o|
52
+ options[:output] = o
53
+ end
56
54
 
57
- opts.on_tail("-h", "--help", "Show this message") do
58
- puts opts
59
- exit
60
- end
55
+ opts.on_tail("-h", "--help", "Show this message") do
56
+ puts opts
57
+ exit
58
+ end
59
+ end
61
60
  end
62
- end
63
61
 
64
- def self.parse(args)
65
- options =
66
- {
67
- :output => STDOUT,
68
- }
62
+ def self.parse(args)
63
+ options =
64
+ {
65
+ output: STDOUT,
66
+ }
69
67
 
70
- self.parser(options).parse!(args)
68
+ self.parser(options).parse!(args)
71
69
 
72
- options
73
- end
70
+ options
71
+ end
74
72
  end
75
73
 
76
74
  begin
77
- @options = OptParser.parse(ARGV)
78
-
79
- target = (ARGV.empty?) ? STDIN : ARGV.shift
80
- params =
81
- {
82
- :verbosity => Parser::VERBOSE_QUIET,
83
- }
84
-
85
- PDF.read(target, params).save(@options[:output], :intent => 'PDF/A', :noindent => true)
86
- rescue SystemExit
87
- rescue Exception => e
88
- STDERR.puts "#{e.class}: #{e.message}"
89
- exit 1
90
- end
75
+ @options = OptParser.parse(ARGV)
91
76
 
77
+ target = (ARGV.empty?) ? STDIN : ARGV.shift
78
+ params =
79
+ {
80
+ verbosity: Parser::VERBOSE_QUIET,
81
+ }
82
+
83
+ PDF.read(target, params).save(@options[:output], intent: 'PDF/A', noindent: true)
84
+
85
+ rescue
86
+ abort"#{$!.class}: #{$!.message}"
87
+ end
@@ -2,37 +2,37 @@
2
2
 
3
3
  =begin
4
4
 
5
- = Info
6
- Convert a PDF document to an Origami script.
7
- Experimental.
5
+ = Info
6
+ Convert a PDF document to an Origami script.
7
+ Experimental.
8
8
 
9
9
  = License:
10
- Origami is free software: you can redistribute it and/or modify
11
- it under the terms of the GNU Lesser General Public License as published by
12
- the Free Software Foundation, either version 3 of the License, or
13
- (at your option) any later version.
10
+ Copyright (C) 2016 Guillaume Delugré.
14
11
 
15
- Origami is distributed in the hope that it will be useful,
16
- but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
- GNU Lesser General Public License for more details.
12
+ Origami is free software: you can redistribute it and/or modify
13
+ it under the terms of the GNU Lesser General Public License as published by
14
+ the Free Software Foundation, either version 3 of the License, or
15
+ (at your option) any later version.
19
16
 
20
- You should have received a copy of the GNU Lesser General Public License
21
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
17
+ Origami is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU Lesser General Public License for more details.
22
21
 
23
- = Author
24
- Guillaume Delugré
22
+ You should have received a copy of the GNU Lesser General Public License
23
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
25
24
 
26
25
  =end
27
26
 
28
27
  require 'optparse'
29
28
  require 'fileutils'
29
+ require 'colorize'
30
+
30
31
  begin
31
- ORIGAMIDIR = "#{File.dirname(__FILE__)}/../lib"
32
- require 'origami'
32
+ require 'origami'
33
33
  rescue LoadError
34
- $: << ORIGAMIDIR
35
- require 'origami'
34
+ $: << File.join(__dir__, '../lib')
35
+ require 'origami'
36
36
  end
37
37
  include Origami
38
38
 
@@ -42,252 +42,247 @@ include Origami
42
42
  @current_idx = nil
43
43
 
44
44
  class OptParser
45
- def self.parse(args)
46
- options = {}
47
- options[:verbose] =
48
- options[:xstreams] = false
45
+ def self.parse(args)
46
+ options = {}
47
+ options[:verbose] =
48
+ options[:xstreams] = false
49
49
 
50
- opts = OptionParser.new do |opts|
51
- opts.banner = <<BANNER
50
+ opts = OptionParser.new do |opts|
51
+ opts.banner = <<BANNER
52
52
  Usage: #{$0} [-v] [-x] <PDF-file>
53
53
  Convert a PDF document to an Origami script (experimental).
54
54
 
55
55
  Options:
56
56
  BANNER
57
-
58
- opts.on("-v", "--verbose", "Verbose mode") do
59
- options[:verbose] = true
60
- end
61
-
62
- opts.on("-x", "--extract-streams", "Extract PDF streams to separate files") do
63
- options[:xstreams] = true
64
- end
65
-
66
- opts.on_tail("-h", "--help", "Show this message") do
67
- puts opts
68
- exit
69
- end
70
- end
71
- opts.parse!(args)
72
57
 
73
- options
74
- end
58
+ opts.on("-v", "--verbose", "Verbose mode") do
59
+ options[:verbose] = true
60
+ end
61
+
62
+ opts.on("-x", "--extract-streams", "Extract PDF streams to separate files") do
63
+ options[:xstreams] = true
64
+ end
65
+
66
+ opts.on_tail("-h", "--help", "Show this message") do
67
+ puts opts
68
+ exit
69
+ end
70
+ end
71
+
72
+ opts.parse!(args)
73
+
74
+ options
75
+ end
75
76
  end
76
77
 
77
78
  @options = OptParser.parse(ARGV)
78
79
 
79
80
  if ARGV.empty?
80
- STDERR.puts "Error: No filename was specified. #{$0} --help for details."
81
- exit 1
81
+ abort "Error: No filename was specified. #{$0} --help for details."
82
82
  else
83
83
  TARGET = ARGV.shift
84
84
  end
85
85
 
86
86
  Origami::OPTIONS[:enable_type_guessing] = Origami::OPTIONS[:enable_type_propagation] = true
87
-
87
+
88
88
  TARGET_DIR = File.basename(TARGET, '.pdf')
89
- TARGET_FILE = "#{TARGET_DIR}/#{TARGET_DIR}.rb"
89
+ TARGET_FILE = File.join(TARGET_DIR, "#{TARGET_DIR}.rb")
90
90
  STREAM_DIR = "streams"
91
91
 
92
92
  def objectToRuby(obj, inclevel = 0, internalname = nil, do_convert = false)
93
- code = ""
94
-
95
- code <<
96
- case obj
97
- when Origami::Null
98
- "Null.new"
99
- when Origami::Boolean, Origami::Number
100
- obj.value.to_s
101
- when Origami::String
102
- "'#{obj.value.gsub("'","\\\\'")}'"
103
- when Origami::Dictionary
104
- customclass = nil
105
- if obj.class != Origami::Dictionary
106
- p = (obj.class == Origami::Encoding) ? 0 : 1
107
- customclass = obj.class.to_s.split('::')[p..-1].join('::') # strip Origami prefix if there is no collision
108
- end
109
- dictionaryToRuby(obj, inclevel, internalname, customclass)
110
- when Origami::Array
111
- arrayToRuby(obj, inclevel, internalname)
112
- when Origami::Stream
113
- streamToRuby(obj, internalname)
114
- when Origami::Name
115
- nameToRuby(obj)
116
- when Origami::Reference
117
- referenceToRuby(obj, internalname)
118
- else
119
- raise RuntimeError, "Unknown object type: #{obj.class}"
120
- end
93
+ code = ""
94
+
95
+ code <<
96
+ case obj
97
+ when Origami::Null
98
+ "Null.new"
99
+ when Origami::Boolean, Origami::Number
100
+ obj.value.to_s
101
+ when Origami::String
102
+ obj.inspect
103
+ when Origami::Dictionary
104
+ customclass = nil
105
+ if obj.class != Origami::Dictionary
106
+ p = (obj.class == Origami::Encoding) ? 0 : 1
107
+ customclass = obj.class.to_s.split('::')[p..-1].join('::') # strip Origami prefix if there is no collision
108
+ end
109
+ dictionaryToRuby(obj, inclevel, internalname, customclass)
110
+ when Origami::Array
111
+ arrayToRuby(obj, inclevel, internalname)
112
+ when Origami::Stream
113
+ streamToRuby(obj, internalname) unless obj.is_a?(ObjectStream) or obj.is_a?(XRefStream)
114
+ when Origami::Name
115
+ nameToRuby(obj)
116
+ when Origami::Reference
117
+ referenceToRuby(obj, internalname)
118
+ else
119
+ raise RuntimeError, "Unknown object type: #{obj.class}"
120
+ end
121
121
 
122
- case obj
122
+ case obj
123
123
  when Origami::String, Origami::Dictionary, Origami::Array, Origami::Name
124
- code << ".to_o" if do_convert
125
- end
124
+ code << ".to_o" if do_convert
125
+ end
126
126
 
127
- code
127
+ code
128
128
  end
129
129
 
130
130
  def referenceToRuby(ref, internalname)
131
- varname = @var_hash[ref]
131
+ varname = @var_hash[ref]
132
132
 
133
- if varname.nil?
134
- "nil"
135
- elsif @obj_route[0..@current_idx].include?(varname)
136
- @code_hash[varname] ||= {}
137
- @code_hash[varname][:afterDecl] ||= []
138
- @code_hash[varname][:afterDecl] << "#{internalname} = #{varname}"#.to_o.set_indirect(true)"
139
-
140
- "nil"
141
- else
142
- @obj_route.push(varname) unless @obj_route.include?(varname)
143
- varname
144
- end
133
+ if varname.nil?
134
+ "nil"
135
+ elsif @obj_route[0..@current_idx].include?(varname)
136
+ @code_hash[varname] ||= {}
137
+ @code_hash[varname][:afterDecl] ||= []
138
+ @code_hash[varname][:afterDecl] << "#{internalname} = #{varname}"#.to_o.set_indirect(true)"
139
+
140
+ "nil"
141
+ else
142
+ @obj_route.push(varname) unless @obj_route.include?(varname)
143
+ varname
144
+ end
145
145
  end
146
146
 
147
147
  def nameToRuby(name)
148
- code = ':'
149
- valid = (name.value.to_s =~ /[+.:-]/).nil?
148
+ code = ':'
149
+ valid = (name.value.to_s =~ /[+.:-]/).nil?
150
150
 
151
- code << '"' unless valid
152
- code << name.value.to_s
153
- code << '"' unless valid
151
+ code << '"' unless valid
152
+ code << name.value.to_s
153
+ code << '"' unless valid
154
154
 
155
- code
155
+ code
156
156
  end
157
157
 
158
158
  def arrayToRuby(arr, inclevel, internalname)
159
- i = 0
160
- code = "\n" + " " * inclevel + "["
161
- arr.each do |obj|
162
- subintname = "#{internalname}[#{i}]"
163
-
164
- code << "#{objectToRuby(obj, inclevel + 1, subintname)}"
165
- code << ", " unless i == arr.length - 1
166
- i = i + 1
167
- end
168
- code << "]"
169
-
170
- code
159
+ i = 0
160
+ code = "\n" + " " * inclevel + "["
161
+ arr.each do |obj|
162
+ subintname = "#{internalname}[#{i}]"
163
+
164
+ code << "#{objectToRuby(obj, inclevel + 1, subintname)}"
165
+ code << ", " unless i == arr.length - 1
166
+ i = i + 1
167
+ end
168
+ code << "]"
169
+
170
+ code
171
171
  end
172
172
 
173
173
  def dictionaryToRuby(dict, inclevel, internalname, customtype = nil)
174
- i = 0
175
- code = "\n" + " " * inclevel
176
-
177
- if customtype
178
- code << "#{customtype}.new(#{dictionaryToHashMap(dict, inclevel, internalname)}"
179
- code << " " * inclevel + ")"
180
- else
181
- code << "{\n"
182
- dict.each_pair do |key, val|
183
- rubyname = nameToRuby(key)
184
- subintname = "#{internalname}[#{rubyname}]"
185
-
186
- if val.is_a?(Origami::Reference) and @var_hash[val] and @var_hash[val][0,3] == "obj"
187
- oldname = @var_hash[val]
188
- newname = (key.value.to_s.downcase + "_" + @var_hash[val][4..-1]).gsub('.','_')
174
+ i = 0
175
+ code = "\n" + " " * inclevel
189
176
 
190
- if not @obj_route.include?(oldname)
191
- @var_hash[val] = newname
192
- @code_hash[newname] = @code_hash[oldname]
193
- @code_hash.delete(oldname)
177
+ if customtype
178
+ code << "#{customtype}.new(#{dictionaryToHashMap(dict, inclevel, internalname)}"
179
+ code << " " * inclevel + ")"
180
+ else
181
+ code << "{\n"
182
+ dict.each_pair do |key, val|
183
+ rubyname = nameToRuby(key)
184
+ subintname = "#{internalname}[#{rubyname}]"
185
+
186
+ if val.is_a?(Origami::Reference) and @var_hash[val] and @var_hash[val][0,3] == "obj"
187
+ oldname = @var_hash[val]
188
+ newname = (key.value.to_s.downcase.gsub(/[^[[:alnum:]]]/,'_') + "_" + @var_hash[val][4..-1]).gsub('.','_')
189
+
190
+ if not @obj_route.include?(oldname)
191
+ @var_hash[val] = newname
192
+ @code_hash[newname] = @code_hash[oldname]
193
+ @code_hash.delete(oldname)
194
+ end
195
+ end
196
+
197
+ code << " " * (inclevel + 1) +
198
+ "#{rubyname} => #{objectToRuby(val, inclevel + 2, subintname)}"
199
+ code << ", " unless i == dict.length - 1
200
+
201
+ i = i + 1
202
+ code << "\n"
194
203
  end
195
- end
196
-
197
- code << " " * (inclevel + 1) +
198
- "#{rubyname} => #{objectToRuby(val, inclevel + 2, subintname)}"
199
- code << ", " unless i == dict.length - 1
200
-
201
- i = i + 1
202
- code << "\n"
204
+
205
+ code << " " * inclevel + "}"
203
206
  end
204
- code << " " * inclevel + "}"
205
- end
206
207
 
207
- code
208
+ code
208
209
  end
209
210
 
210
211
  def dictionaryToHashMap(dict, inclevel, internalname)
211
- i = 0
212
- code = "\n"
213
- dict.each_pair do |key, val|
214
- rubyname = nameToRuby(key)
215
- subintname = "#{internalname}[#{rubyname}]"
216
-
217
- if val.is_a?(Origami::Reference) and @var_hash[val] and @var_hash[val][0,3] == "obj"
218
- oldname = @var_hash[val]
219
- newname = (key.value.to_s.downcase + "_" + @var_hash[val][4..-1]).gsub('.','_')
220
-
221
- if not @obj_route.include?(oldname)
222
- @var_hash[val] = newname
223
- @code_hash[newname] = @code_hash[oldname]
224
- @code_hash.delete(oldname)
225
- end
226
- end
212
+ i = 0
213
+ code = "\n"
214
+ dict.each_pair do |key, val|
215
+ rubyname = nameToRuby(key)
216
+ subintname = "#{internalname}[#{rubyname}]"
217
+
218
+ if val.is_a?(Origami::Reference) and @var_hash[val] and @var_hash[val][0,3] == "obj"
219
+ oldname = @var_hash[val]
220
+ newname = (key.value.to_s.downcase + "_" + @var_hash[val][4..-1]).gsub('.','_')
221
+
222
+ if not @obj_route.include?(oldname)
223
+ @var_hash[val] = newname
224
+ @code_hash[newname] = @code_hash[oldname]
225
+ @code_hash.delete(oldname)
226
+ end
227
+ end
227
228
 
228
- code << " " * (inclevel + 1) +
229
- "#{rubyname} => #{objectToRuby(val, inclevel + 2, subintname)}"
230
- code << ", " unless i == dict.length - 1
231
- i = i + 1
232
- code << "\n"
233
- end
229
+ code << " " * (inclevel + 1) +
230
+ "#{rubyname} => #{objectToRuby(val, inclevel + 2, subintname)}"
231
+ code << ", " unless i == dict.length - 1
232
+ i = i + 1
233
+ code << "\n"
234
+ end
234
235
 
235
- code
236
+ code
236
237
  end
237
238
 
238
239
  def streamToRuby(stm, internalname)
239
- dict = stm.dictionary.dup.delete_if{|k,v| k == :Length or k == :Filter}
240
-
241
- code = "Stream.new("
242
-
243
- if @options[:xstreams]
244
- stmdir = "#{TARGET_DIR}/#{STREAM_DIR}"
245
- Dir::mkdir(stmdir) unless File.directory? stmdir
246
- stmfile = "#{stmdir}/stm_#{stm.reference.refno}.data"
247
- File.open(stmfile, "w") do |stmfd|
248
- stmfd.write stm.data
240
+ dict = stm.dictionary.dup.delete_if{|k,v| k == :Length}
241
+
242
+ code = "Stream.new("
243
+
244
+ if @options[:xstreams]
245
+ stmdir = File.join(TARGET_DIR, STREAM_DIR)
246
+ Dir::mkdir(stmdir) unless File.directory? stmdir
247
+ stmfile = File.join(stmdir, "stm_#{stm.reference.refno}.data")
248
+ File.binwrite(stmfile, stm.data)
249
+
250
+ code << "File.binread('#{stmfile}')"
251
+ else
252
+ code << stm.data.inspect << ".b"
249
253
  end
250
254
 
251
- code << "File.read('#{STREAM_DIR}/stm_#{stm.reference.refno}.data')"
252
- else
253
- code << stm.data.inspect
254
- end
255
-
256
- code << ", #{dictionaryToHashMap(dict, 1, internalname)}" unless dict.empty?
257
- code << ")"
258
- if stm.dictionary.has_key? :Filter
259
- code << ".setFilter(#{objectToRuby(stm.Filter, 1, internalname)})"
260
- end
261
-
262
- code
255
+ code << ", #{dictionaryToHashMap(dict, 1, internalname)}" unless dict.empty?
256
+ code << ")"
257
+
258
+ code
263
259
  end
264
260
 
265
- Console.colorprint "[*] ", Console::Colors::RED
266
- puts "Loading document '#{TARGET}'"
267
- verbosity = @options[:verbose] ? Parser::VERBOSE_INSANE : Parser::VERBOSE_QUIET
268
- target = PDF.read(TARGET, :verbosity => verbosity)
269
- Console.colorprint "[*] ", Console::Colors::RED
270
- puts "Document successfully loaded into Origami"
261
+ puts "[*] ".red + "Loading document '#{TARGET}'"
262
+
263
+ verbosity = @options[:verbose] ? Parser::VERBOSE_TRACE : Parser::VERBOSE_QUIET
264
+ target = PDF.read(TARGET, verbosity: verbosity)
265
+ puts "[*] ".red + "Document successfully loaded into Origami"
271
266
 
272
267
  Dir::mkdir(TARGET_DIR) unless File.directory? TARGET_DIR
273
268
  fd = File.open(TARGET_FILE, 'w', 0700)
274
269
 
275
270
  DOCREF = "pdf"
276
- ORIGAMI_PATH = ORIGAMIDIR[0,1] == '/' ?
277
- ORIGAMIDIR :
278
- "../#{ORIGAMIDIR}"
279
271
 
280
272
  fd.puts <<RUBY
281
273
  #!/usr/bin/env ruby
282
274
 
283
275
  begin
284
- require 'origami'
276
+ require 'origami'
285
277
  rescue LoadError
286
- ORIGAMIDIR = "#{ORIGAMI_PATH}"
287
- $: << ORIGAMIDIR
288
- require 'origami'
278
+ $: << "#{File.join(__dir__, '../lib')}"
279
+ require 'origami'
289
280
  end
290
281
  include Origami
282
+ using Origami::TypeConversion
283
+
284
+ # Disable automatic type casting.
285
+ Origami::OPTIONS[:enable_type_guessing] = false
291
286
 
292
287
  OUTPUT = "\#{File.basename(__FILE__, '.rb')}.pdf"
293
288
 
@@ -298,50 +293,42 @@ OUTPUT = "\#{File.basename(__FILE__, '.rb')}.pdf"
298
293
 
299
294
  RUBY
300
295
 
301
- Console.colorprint "[*] ", Console::Colors::RED
302
- puts "Retrieving all indirect objects..."
303
- roots = target.root_objects
304
- roots.each do |obj|
305
- varname = "obj_" + obj.no.to_s
306
- @var_hash[obj.reference] = varname
296
+ puts "[*] ".red + "Retrieving all indirect objects..."
297
+ target.each_object(compressed: true) do |obj|
298
+ varname = "obj_" + obj.no.to_s
299
+ @var_hash[obj.reference] = varname
307
300
  end
308
301
 
309
- Console.colorprint "[*] ", Console::Colors::RED
310
- puts "Retrieving the document Catalog..."
302
+ puts "[*] ".red + "Retrieving the document Catalog..."
311
303
  catalog = target.Catalog
312
304
 
313
305
  @var_hash[catalog.reference] = "#{DOCREF}.Catalog"
314
306
  @obj_route.push "#{DOCREF}.Catalog"
315
307
 
316
- Console.colorprint "[*] ", Console::Colors::RED
317
- puts "Processing the object hierarchy..."
308
+ puts "[*] ".red + "Processing the object hierarchy..."
318
309
  @current_idx = 0
319
310
  while @current_idx != @obj_route.size
320
- varname = @obj_route[@current_idx]
321
- if RUBY_VERSION < '1.9'
322
- obj = target[@var_hash.index(varname)]
323
- else
311
+ varname = @obj_route[@current_idx]
324
312
  obj = target[@var_hash.key(varname)]
325
- end
326
-
327
- @code_hash[varname] ||= {}
328
- @code_hash[varname][:body] = objectToRuby(obj, 0, varname, true)
329
313
 
330
- @current_idx = @current_idx + 1
314
+ @code_hash[varname] ||= {}
315
+ @code_hash[varname][:body] = objectToRuby(obj, 0, varname, true)
316
+
317
+ @current_idx = @current_idx + 1
331
318
  end
332
319
 
333
320
  @obj_route.reverse.each do |varname|
334
- fd.puts "#{varname} = #{@code_hash[varname][:body]}"
335
- if @code_hash[varname][:afterDecl]
336
- @code_hash[varname][:afterDecl].each do |decl|
337
- fd.puts decl
321
+ fd.puts "#{varname} = #{@code_hash[varname][:body]}"
322
+ if @code_hash[varname][:afterDecl]
323
+ @code_hash[varname][:afterDecl].each do |decl|
324
+ fd.puts decl
325
+ end
338
326
  end
339
- end
340
- fd.puts
327
+ fd.puts
341
328
  end
342
329
 
343
330
  @obj_route.each do |varname|
344
- fd.puts "#{DOCREF}.insert(#{varname})" unless varname == "#{DOCREF}.Catalog"
331
+ fd.puts "#{DOCREF}.insert(#{varname})" unless varname == "#{DOCREF}.Catalog"
345
332
  end
346
333
  fd.puts
347
334
 
@@ -350,11 +337,8 @@ fd.puts <<RUBY
350
337
  # Saves the document.
351
338
  #
352
339
  #{DOCREF}.save(OUTPUT)
353
-
354
340
  RUBY
355
341
 
356
- Console.colorprint "[*] ", Console::Colors::RED
357
- puts "Successfully generated script '#{TARGET_FILE}'"
358
- fd.close
359
- exit
342
+ puts "[*] ".red + "Successfully generated script '#{TARGET_FILE}'"
360
343
 
344
+ fd.close