combine_pdf 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0cdaac783f68294ad27e5b4debc724f56190fc02
4
- data.tar.gz: c31baf6a9e9fc4076b1d28abafde4e383d797b1f
3
+ metadata.gz: 40bc13d0d602d989d06580fd8d18d4bff8fd825b
4
+ data.tar.gz: 5c516b4f7f241018ace628f5b30df65074f416d4
5
5
  SHA512:
6
- metadata.gz: 10ec2ba8ab2885d7f99cab5c7bcd7feaf22408d8e4da66e0ab3fc2f57ab0c5ba52e9325e3c110642b03a2309561d0494bfaab7b37126c949937f55e66a22ef29
7
- data.tar.gz: 3650485fcdbafbd255912365bc6ffee8acd86b16cf07e71653388972ed2fb78f27305ca5b8c4f51303e45b3f59f6d468c8dbdaa180e084aff1045bc5e01c8659
6
+ metadata.gz: d0a892d29ba0e918ea707a1e0206768450966a35643ed4bab825fe5ce1fea24091b9de8e0d033dba70b3cc5f8052c95f3f58238fc06b644c0ac8c63f85008ce4
7
+ data.tar.gz: bc3d9c23a738c4f282fd00b213fb0352fe4cf9275f1b54c9b9d92c0f63d0a1bacffd1faa2151310f91bbbb01e2e7244f1c5303b423135659f84a5424f33beccf
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ***
4
4
 
