origami 1.2.3 → 1.2.4

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.
@@ -135,7 +135,7 @@ begin
135
135
 
136
136
  pdf.root_objects.find_all{|obj| obj.is_a?(Stream)}.each do |stream|
137
137
  stream_file = "#{OUTPUT_DIR}/streams/stream_#{stream.reference.refno}.dmp"
138
- File.open(stream_file, "w") do |fd|
138
+ File.open(stream_file, "wb") do |fd|
139
139
  fd.write(stream.data)
140
140
  end
141
141
  nstreams += 1
@@ -150,7 +150,7 @@ begin
150
150
 
151
151
  pdf.ls(/^JS$/).each do |script|
152
152
  script_file = "#{OUTPUT_DIR}/scripts/script_#{script.hash}.js"
153
- File.open(script_file, "w") do |fd|
153
+ File.open(script_file, "wb") do |fd|
154
154
  fd.write(
155
155
  case script
156
156
  when Stream then
@@ -187,7 +187,7 @@ begin
187
187
  xfadoc = REXML::Document.new(xml)
188
188
  REXML::XPath.match(xfadoc, "//script").each do |script|
189
189
  script_file = "#{OUTPUT_DIR}/script_#{script.hash}.js"
190
- File.open(script_file, 'w') do |fd|
190
+ File.open(script_file, "wb") do |fd|
191
191
  fd.write(script.text)
192
192
  end
193
193
  nscripts += 1
@@ -205,7 +205,7 @@ begin
205
205
  attached_file = "#{OUTPUT_DIR}/attachments/attached_#{File.basename(name)}"
206
206
  spec = attachment.solve
207
207
  if spec and spec.EF and f = spec.EF.F and f.is_a?(Stream)
208
- File.open(attached_file, "w") do |fd|
208
+ File.open(attached_file, "wb") do |fd|
209
209
  fd.write(f.data)
210
210
  end
211
211
  nattach += 1
@@ -223,7 +223,7 @@ begin
223
223
  font = stream.xrefs.find{|obj| obj.is_a?(FontDescriptor)}
224
224
  if font
225
225
  font_file = "#{OUTPUT_DIR}/fonts/font_#{File.basename(font.FontName.value.to_s)}"
226
- File.open(font_file, "w") do |fd|
226
+ File.open(font_file, "wb") do |fd|
227
227
  fd.write(stream.data)
228
228
  end
229
229
  nfonts += 1
@@ -239,7 +239,7 @@ begin
239
239
 
240
240
  pdf.root_objects.find_all{|obj| obj.is_a?(MetadataStream)}.each do |stream|
241
241
  metadata_file = "#{OUTPUT_DIR}/metadata/metadata_#{stream.reference.refno}.xml"
242
- File.open(metadata_file, "w") do |fd|
242
+ File.open(metadata_file, "wb") do |fd|
243
243
  fd.write(stream.data)
244
244
  end
245
245
  nmeta += 1
@@ -261,7 +261,7 @@ begin
261
261
  STDERR.puts "Warning: file '#{image_file}' is intended to be viewed in CMYK color space."
262
262
  end
263
263
 
264
- File.open(image_file, "w") do |fd|
264
+ File.open(image_file, "wb") do |fd|
265
265
  fd.write(image_data)
266
266
  end
267
267
  nimages += 1
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift "#{File.dirname(__FILE__)}" if RUBY_VERSION >= '1.9'
3
+ $:.unshift "#{File.dirname(__FILE__)}"
4
4
  require 'gui/walker'
5
5
 
6
6
  PDFWalker::Walker.start(ARGV[0])
@@ -41,7 +41,7 @@ module Origami
41
41
  end
42
42
  end
43
43
 
44
- unless (RUBY_VERSION < '1.9' and RUBY_PLATFORM =~ /win32/)
44
+ unless RUBY_VERSION < '1.9'
45
45
  require 'tempfile'
46
46
 
47
47
  class Stream
@@ -50,7 +50,7 @@ module Origami
50
50
  tmpfile.write(self.data)
51
51
  tmpfile.close
52
52
 
53
- Process.wait Kernel.spawn "#{editor or 'vim'} #{tmpfile.path}"
53
+ Process.wait Kernel.spawn "#{editor} #{tmpfile.path}"
54
54
 
55
55
  self.data = File.read(tmpfile.path)
56
56
  tmpfile.unlink
@@ -25,7 +25,6 @@
25
25
 
26
26
  require 'digest/md5'
27
27
  require 'digest/sha2'
28
- require 'iconv'
29
28
 
30
29
  module Origami
31
30
 
@@ -115,16 +114,15 @@ module Origami
115
114
  doc_id = doc_id.first
116
115
  end
117
116
 
118
- if handler.is_owner_password?(passwd, doc_id)
117
+ if handler.is_user_password?(passwd, doc_id)
118
+ encryption_key = handler.compute_user_encryption_key(passwd, doc_id)
119
+ elsif handler.is_owner_password?(passwd, doc_id)
119
120
  if handler.V.to_i < 5
120
121
  user_passwd = handler.retrieve_user_password(passwd)
121
122
  encryption_key = handler.compute_user_encryption_key(user_passwd, doc_id)
122
123
  else
123
124
  encryption_key = handler.compute_owner_encryption_key(passwd)
124
125
  end
125
-
126
- elsif handler.is_user_password?(passwd, doc_id)
127
- encryption_key = handler.compute_user_encryption_key(passwd, doc_id)
128
126
  else
129
127
  raise EncryptionInvalidPasswordError
130
128
  end
@@ -1325,10 +1323,10 @@ module Origami
1325
1323
  end
1326
1324
 
1327
1325
  64.times do |j|
1328
- x = aes.update(block)
1329
- unless vector.empty?
1330
- x += aes.update(vector)
1331
- end
1326
+ x = ''
1327
+ x += aes.update(password) unless password.empty?
1328
+ x += aes.update(block)
1329
+ x += aes.update(vector) unless vector.empty?
1332
1330
 
1333
1331
  if j == 0
1334
1332
  block_size = 32 + (x.unpack("C16").inject(0) {|a,b| a+b} % 3) * 16
@@ -30,6 +30,16 @@ module Origami
30
30
  #
31
31
  module Filter
32
32
 
33
+ class InvalidFilterDataError < Exception # :nodoc:
34
+ attr_reader :decoded_data
35
+
36
+ def initialize(message, decoded_data = nil)
37
+ super(message)
38
+
39
+ @decoded_data = decoded_data
40
+ end
41
+ end
42
+
33
43
  module Utils
34
44
 
35
45
  class BitWriterError < Exception #:nodoc:
@@ -27,7 +27,7 @@ module Origami
27
27
 
28
28
  module Filter
29
29
 
30
- class InvalidASCIIHexStringError < Exception #:nodoc:
30
+ class InvalidASCIIHexStringError < InvalidFilterDataError #:nodoc:
31
31
  end
32
32
 
33
33
  #
@@ -64,7 +64,7 @@ module Origami
64
64
 
65
65
  end
66
66
 
67
- class InvalidASCII85StringError < Exception #:nodoc:
67
+ class InvalidASCII85StringError < InvalidFilterDataError #:nodoc:
68
68
  end
69
69
 
70
70
  #
@@ -141,7 +141,7 @@ module Origami
141
141
  codelen = 5
142
142
 
143
143
  if input.length - i < 5
144
- raise InvalidASCII85StringError, "Invalid length" if input.length - i == 1
144
+ raise InvalidASCII85StringError.new("Invalid length", result) if input.length - i == 1
145
145
 
146
146
  addend = 5 - (input.length - i)
147
147
  input << "u" * addend
@@ -152,15 +152,20 @@ module Origami
152
152
  # Checking if this string is in base85
153
153
  5.times do |j|
154
154
  if input[i+j].ord > "u"[0].ord or input[i+j].ord < "!"[0].ord
155
- raise InvalidASCII85StringError, "Invalid character sequence: #{input[i,5].inspect}"
155
+ raise InvalidASCII85StringError.new(
156
+ "Invalid character sequence: #{input[i,5].inspect}",
157
+ result
158
+ )
156
159
  else
157
160
  inblock += (input[i+j].ord - "!"[0].ord) * 85 ** (4 - j)
158
161
  end
159
162
  end
160
163
 
161
- if inblock >= 2**32
162
- raise InvalidASCII85StringError, "Invalid value (#{inblock}) for block #{input[i,5].inspect}"
163
- end
164
+
165
+ raise InvalidASCII85StringError.new(
166
+ "Invalid value (#{inblock}) for block #{input[i,5].inspect}",
167
+ result
168
+ ) if inblock >= 2**32
164
169
 
165
170
  end
166
171
 
@@ -27,7 +27,7 @@ module Origami
27
27
 
28
28
  module Filter
29
29
 
30
- class InvalidCCITTFaxDataError < Exception #:nodoc:
30
+ class InvalidCCITTFaxDataError < InvalidFilterDataError #:nodoc:
31
31
  end
32
32
 
33
33
  class CCITTFaxFilterError < Exception #:nodoc:
@@ -388,8 +388,8 @@ module Origami
388
388
  bitr = Utils::BitReader.new(stream)
389
389
  bitw = Utils::BitWriter.new
390
390
 
391
- current_color = white
392
391
  until bitr.eod? or rows == 0
392
+ current_color = white
393
393
 
394
394
  # realign the read line on a 8-bit boundary if required
395
395
  if aligned and bitr.pos % 8 != 0
@@ -404,7 +404,10 @@ module Origami
404
404
 
405
405
  # checking for the presence of EOL
406
406
  if bitr.peek(EOL[1]) != EOL[0]
407
- raise CCITTFaxFilterError, "No end-of-line pattern found (at bit pos #{bitr.pos}/#{bitr.size}})" if has_eol
407
+ raise InvalidCCITTFaxDataError.new(
408
+ "No end-of-line pattern found (at bit pos #{bitr.pos}/#{bitr.size}})",
409
+ bitw.final.to_s
410
+ )if has_eol
408
411
  else
409
412
  bitr.pos += EOL[1]
410
413
  end
@@ -417,10 +420,16 @@ module Origami
417
420
  bit_length = get_black_bits(bitr)
418
421
  end
419
422
 
420
- raise CCITTFaxFilterError, "Unfinished line (at bit pos #{bitr.pos}/#{bitr.size}})" if bit_length.nil?
423
+ raise InvalidCCITTFaxDataError.new(
424
+ "Unfinished line (at bit pos #{bitr.pos}/#{bitr.size}})",
425
+ bitw.final.to_s
426
+ ) if bit_length.nil?
421
427
 
422
428
  line_length += bit_length
423
- raise CCITTFaxFilterError, "Line is too long (at bit pos #{bitr.pos}/#{bitr.size}})" if line_length > columns
429
+ raise InvalidCCITTFaxDataError.new(
430
+ "Line is too long (at bit pos #{bitr.pos}/#{bitr.size}})",
431
+ bitw.final.to_s
432
+ ) if line_length > columns
424
433
 
425
434
  write_bit_range(bitw, current_color, bit_length)
426
435
  current_color ^= 1
@@ -30,16 +30,7 @@ module Origami
30
30
 
31
31
  module Filter
32
32
 
33
- class InvalidFlateDataError < Exception #:nodoc:
34
- attr_reader :zlib_stream, :zlib_except
35
-
36
- def initialize(zlib_stream, zlib_except)
37
- super(zlib_except.message)
38
-
39
- @zlib_stream = zlib_stream
40
- @zlib_except = zlib_except
41
- end
42
- end
33
+ class InvalidFlateDataError < InvalidFilterDataError; end #:nodoc:
43
34
 
44
35
  #
45
36
  # Class representing a Filter used to encode and decode data with zlib/Flate compression algorithm.
@@ -92,7 +83,7 @@ module Origami
92
83
  begin
93
84
  uncompressed = zlib_stream.inflate(stream)
94
85
  rescue Zlib::DataError => zlib_except
95
- raise InvalidFlateDataError.new(zlib_stream, zlib_except)
86
+ raise InvalidFlateDataError.new(zlib_except.message, zlib_stream.flush_next_out)
96
87
  end
97
88
 
98
89
  if @params.Predictor.is_a?(Integer)
@@ -29,7 +29,7 @@ module Origami
29
29
 
30
30
  module Filter
31
31
 
32
- class InvalidLZWDataError < Exception #:nodoc:
32
+ class InvalidLZWDataError < InvalidFilterDataError #:nodoc:
33
33
  end
34
34
 
35
35
  #
@@ -131,8 +131,10 @@ module Origami
131
131
  when 4095
132
132
  if byte != CLEARTABLE
133
133
  then
134
- raise InvalidLZWDataError,
135
- "LZW table is full and no clear flag was set (codeword #{byte.to_s(2).rjust(codesize,'0')} at bit #{bstring.pos - codesize}/#{bstring.size})"
134
+ raise InvalidLZWDataError.new(
135
+ "LZW table is full and no clear flag was set (codeword #{byte.to_s(2).rjust(codesize,'0')} at bit #{bstring.pos - codesize}/#{bstring.size})",
136
+ result
137
+ )
136
138
  end
137
139
  end
138
140
 
@@ -150,6 +152,11 @@ module Origami
150
152
  result << table.key(byte)
151
153
  redo
152
154
  else
155
+ raise InvalidLZWDataError.new(
156
+ "No entry for codeword #{prevbyte.to_s(2).rjust(codesize,'0')}.",
157
+ result
158
+ ) unless table.key(prevbyte)
159
+
153
160
  if table.has_value?(byte)
154
161
  entry = table.key(byte)
155
162
  else
@@ -27,7 +27,7 @@ module Origami
27
27
 
28
28
  module Filter
29
29
 
30
- class InvalidRunLengthDataError < Exception #:nodoc:
30
+ class InvalidRunLengthDataError < InvalidFilterDataError #:nodoc:
31
31
  end
32
32
 
33
33
  #
@@ -490,13 +490,15 @@ module Origami
490
490
  end
491
491
 
492
492
  def skip_until_next_obj(stream) #:nodoc:
493
- stream.pos += 1 until stream.match?(@@regexp_obj) or
494
- stream.match?(/xref/) or stream.match?(/trailer/) or stream.match?(/startxref/) or
495
- stream.eos?
493
+ [ @@regexp_obj, /xref/, /trailer/, /startxref/ ].each do |re|
494
+ if stream.scan_until(re)
495
+ stream.pos -= stream.matched_size
496
+ return true
497
+ end
498
+ end
496
499
 
497
- not stream.eos?
500
+ false
498
501
  end
499
-
500
502
  end
501
503
 
502
504
  def pdf_version_required #:nodoc:
@@ -45,15 +45,15 @@ module Origami
45
45
  begin
46
46
  pdf.add_new_revision unless revision.zero?
47
47
  revision = revision + 1
48
-
48
+
49
49
  info "...Parsing revision #{pdf.revisions.size}..."
50
50
  loop do
51
51
  break if (object = parse_object).nil?
52
52
  pdf.insert(object)
53
53
  end
54
-
54
+
55
55
  pdf.revisions.last.xreftable = parse_xreftable
56
-
56
+
57
57
  trailer = parse_trailer
58
58
  pdf.revisions.last.trailer = trailer
59
59
 
@@ -61,7 +61,7 @@ module Origami
61
61
  (pdf.get_object_by_offset(trailer.XRefStm) if trailer.has_field? :XRefStm)
62
62
 
63
63
  if not xrefstm.nil?
64
- debug "Found a XRefStream for this revision at #{xrefstm.reference}"
64
+ warn "Found a XRefStream for this revision at #{xrefstm.reference}"
65
65
  pdf.revisions.last.xrefstm = xrefstm
66
66
  end
67
67
 
@@ -70,10 +70,10 @@ module Origami
70
70
  rescue Exception => e
71
71
  error "Cannot read : " + (@data.peek(10) + "...").inspect
72
72
  error "Stopped on exception : " + e.message
73
-
73
+
74
74
  break
75
75
  end
76
-
76
+
77
77
  end
78
78
 
79
79
  parse_finalize(pdf)
@@ -61,8 +61,8 @@ require 'origami/parsers/pdf'
61
61
 
62
62
  module Origami
63
63
 
64
- VERSION = "1.2.3"
65
- REVISION = "$Revision: rev 143/, 2011/10/20 16:22:40 $" #:nodoc:
64
+ VERSION = "1.2.4"
65
+ REVISION = "$Revision$" #:nodoc:
66
66
 
67
67
  #
68
68
  # Global options for Origami.
@@ -249,11 +249,19 @@ module Origami
249
249
  filters = [ filters ] unless filters.is_a?(::Array)
250
250
 
251
251
  @data = @rawdata.dup
252
+ @data.freeze
253
+
252
254
  filters.length.times do |layer|
253
255
  params = dparams[layer].is_a?(Dictionary) ? dparams[layer] : {}
254
256
  filter = filters[layer]
255
257
 
256
- @data = decode_data(@data, filter, params)
258
+ begin
259
+ @data = decode_data(@data, filter, params)
260
+ rescue Filter::InvalidFilterDataError => e
261
+ @data = e.decoded_data if e.decoded_data
262
+ raise InvalidStreamObjectError,
263
+ "Error while decoding stream #{self.reference}\n\t-> [#{e.class}] #{e.message}"
264
+ end
257
265
  end
258
266
  else
259
267
  raise InvalidStreamObjectError, "Invalid Filter type parameter"
@@ -357,15 +365,8 @@ module Origami
357
365
  raise InvalidStreamObjectError, "Unknown filter : #{filter}"
358
366
  end
359
367
 
360
- begin
361
- Origami::Filter.const_get(filter.value.to_s.sub(/Decode$/,"")).decode(data, params)
362
-
363
- rescue Filter::InvalidFlateDataError => flate_e
364
- return flate_e.zlib_stream.flush_next_out
368
+ Origami::Filter.const_get(filter.value.to_s.sub(/Decode$/,"")).decode(data, params)
365
369
 
366
- rescue Exception => e
367
- raise InvalidStreamObjectError, "Error while decoding stream #{self.reference}\n\t-> [#{e.class}] #{e.message}"
368
- end
369
370
  end
370
371
 
371
372
  def encode_data(data, filter, params) #:nodoc:
@@ -125,12 +125,16 @@ module Origami
125
125
  # Convert String object to an UTF8 encoded Ruby string.
126
126
  #
127
127
  def to_utf8
128
- require 'iconv'
129
-
130
128
  infer_encoding
131
- i = Iconv.new("UTF-8", "UTF-16")
132
- utf8str = i.iconv(self.encoding.to_utf16be(self.value))
133
- i.close
129
+
130
+ if RUBY_VERSION < '1.9'
131
+ require 'iconv'
132
+ i = Iconv.new("UTF-8", "UTF-16")
133
+ utf8str = i.iconv(self.encoding.to_utf16be(self.value))
134
+ i.close
135
+ else
136
+ utf8str = self.encoding.to_utf16be(self.value).encode("utf-8", "utf-16")
137
+ end
134
138
 
135
139
  utf8str
136
140
  end