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,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