5
+ Change log v.0.1.11
6
+
7
+ **fix**: fixed a bug where Page Resources and ColorSpace data wouldn't be inherited correctly from the Catalog and Pages parent objects. This issue could cause pages to render without all their content intact. This issue is now fixed (although more testing should be done for multiple inheritance).
8
+
9
+ **?fix?** Attempted to fix [the issue reported by srogers](https://github.com/boazsegev/combine_pdf/issues/10), by forcing all String byte collections to return an Array. waiting confirmation for fix (couldn't reproduce the issue just yet, as I can't seem to install Ruby MRI 1.9.3 on my mac).
10
+
11
+ ***
12
+
5
13
  Change log v.0.1.10
6
14
 
7
15
  **fix**: fixed a typo that prevented access to the CombinePDF::VERSION constant.
@@ -69,7 +69,7 @@ module CombinePDF
69
69
 
70
70
  def set_general_key(password = "")
71
71
  # 1) make sure the initial key is 32 byte long (if no password, uses padding).
72
- key = (password.bytes[0..32] + @padding_key)[0..31].pack('C*').force_encoding(Encoding::ASCII_8BIT)
72
+ key = (password.bytes[0..32].to_a + @padding_key)[0..31].to_a.pack('C*').force_encoding(Encoding::ASCII_8BIT)
73
73
  # 2) add the value of the encryption dictionary’s O entry
74
74
  key << @encryption_dictionary[:O].to_s
75
75
  # 3) Convert the integer value of the P entry to a 32-bit unsigned binary number
@@ -34,6 +34,7 @@ module CombinePDF
34
34
  #
35
35
  # object:: object to decompress.
36
36
  def inflate_object object = nil
37
+ return false unless object.is_a?(Hash)
37
38
  filter_array = object[:Filter]
38
39
  if filter_array.is_a?(Hash) && filter_array[:is_reference_only]
39
40
  filter_array = filter_array[:referenced_object]
@@ -348,7 +348,7 @@ module CombinePDF
348
348
  # b) Any character in a name that is a regular character (other than NUMBER SIGN) shall be written as itself or by using its 2-digit hexadecimal code, preceded by the NUMBER SIGN.
349
349
  # c) Any character that is not a regular character shall be written using its 2-digit hexadecimal code, preceded by the NUMBER SIGN only.
350
350
  # [0x00, 0x09, 0x0a, 0x0c, 0x0d, 0x20, 0x28, 0x29, 0x3c, 0x3e, 0x5b, 0x5d, 0x7b, 0x7d, 0x2f, 0x25]
351
- out = object.to_s.bytes.map do |b|
351
+ out = object.to_s.bytes.to_a.map do |b|
352
352
  case b
353
353
  when 0..15
354
354
  '#0' + b.to_s(16)
@@ -237,7 +237,7 @@ module CombinePDF
237
237
  str << 8
238
238
  when 102 #f
239
239
  str << 255
240
- when 48..57 #decimal notation for byte?
240
+ when 48..57 #octal notation for byte?
241
241
  rep = rep.chr
242
242
  rep += str_bytes.shift.chr if str_bytes[0].between?(48,57)
243
243
  rep += str_bytes.shift.chr if str_bytes[0].between?(48,57) && ((rep + str_bytes[0].chr).to_i <= 255)
@@ -144,7 +144,7 @@ module CombinePDF
144
144
 
145
145
  #collect objects and set xref table locations
146
146
  loc = 0
147
- out.each {|line| loc += line.bytes.length + 1}
147
+ out.each {|line| loc += line.bytesize + 1}
148
148
  @objects.each do |o|
149
149
  indirect_object_count += 1
150
150
  xref << loc
@@ -152,7 +152,7 @@ module CombinePDF
152
152
  loc += out.last.length + 1
153
153
  end
154
154
  xref_location = 0
155
- out.each { |line| xref_location += line.bytes.length + 1}
155
+ out.each { |line| xref_location += line.bytesize + 1}
156
156
  out << "xref\n\r0 #{(indirect_object_count).to_s}\n\r0000000000 65535 f \n\r"
157
157
  xref.each {|offset| out << ( out.pop + ("%010d 00000 n \n\r" % offset) ) }
158
158
  out << out.pop + "trailer"
@@ -197,7 +197,7 @@ module CombinePDF
197
197
  #
198
198
  # catalogs:: a catalog, or an Array of catalog objects. defaults to the existing catalog.
199
199
  # secure_injection:: a boolean (true / false) controling the behavior of the << operator.
200
- def pages(catalogs = nil, secure_injection = true)
200
+ def pages(catalogs = nil, secure_injection = true, inheritance_hash = {})
201
201
  page_list = []
202
202
  if catalogs == nil
203
203
  catalogs = @objects.select {|obj| obj.is_a?(Hash) && obj[:Type] == :Catalog}
@@ -205,16 +205,24 @@ module CombinePDF
205
205
  end
206
206
  case
207
207
  when catalogs.is_a?(Array)
208
- catalogs.each {|c| page_list.push *(pages(c)) unless c.nil?}
208
+ catalogs.each {|c| page_list.push *( pages(c, secure_injection, inheritance_hash ) ) unless c.nil?}
209
209
  when catalogs.is_a?(Hash)
210
210
  if catalogs[:is_reference_only]
211
- catalogs[:referenced_object] = pages(PDFOperations.get_refernced_object @objects, catalogs) unless catalogs[:referenced_object]
211
+ # not applicable any more... | catalogs[:referenced_object] = PDFOperations.get_refernced_object(@objects, catalogs) # for some reson, the code was: pages(PDFOperations.get_refernced_object(@objects, catalogs), secure_injection, inheritance_hash) unless catalogs[:referenced_object]
212
212
  if catalogs[:referenced_object]
213
- page_list.push *( pages(catalogs[:referenced_object]) )
213
+ page_list.push *( pages(catalogs[:referenced_object], secure_injection, inheritance_hash) )
214
214
  else
215
215
  warn "couldn't follow reference!!! #{catalogs} not found!"
216
216
  end
217
217
  else
218
+ unless catalogs[:Type] == :Page
219
+ # set inheritance, when applicable
220
+ inheritance_hash[:MediaBox] = catalogs[:MediaBox] if catalogs[:MediaBox]
221
+ inheritance_hash[:CropBox] = catalogs[:CropBox] if catalogs[:CropBox]
222
+ (inheritance_hash[:Resources] ||= {}).update( (catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &self.class.method(:hash_update_proc_for_new) ) if catalogs[:Resources]
223
+ (inheritance_hash[:ColorSpace] ||= {}).update( (catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &self.class.method(:hash_update_proc_for_new) ) if catalogs[:ColorSpace]
224
+ end
225
+
218
226
  case catalogs[:Type]
219
227
  when :Page
220
228
  holder = self
@@ -233,15 +241,23 @@ module CombinePDF
233
241
  self
234
242
  end
235
243
  end
236
- catalogs[:MediaBox] ||= catalogs[:Parent][:referenced_object][:MediaBox] if catalogs[:Parent].is_a?(Hash) && catalogs[:Parent][:referenced_object].is_a?(Hash) && catalogs[:Parent][:referenced_object][:MediaBox]
237
- catalogs[:CropBox] ||= catalogs[:Parent][:referenced_object][:CropBox] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:Parent][:referenced_object][:CropBox]
244
+
245
+ # inheritance
246
+ catalogs[:MediaBox] ||= inheritance_hash[:MediaBox] if inheritance_hash[:MediaBox]
247
+ catalogs[:CropBox] ||= inheritance_hash[:CropBox] if inheritance_hash[:CropBox]
248
+ (catalogs[:Resources] ||= {}).update( inheritance_hash[:Resources], &( self.class.method(:hash_update_proc_for_old) ) ) if inheritance_hash[:Resources]
249
+ (catalogs[:ColorSpace] ||= {}).update( inheritance_hash[:ColorSpace], &( self.class.method(:hash_update_proc_for_old) ) ) if inheritance_hash[:ColorSpace]
250
+
251
+
252
+ # avoide references on MediaBox and CropBox
238
253
  catalogs[:MediaBox] = catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary] if catalogs[:MediaBox].is_a?(Hash) && catalogs[:MediaBox][:referenced_object].is_a?(Hash) && catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary]
