origami 1.2.7 → 2.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 (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,21 +1,20 @@
1
1
  =begin
2
2
 
3
- = File
4
- parsers/fdf.rb
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
5
5
 
6
- = Info
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.
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.
11
10
 
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.
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.
16
15
 
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/>.
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/>.
19
18
 
20
19
  =end
21
20
 
@@ -23,26 +22,35 @@ require 'origami/parser'
23
22
 
24
23
  module Origami
25
24
 
26
- class FDF
27
- class Parser < Origami::Parser
28
- def parse(stream) #:nodoc:
29
- super
30
-
31
- fdf = Adobe::FDF.new
32
- fdf.header = Adobe::FDF::Header.parse(stream)
33
- @options[:callback].call(fdf.header)
34
-
35
- loop do
36
- break if (object = parse_object).nil?
37
- fdf << object
38
- end
39
-
40
- fdf.revisions.first.xreftable = parse_xreftable
41
- fdf.revisions.first.trailer = parse_trailer
25
+ class FDF
26
+ class Parser < Origami::Parser
27
+ def parse(stream) #:nodoc:
28
+ super(stream)
29
+
30
+ fdf = FDF.new
31
+ fdf.header = FDF::Header.parse(@data)
32
+ @options[:callback].call(fdf.header)
33
+
34
+ loop do
35
+ break if (object = parse_object).nil?
36
+ fdf.insert(object)
37
+ end
38
+
39
+ fdf.revisions.first.xreftable = parse_xreftable
40
+ fdf.revisions.first.trailer = parse_trailer
41
+
42
+ if Origami::OPTIONS[:enable_type_propagation]
43
+ trailer = fdf.revisions.first.trailer
42
44
 
43
- fdf
44
- end
45
+ if trailer[:Root].is_a?(Reference)
46
+ fdf.cast_object(trailer[:Root], FDF::Catalog, self)
47
+ end
48
+
49
+ propagate_types(fdf)
50
+ end
51
+
52
+ fdf
53
+ end
54
+ end
45
55
  end
46
- end
47
56
  end
48
-
@@ -1,115 +1,95 @@
1
1
  =begin
2
2
 
3
- = File
4
- parsers/pdf.rb
5
-
6
- = Info
7
- This file is part of Origami, PDF manipulation framework for Ruby
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- Origami is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU Lesser 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
- Origami 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 Lesser General Public License for more details.
20
-
21
- You should have received a copy of the GNU Lesser General Public License
22
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
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/>.
23
18
 
24
19
  =end
25
20
 
26
21
  require 'origami/parser'
27
22
 
28
23
  module Origami
29
-
30
- class PDF
31
- class Parser < Origami::Parser
32
- def initialize(params = {})
33
- options =
34
- {
35
- :password => '', # Default password being tried when opening a protected document.
36
- :prompt_password => Proc.new {
37
- print "Password: "
38
- gets.chomp
39
- }, # Callback procedure to prompt password when document is encrypted.
40
- :force => false # Force PDF header detection
41
- }.update(params)
42
-
43
- super(options)
44
- end
45
-
46
- private
47
-
48
- def parse_initialize #:nodoc:
49
- if @options[:force] == true
50
- @data.skip_until(/%PDF-/).nil?
51
- @data.pos = @data.pos - 5
52
- end
53
24
 
54
- pdf = PDF.new(self)
55
-
56
- info "...Reading header..."
57
- begin
58
- pdf.header = PDF::Header.parse(@data)
59
- @options[:callback].call(pdf.header)
60
- rescue InvalidHeaderError => e
61
- if @options[:ignore_errors] == true
62
- warn "PDF header is invalid, ignoring..."
63
- else
64
- raise e
65
- end
66
- end
25
+ class PDF
26
+ class Parser < Origami::Parser
27
+ def initialize(params = {})
28
+ options =
29
+ {
30
+ password: '', # Default password being tried when opening a protected document.
31
+ prompt_password: lambda do # Callback procedure to prompt password when document is encrypted.
32
+ require 'io/console'
33
+ STDERR.print "Password: "
34
+ STDIN.noecho(&:gets).chomp
35
+ end,
36
+ force: false # Force PDF header detection
37
+ }.update(params)
38
+
39
+ super(options)
40
+ end
67
41
 
68
- pdf
69
- end
42
+ private
70
43
 
71
- def parse_finalize(pdf) #:nodoc:
72
- warn "This file has been linearized." if pdf.is_linearized?
44
+ def parse_initialize #:nodoc:
45
+ if @options[:force] == true
46
+ @data.skip_until(/%PDF-/).nil?
47
+ @data.pos = @data.pos - 5
48
+ end
73
49
 
74
- if Origami::OPTIONS[:enable_type_propagation]
75
- info "...Propagating types..."
76
- @deferred_casts.each_pair do |ref, type|
77
- type = [ type ] unless type.is_a?(::Array)
78
- type.each do |hint|
79
- pdf.cast_object(ref, hint)
80
- end
81
- end
82
- end
50
+ pdf = PDF.new(self)
83
51
 
84
- #
85
- # Decrypt encrypted file contents
86
- #
87
- if pdf.is_encrypted?
88
- warn "This document contains encrypted data!"
89
-
90
- passwd = @options[:password]
91
- begin
92
- pdf.decrypt(passwd)
93
- rescue EncryptionInvalidPasswordError
94
- if passwd.empty?
95
- passwd = @options[:prompt_password].call
96
- retry unless passwd.empty?
52
+ info "...Reading header..."
53
+ begin
54
+ pdf.header = PDF::Header.parse(@data)
55
+ @options[:callback].call(pdf.header)
56
+ rescue InvalidHeaderError
57
+ raise unless @options[:ignore_errors]
58
+ warn "PDF header is invalid, ignoring..."
59
+ end
60
+
61
+ pdf
97
62
  end
98
63
 
99
- raise EncryptionInvalidPasswordError
100
- end
101
- end
64
+ def parse_finalize(pdf) #:nodoc:
65
+ warn "This file has been linearized." if pdf.linearized?
102
66
 
103
- if pdf.is_signed?
104
- warn "This document has been signed!"
105
- end
67
+ propagate_types(pdf) if Origami::OPTIONS[:enable_type_propagation]
106
68
 
107
- pdf
108
- end
109
- end
110
- end
69
+ #
70
+ # Decrypt encrypted file contents
71
+ #
72
+ if pdf.encrypted?
73
+ warn "This document contains encrypted data!"
111
74
 
112
- end
75
+ passwd = @options[:password]
76
+ begin
77
+ pdf.decrypt(passwd)
78
+ rescue EncryptionInvalidPasswordError
79
+ if passwd.empty?
80
+ passwd = @options[:prompt_password].call
81
+ retry unless passwd.empty?
82
+ end
113
83
 
114
- require 'origami/parsers/pdf/linear'
84
+ raise
85
+ end
86
+ end
115
87
 
88
+ warn "This document has been signed!" if pdf.signed?
89
+
90
+ pdf
91
+ end
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,137 @@
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
+
22
+ require 'origami/parsers/pdf'
23
+
24
+ module Origami
25
+
26
+ class PDF
27
+
28
+ #
29
+ # Create a new PDF lazy Parser.
30
+ #
31
+ class LazyParser < Parser
32
+ def parse(stream)
33
+ super
34
+
35
+ pdf = parse_initialize
36
+ revisions = []
37
+
38
+ # Set the scanner position at the end.
39
+ @data.terminate
40
+
41
+ # Locate the startxref token.
42
+ until @data.match?(/#{Trailer::XREF_TOKEN}/)
43
+ raise ParsingError, "No xref token found" if @data.pos == 0
44
+ @data.pos -= 1
45
+ end
46
+
47
+ # Extract the offset of the last xref section.
48
+ trailer = Trailer.parse(@data, self)
49
+ raise ParsingError, "Cannot locate xref section" if trailer.startxref.zero?
50
+
51
+ xref_offset = trailer.startxref
52
+ while xref_offset and xref_offset != 0
53
+
54
+ # Create a new revision based on the xref section offset.
55
+ revision = parse_revision(pdf, xref_offset)
56
+
57
+ # Locate the previous xref section.
58
+ if revision.xrefstm
59
+ xref_offset = revision.xrefstm[:Prev].to_i
60
+ else
61
+ xref_offset = revision.trailer[:Prev].to_i
62
+ end
63
+
64
+ # Prepend the revision.
65
+ revisions.unshift(revision)
66
+ end
67
+
68
+ pdf.revisions.clear
69
+ revisions.each do |rev|
70
+ pdf.revisions.push(rev)
71
+ pdf.insert(rev.xrefstm) if rev.has_xrefstm?
72
+ end
73
+
74
+ parse_finalize(pdf)
75
+
76
+ pdf
77
+ end
78
+
79
+ private
80
+
81
+ def parse_revision(pdf, offset)
82
+ raise ParsingError, "Invalid xref offset" if offset < 0 or offset >= @data.string.size
83
+
84
+ @data.pos = offset
85
+
86
+ # Create a new revision.
87
+ revision = PDF::Revision.new(pdf)
88
+
89
+ # Regular xref section.
90
+ if @data.match?(/#{XRef::Section::TOKEN}/)
91
+ xreftable = parse_xreftable
92
+ raise ParsingError, "Cannot parse xref section" if xreftable.nil?
93
+
94
+ revision.xreftable = xreftable
95
+ revision.trailer = parse_trailer
96
+
97
+ # Handle hybrid cross-references.
98
+ if revision.trailer[:XRefStm].is_a?(Integer)
99
+ begin
100
+ offset = revision.trailer[:XRefStm].to_i
101
+ xrefstm = parse_object(offset)
102
+
103
+ if xrefstm.is_a?(XRefStream)
104
+ revision.xrefstm = xrefstm
105
+ else
106
+ warn "Invalid xref stream at offset #{offset}"
107
+ end
108
+
109
+ rescue
110
+ warn "Cannot parse xref stream at offset #{offset}"
111
+ end
112
+ end
113
+
114
+ # The xrefs are stored in a stream.
115
+ else
116
+ xrefstm = parse_object
117
+ raise ParsingError, "Invalid xref stream" unless xrefstm.is_a?(XRefStream)
118
+
119
+ revision.xrefstm = xrefstm
120
+
121
+ # Search for the trailer.
122
+ if @data.skip_until Regexp.union(Trailer::XREF_TOKEN, *Trailer::TOKENS)
123
+ @data.pos -= @data.matched_size
124
+
125
+ revision.trailer = parse_trailer
126
+ else
127
+ warn "No trailer found."
128
+ revision.trailer = Trailer.new
129
+ end
130
+ end
131
+
132
+ revision
133
+ end
134
+ end
135
+ end
136
+
137
+ end
@@ -1,85 +1,83 @@
1
1
  =begin
2
2
 
3
- = File
4
- parsers/linear.rb
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
5
5
 
6
- = Info
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.
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.
11
10
 
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.
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.
16
15
 
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/>.
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/>.
19
18
 
20
19
  =end
21
20
 
22
21
 
23
- require 'origami/parser'
24
- require 'origami/pdf'
22
+ require 'origami/parsers/pdf'
25
23
 
26
24
  module Origami
27
25
 
28
- class PDF
29
-
30
- #
31
- # Create a new PDF linear Parser.
32
- #
33
- class LinearParser < Parser
34
- def parse(stream)
35
- super
36
-
37
- pdf = parse_initialize
26
+ class PDF
38
27
 
39
28
  #
40
- # Parse each revision
29
+ # Create a new PDF linear Parser.
41
30
  #
42
- revision = 0
43
- until @data.eos? do
44
-
45
- begin
46
- pdf.add_new_revision unless revision.zero?
47
- revision = revision + 1
48
-
49
- info "...Parsing revision #{pdf.revisions.size}..."
50
- loop do
51
- break if (object = parse_object).nil?
52
- pdf.insert(object)
31
+ class LinearParser < Parser
32
+ def parse(stream)
33
+ super
34
+
35
+ pdf = parse_initialize
36
+
37
+ #
38
+ # Parse each revision
39
+ #
40
+ revision = 0
41
+ until @data.eos? do
42
+ begin
43
+ pdf.add_new_revision unless revision.zero?
44
+ revision = revision + 1
45
+
46
+ info "...Parsing revision #{pdf.revisions.size}..."
47
+ loop do
48
+ break if (object = parse_object).nil?
49
+ pdf.insert(object)
50
+ end
51
+
52
+ pdf.revisions.last.xreftable = parse_xreftable
53
+
54
+ trailer = parse_trailer
55
+ pdf.revisions.last.trailer = trailer
56
+
57
+ if trailer.startxref != 0
58
+ xrefstm = pdf.get_object_by_offset(trailer.startxref)
59
+ elsif trailer[:XRefStm].is_a?(Integer)
60
+ xrefstm = pdf.get_object_by_offset(trailer[:XRefStm])
61
+ end
62
+
63
+ if xrefstm.is_a?(XRefStream)
64
+ warn "Found a XRefStream for this revision at #{xrefstm.reference}"
65
+ pdf.revisions.last.xrefstm = xrefstm
66
+ end
67
+
68
+ rescue
69
+ error "Cannot read : " + (@data.peek(10) + "...").inspect
70
+ error "Stopped on exception : " + $!.message
71
+
72
+ break
73
+ end
74
+ end
75
+
76
+ pdf.loaded!
77
+
78
+ parse_finalize(pdf)
53
79
  end
54
-
55
- pdf.revisions.last.xreftable = parse_xreftable
56
-
57
- trailer = parse_trailer
58
- pdf.revisions.last.trailer = trailer
59
-
60
- xrefstm = pdf.get_object_by_offset(trailer.startxref) ||
61
- (pdf.get_object_by_offset(trailer.XRefStm) if trailer.has_field? :XRefStm)
62
-
63
- if not xrefstm.nil?
64
- warn "Found a XRefStream for this revision at #{xrefstm.reference}"
65
- pdf.revisions.last.xrefstm = xrefstm
66
- end
67
-
68
- rescue SystemExit
69
- raise
70
- rescue Exception => e
71
- error "Cannot read : " + (@data.peek(10) + "...").inspect
72
- error "Stopped on exception : " + e.message
73
-
74
- break
75
- end
76
-
77
80
  end
78
-
79
- parse_finalize(pdf)
80
- end
81
-
82
81
  end
83
- end
84
- end
85
82
 
83
+ end