origami 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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