239
254
  catalogs[:CropBox] = catalogs[:CropBox][:referenced_object][:indirect_without_dictionary] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:CropBox][:referenced_object][:indirect_without_dictionary]
255
+
240
256
  page_list << catalogs
241
257
  when :Pages
242
- page_list.push *(pages(catalogs[:Kids])) unless catalogs[:Kids].nil?
258
+ page_list.push *(pages(catalogs[:Kids], secure_injection, inheritance_hash.dup )) unless catalogs[:Kids].nil?
243
259
  when :Catalog
244
- page_list.push *(pages(catalogs[:Pages])) unless catalogs[:Pages].nil?
260
+ page_list.push *(pages(catalogs[:Pages], secure_injection, inheritance_hash.dup )) unless catalogs[:Pages].nil?
245
261
  end
246
262
  end
247
263
  end
@@ -466,6 +482,7 @@ module CombinePDF
466
482
  case
467
483
  when object.is_a?(Array)
468
484
  object.each {|it| add_referenced(it)}
485
+ return true
469
486
  when object.is_a?(Hash)
470
487
  if object[:is_reference_only] && object[:referenced_object]
471
488
  found_at = @objects.find_index object[:referenced_object]
@@ -474,20 +491,22 @@ module CombinePDF
474
491
  # so, we need to make sure they are the same object for the pointers to effect id numbering
475
492
  # and formatting operations.
476
493
  object[:referenced_object] = @objects[found_at]
477
- else @objects.include? object[:referenced_object]
494
+ # stop this path, there is no need to run over the Hash's keys and values
495
+ return true
496
+ else
497
+ # @objects.include? object[:referenced_object] is bound to be false
478
498
  #the object wasn't found - add it to the @objects array
479
499
  @objects << object[:referenced_object]
480
- object[:referenced_object].each do |k, v|
481
- add_referenced(v) unless k == :Parent
482
- end
483
500
  end
484
501
 
485
- else
486
- object.each do |k, v|
487
- add_referenced(v) unless k == :Parent
488
- end
489
502
  end
503
+ object.each do |k, v|
504
+ add_referenced(v) unless k == :Parent
505
+ end
506
+ else
507
+ return false
490
508
  end
509
+ true
491
510
  end
492
511
  # @private
493
512
  # run block of code on evey PDF object (PDF objects are class Hash)
@@ -497,6 +516,27 @@ module CombinePDF
497
516
 
498
517
  protected
499
518
 
519
+ # @private
520
+ # this method reviews a Hash an updates it by merging Hash data,
521
+ # preffering the old over the new.
522
+ def self.hash_update_proc_for_old key, old_data, new_data
523
+ if old_data.is_a? Hash
524
+ old_data.merge( new_data, &self.method(:hash_update_proc_for_old) )
525
+ else
526
+ old_data
527
+ end
528
+ end
529
+ # @private
530
+ # this method reviews a Hash an updates it by merging Hash data,
531
+ # preffering the new over the old.
532
+ def self.hash_update_proc_for_new key, old_data, new_data
533
+ if old_data.is_a? Hash
534
+ old_data.merge( new_data, &self.method(:hash_update_proc_for_new) )
535
+ else
536
+ new_data
537
+ end
538
+ end
539
+
500
540
  # @private
501
541
  # this function returns all the Page objects - regardless of order and even if not cataloged
502
542
  # could be used for finding "lost" pages... but actually rather useless.
@@ -531,7 +571,7 @@ module CombinePDF
531
571
  each_object do |obj|
532
572
  if obj[:is_reference_only]
533
573
  obj[:referenced_object] = objects_reference_hash[ [obj[:indirect_reference_id], obj[:indirect_generation_number] ] ]
534
- warn "couldn't connect a reference!!! could be a null or removed (empty) object, Silent error!!!" unless obj[:referenced_object]
574
+ warn "couldn't connect a reference!!! could be a null or removed (empty) object, Silent error!!!\n Object raising issue: #{obj.to_s}" unless obj[:referenced_object]
535
575
  end
536
576
  end
537
577
 
@@ -1,3 +1,3 @@
1
1
  module CombinePDF
2
- VERSION = "0.1.10"
2
+ VERSION = "0.1.11"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: combine_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev