hexapdf 0.6.0 → 0.7.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 (257) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +33 -0
  3. data/CONTRIBUTERS +1 -1
  4. data/LICENSE +1 -1
  5. data/Rakefile +1 -1
  6. data/VERSION +1 -1
  7. data/bin/hexapdf +1 -1
  8. data/examples/text_layouter_styling.rb +1 -2
  9. data/lib/hexapdf.rb +2 -2
  10. data/lib/hexapdf/cli.rb +3 -3
  11. data/lib/hexapdf/cli/batch.rb +5 -5
  12. data/lib/hexapdf/cli/command.rb +15 -17
  13. data/lib/hexapdf/cli/files.rb +3 -3
  14. data/lib/hexapdf/cli/images.rb +3 -4
  15. data/lib/hexapdf/cli/info.rb +5 -5
  16. data/lib/hexapdf/cli/inspect.rb +6 -6
  17. data/lib/hexapdf/cli/merge.rb +6 -6
  18. data/lib/hexapdf/cli/modify.rb +4 -4
  19. data/lib/hexapdf/cli/optimize.rb +3 -3
  20. data/lib/hexapdf/configuration.rb +4 -5
  21. data/lib/hexapdf/content.rb +2 -2
  22. data/lib/hexapdf/content/canvas.rb +35 -36
  23. data/lib/hexapdf/content/color_space.rb +9 -14
  24. data/lib/hexapdf/content/graphic_object.rb +2 -2
  25. data/lib/hexapdf/content/graphic_object/arc.rb +3 -3
  26. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
  27. data/lib/hexapdf/content/graphic_object/solid_arc.rb +4 -8
  28. data/lib/hexapdf/content/graphics_state.rb +4 -13
  29. data/lib/hexapdf/content/operator.rb +33 -35
  30. data/lib/hexapdf/content/parser.rb +28 -18
  31. data/lib/hexapdf/content/processor.rb +4 -5
  32. data/lib/hexapdf/content/transformation_matrix.rb +2 -2
  33. data/lib/hexapdf/data_dir.rb +2 -2
  34. data/lib/hexapdf/dictionary.rb +8 -9
  35. data/lib/hexapdf/dictionary_fields.rb +7 -10
  36. data/lib/hexapdf/document.rb +18 -18
  37. data/lib/hexapdf/document/files.rb +12 -10
  38. data/lib/hexapdf/document/fonts.rb +2 -2
  39. data/lib/hexapdf/document/images.rb +3 -3
  40. data/lib/hexapdf/document/pages.rb +4 -4
  41. data/lib/hexapdf/encryption.rb +2 -2
  42. data/lib/hexapdf/encryption/aes.rb +2 -2
  43. data/lib/hexapdf/encryption/arc4.rb +4 -4
  44. data/lib/hexapdf/encryption/fast_aes.rb +2 -2
  45. data/lib/hexapdf/encryption/fast_arc4.rb +4 -4
  46. data/lib/hexapdf/encryption/identity.rb +5 -4
  47. data/lib/hexapdf/encryption/ruby_aes.rb +147 -139
  48. data/lib/hexapdf/encryption/ruby_arc4.rb +4 -4
  49. data/lib/hexapdf/encryption/security_handler.rb +11 -12
  50. data/lib/hexapdf/encryption/standard_security_handler.rb +6 -9
  51. data/lib/hexapdf/error.rb +7 -9
  52. data/lib/hexapdf/filter.rb +2 -3
  53. data/lib/hexapdf/filter/ascii85_decode.rb +3 -3
  54. data/lib/hexapdf/filter/ascii_hex_decode.rb +2 -2
  55. data/lib/hexapdf/filter/dct_decode.rb +2 -2
  56. data/lib/hexapdf/filter/encryption.rb +2 -2
  57. data/lib/hexapdf/filter/flate_decode.rb +16 -33
  58. data/lib/hexapdf/filter/jpx_decode.rb +2 -2
  59. data/lib/hexapdf/filter/lzw_decode.rb +4 -4
  60. data/lib/hexapdf/filter/predictor.rb +2 -6
  61. data/lib/hexapdf/filter/run_length_decode.rb +2 -2
  62. data/lib/hexapdf/font/cmap.rb +2 -3
  63. data/lib/hexapdf/font/cmap/parser.rb +11 -11
  64. data/lib/hexapdf/font/cmap/writer.rb +25 -25
  65. data/lib/hexapdf/font/encoding.rb +2 -2
  66. data/lib/hexapdf/font/encoding/base.rb +2 -2
  67. data/lib/hexapdf/font/encoding/difference_encoding.rb +2 -2
  68. data/lib/hexapdf/font/encoding/glyph_list.rb +6 -6
  69. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +2 -2
  70. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
  71. data/lib/hexapdf/font/encoding/standard_encoding.rb +2 -2
  72. data/lib/hexapdf/font/encoding/symbol_encoding.rb +2 -2
  73. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +2 -2
  74. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +2 -2
  75. data/lib/hexapdf/font/invalid_glyph.rb +7 -7
  76. data/lib/hexapdf/font/true_type.rb +2 -2
  77. data/lib/hexapdf/font/true_type/builder.rb +13 -7
  78. data/lib/hexapdf/font/true_type/font.rb +2 -3
  79. data/lib/hexapdf/font/true_type/optimizer.rb +2 -2
  80. data/lib/hexapdf/font/true_type/subsetter.rb +4 -4
  81. data/lib/hexapdf/font/true_type/table.rb +3 -5
  82. data/lib/hexapdf/font/true_type/table/cmap.rb +2 -2
  83. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +9 -16
  84. data/lib/hexapdf/font/true_type/table/directory.rb +4 -4
  85. data/lib/hexapdf/font/true_type/table/glyf.rb +2 -2
  86. data/lib/hexapdf/font/true_type/table/head.rb +3 -2
  87. data/lib/hexapdf/font/true_type/table/hhea.rb +2 -2
  88. data/lib/hexapdf/font/true_type/table/hmtx.rb +2 -2
  89. data/lib/hexapdf/font/true_type/table/kern.rb +3 -3
  90. data/lib/hexapdf/font/true_type/table/loca.rb +3 -3
  91. data/lib/hexapdf/font/true_type/table/maxp.rb +2 -2
  92. data/lib/hexapdf/font/true_type/table/name.rb +3 -5
  93. data/lib/hexapdf/font/true_type/table/os2.rb +4 -3
  94. data/lib/hexapdf/font/true_type/table/post.rb +3 -7
  95. data/lib/hexapdf/font/true_type_wrapper.rb +20 -22
  96. data/lib/hexapdf/font/type1.rb +2 -2
  97. data/lib/hexapdf/font/type1/afm_parser.rb +7 -7
  98. data/lib/hexapdf/font/type1/character_metrics.rb +2 -2
  99. data/lib/hexapdf/font/type1/font.rb +3 -3
  100. data/lib/hexapdf/font/type1/font_metrics.rb +2 -4
  101. data/lib/hexapdf/font/type1/pfb_parser.rb +2 -2
  102. data/lib/hexapdf/font/type1_wrapper.rb +8 -9
  103. data/lib/hexapdf/font_loader.rb +2 -2
  104. data/lib/hexapdf/font_loader/from_configuration.rb +2 -2
  105. data/lib/hexapdf/font_loader/from_file.rb +2 -2
  106. data/lib/hexapdf/font_loader/standard14.rb +2 -2
  107. data/lib/hexapdf/image_loader.rb +2 -2
  108. data/lib/hexapdf/image_loader/jpeg.rb +6 -4
  109. data/lib/hexapdf/image_loader/pdf.rb +2 -2
  110. data/lib/hexapdf/image_loader/png.rb +6 -6
  111. data/lib/hexapdf/importer.rb +6 -4
  112. data/lib/hexapdf/layout.rb +2 -2
  113. data/lib/hexapdf/layout/box.rb +4 -4
  114. data/lib/hexapdf/layout/inline_box.rb +2 -2
  115. data/lib/hexapdf/layout/line.rb +6 -6
  116. data/lib/hexapdf/layout/numeric_refinements.rb +2 -2
  117. data/lib/hexapdf/layout/style.rb +17 -8
  118. data/lib/hexapdf/layout/text_fragment.rb +86 -48
  119. data/lib/hexapdf/layout/text_layouter.rb +40 -21
  120. data/lib/hexapdf/layout/text_shaper.rb +2 -2
  121. data/lib/hexapdf/name_tree_node.rb +2 -2
  122. data/lib/hexapdf/number_tree_node.rb +2 -2
  123. data/lib/hexapdf/object.rb +6 -8
  124. data/lib/hexapdf/parser.rb +10 -10
  125. data/lib/hexapdf/rectangle.rb +4 -4
  126. data/lib/hexapdf/reference.rb +2 -2
  127. data/lib/hexapdf/revision.rb +4 -4
  128. data/lib/hexapdf/revisions.rb +5 -5
  129. data/lib/hexapdf/serializer.rb +27 -24
  130. data/lib/hexapdf/stream.rb +4 -4
  131. data/lib/hexapdf/task.rb +2 -2
  132. data/lib/hexapdf/task/dereference.rb +4 -4
  133. data/lib/hexapdf/task/optimize.rb +5 -4
  134. data/lib/hexapdf/tokenizer.rb +12 -14
  135. data/lib/hexapdf/type.rb +2 -2
  136. data/lib/hexapdf/type/action.rb +3 -3
  137. data/lib/hexapdf/type/actions.rb +2 -2
  138. data/lib/hexapdf/type/actions/go_to.rb +2 -2
  139. data/lib/hexapdf/type/actions/go_to_r.rb +2 -2
  140. data/lib/hexapdf/type/actions/launch.rb +2 -2
  141. data/lib/hexapdf/type/actions/uri.rb +3 -3
  142. data/lib/hexapdf/type/annotation.rb +3 -3
  143. data/lib/hexapdf/type/annotations.rb +2 -2
  144. data/lib/hexapdf/type/annotations/link.rb +2 -2
  145. data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -2
  146. data/lib/hexapdf/type/annotations/text.rb +2 -2
  147. data/lib/hexapdf/type/catalog.rb +4 -4
  148. data/lib/hexapdf/type/cid_font.rb +4 -5
  149. data/lib/hexapdf/type/embedded_file.rb +3 -3
  150. data/lib/hexapdf/type/file_specification.rb +6 -7
  151. data/lib/hexapdf/type/font.rb +4 -4
  152. data/lib/hexapdf/type/font_descriptor.rb +3 -4
  153. data/lib/hexapdf/type/font_simple.rb +12 -16
  154. data/lib/hexapdf/type/font_true_type.rb +2 -2
  155. data/lib/hexapdf/type/font_type0.rb +5 -5
  156. data/lib/hexapdf/type/font_type1.rb +4 -4
  157. data/lib/hexapdf/type/form.rb +3 -3
  158. data/lib/hexapdf/type/graphics_state_parameter.rb +3 -3
  159. data/lib/hexapdf/type/image.rb +13 -14
  160. data/lib/hexapdf/type/info.rb +2 -2
  161. data/lib/hexapdf/type/names.rb +2 -2
  162. data/lib/hexapdf/type/object_stream.rb +5 -5
  163. data/lib/hexapdf/type/page.rb +9 -10
  164. data/lib/hexapdf/type/page_tree_node.rb +5 -6
  165. data/lib/hexapdf/type/resources.rb +11 -11
  166. data/lib/hexapdf/type/trailer.rb +3 -3
  167. data/lib/hexapdf/type/viewer_preferences.rb +2 -2
  168. data/lib/hexapdf/type/xref_stream.rb +8 -4
  169. data/lib/hexapdf/utils/bit_field.rb +4 -4
  170. data/lib/hexapdf/utils/bit_stream.rb +4 -4
  171. data/lib/hexapdf/utils/graphics_helpers.rb +2 -2
  172. data/lib/hexapdf/utils/lru_cache.rb +2 -2
  173. data/lib/hexapdf/utils/math_helpers.rb +2 -2
  174. data/lib/hexapdf/utils/object_hash.rb +3 -3
  175. data/lib/hexapdf/utils/pdf_doc_encoding.rb +3 -3
  176. data/lib/hexapdf/utils/sorted_tree_node.rb +12 -11
  177. data/lib/hexapdf/version.rb +3 -3
  178. data/lib/hexapdf/writer.rb +8 -8
  179. data/lib/hexapdf/xref_section.rb +3 -3
  180. data/test/hexapdf/common_tokenizer_tests.rb +6 -7
  181. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -1
  182. data/test/hexapdf/content/test_canvas.rb +28 -36
  183. data/test/hexapdf/content/test_color_space.rb +4 -0
  184. data/test/hexapdf/content/test_graphics_state.rb +2 -0
  185. data/test/hexapdf/content/test_operator.rb +6 -7
  186. data/test/hexapdf/content/test_parser.rb +2 -2
  187. data/test/hexapdf/content/test_processor.rb +1 -1
  188. data/test/hexapdf/document/test_files.rb +1 -0
  189. data/test/hexapdf/document/test_images.rb +1 -1
  190. data/test/hexapdf/encryption/common.rb +3 -3
  191. data/test/hexapdf/encryption/test_aes.rb +10 -4
  192. data/test/hexapdf/encryption/test_identity.rb +1 -1
  193. data/test/hexapdf/encryption/test_security_handler.rb +13 -17
  194. data/test/hexapdf/encryption/test_standard_security_handler.rb +12 -12
  195. data/test/hexapdf/filter/test_ascii85_decode.rb +2 -3
  196. data/test/hexapdf/filter/test_ascii_hex_decode.rb +6 -1
  197. data/test/hexapdf/filter/test_flate_decode.rb +2 -2
  198. data/test/hexapdf/filter/test_lzw_decode.rb +10 -10
  199. data/test/hexapdf/filter/test_predictor.rb +10 -2
  200. data/test/hexapdf/filter/test_run_length_decode.rb +1 -1
  201. data/test/hexapdf/font/cmap/test_parser.rb +40 -40
  202. data/test/hexapdf/font/cmap/test_writer.rb +29 -29
  203. data/test/hexapdf/font/test_true_type_wrapper.rb +3 -2
  204. data/test/hexapdf/font/true_type/common.rb +2 -0
  205. data/test/hexapdf/font/true_type/table/test_cmap.rb +1 -1
  206. data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +5 -4
  207. data/test/hexapdf/font/true_type/table/test_glyf.rb +2 -2
  208. data/test/hexapdf/font/true_type/table/test_head.rb +2 -2
  209. data/test/hexapdf/font/true_type/table/test_name.rb +9 -6
  210. data/test/hexapdf/font/true_type/test_builder.rb +8 -3
  211. data/test/hexapdf/font/true_type/test_optimizer.rb +1 -2
  212. data/test/hexapdf/font/type1/test_afm_parser.rb +2 -2
  213. data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
  214. data/test/hexapdf/image_loader/test_pdf.rb +1 -1
  215. data/test/hexapdf/image_loader/test_png.rb +3 -3
  216. data/test/hexapdf/layout/test_inline_box.rb +10 -1
  217. data/test/hexapdf/layout/test_line.rb +4 -4
  218. data/test/hexapdf/layout/test_style.rb +19 -7
  219. data/test/hexapdf/layout/test_text_fragment.rb +73 -27
  220. data/test/hexapdf/layout/test_text_layouter.rb +84 -68
  221. data/test/hexapdf/layout/test_text_shaper.rb +4 -6
  222. data/test/hexapdf/task/test_dereference.rb +2 -2
  223. data/test/hexapdf/task/test_optimize.rb +16 -7
  224. data/test/hexapdf/test_configuration.rb +1 -1
  225. data/test/hexapdf/test_data_dir.rb +2 -2
  226. data/test/hexapdf/test_dictionary.rb +6 -3
  227. data/test/hexapdf/test_dictionary_fields.rb +15 -14
  228. data/test/hexapdf/test_document.rb +47 -48
  229. data/test/hexapdf/test_filter.rb +30 -26
  230. data/test/hexapdf/test_importer.rb +14 -0
  231. data/test/hexapdf/test_object.rb +16 -4
  232. data/test/hexapdf/test_parser.rb +36 -36
  233. data/test/hexapdf/test_reference.rb +7 -5
  234. data/test/hexapdf/test_revision.rb +1 -1
  235. data/test/hexapdf/test_revisions.rb +90 -90
  236. data/test/hexapdf/test_serializer.rb +3 -2
  237. data/test/hexapdf/test_stream.rb +2 -4
  238. data/test/hexapdf/test_tokenizer.rb +2 -2
  239. data/test/hexapdf/test_writer.rb +80 -80
  240. data/test/hexapdf/test_xref_section.rb +1 -1
  241. data/test/hexapdf/type/annotations/test_link.rb +1 -1
  242. data/test/hexapdf/type/annotations/test_text.rb +3 -3
  243. data/test/hexapdf/type/test_font_descriptor.rb +1 -1
  244. data/test/hexapdf/type/test_font_simple.rb +2 -2
  245. data/test/hexapdf/type/test_font_type0.rb +0 -1
  246. data/test/hexapdf/type/test_image.rb +0 -3
  247. data/test/hexapdf/type/test_object_stream.rb +2 -1
  248. data/test/hexapdf/type/test_page.rb +5 -1
  249. data/test/hexapdf/type/test_page_tree_node.rb +4 -4
  250. data/test/hexapdf/type/test_trailer.rb +1 -1
  251. data/test/hexapdf/type/test_xref_stream.rb +4 -0
  252. data/test/hexapdf/utils/test_bit_field.rb +2 -0
  253. data/test/hexapdf/utils/test_bit_stream.rb +1 -1
  254. data/test/hexapdf/utils/test_lru_cache.rb +1 -1
  255. data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -4
  256. data/test/test_helper.rb +3 -6
  257. metadata +3 -3
@@ -45,8 +45,8 @@ describe HexaPDF::Content::Parser do
45
45
  assert_equal([[:inline_image, [{CS: :RGB}, @image_data]],
46
46
  [:restore_graphics_state],
47
47
  [:save_graphics_state],
48
- [:concatenate_matrix, [1308, 0, 0, 1, 485.996, 4531.67]]
49
- ], @processor.recorded_ops)
48
+ [:concatenate_matrix, [1308, 0, 0, 1, 485.996, 4531.67]]],
49
+ @processor.recorded_ops)
50
50
  end
51
51
 
52
52
  it "parses a content stream with an inline image with EI in image data at end of stream" do
@@ -141,7 +141,7 @@ describe HexaPDF::Content::Processor do
141
141
  lry = @font.bounding_box[3] / 1000.0 * @processor.graphics_state.font_size +
142
142
  @processor.graphics_state.text_rise
143
143
  arr = ["Hül".encode("Windows-1252"), 20, " le".encode("Windows-1252")]
144
- width = "Hül le".encode("Windows-1252").codepoints.inject(0) {|s, cp| s + @font.width(cp)}
144
+ width = "Hül le".encode("Windows-1252").codepoints.inject(0) {|s, cp| s + @font.width(cp) }
145
145
  width = (width - 20) * @processor.graphics_state.scaled_font_size +
146
146
  6 * @processor.graphics_state.scaled_character_spacing +
147
147
  @processor.graphics_state.scaled_word_spacing
@@ -53,6 +53,7 @@ describe HexaPDF::Document::Files do
53
53
  @doc.add(Type: :Filespec)
54
54
  spec1 = @doc.files.add(__FILE__)
55
55
  spec2 = @doc.add(Type: :Filespec)
56
+ @doc.pages.add # page without annot
56
57
  @doc.pages.add[:Annots] = [
57
58
  {Subtype: :FileAttachment, FS: HexaPDF::Reference.new(spec1.oid, spec1.gen)},
58
59
  {Subtype: :FileAttachment, FS: spec2},
@@ -13,7 +13,7 @@ describe HexaPDF::Document::Images do
13
13
  describe "using a custom image loader" do
14
14
  before do
15
15
  @loader = Object.new
16
- @loader.define_singleton_method(:handles?) {|*| true}
16
+ @loader.define_singleton_method(:handles?) {|*| true }
17
17
  @loader.define_singleton_method(:load) do |doc, s|
18
18
  s = HexaPDF::StreamData.new(s) if s.kind_of?(IO)
19
19
  doc.add({Subtype: :Image}, stream: s)
@@ -30,7 +30,7 @@ module AESEncryptionTests
30
30
  TEST_VECTOR_FILES.each do |filename|
31
31
  name, size, mode = File.basename(filename, '.data.gz').split('-')
32
32
  size = size.to_i / 8
33
- data = Zlib::GzipReader.open(filename) {|io| io.read}.force_encoding(Encoding::BINARY)
33
+ data = Zlib::GzipReader.open(filename, &:read).force_encoding(Encoding::BINARY)
34
34
  data.scan(/(.{#{size}})(.{16})(.{16})(.{16})/m).each_with_index do |(key, iv, plain, cipher), index|
35
35
  aes = @algorithm_class.new(key, iv, mode.intern)
36
36
  assert_equal(cipher, aes.process(plain),
@@ -66,8 +66,8 @@ module ARC4EncryptionTests
66
66
  def setup
67
67
  super
68
68
  @encrypted = ['BBF316E8D940AF0AD3', '1021BF0420', '45A01F645FC35B383552544B9BF5'].
69
- map {|c| [c].pack('H*')}
70
- @plain = ['Plaintext', 'pedia', 'Attack at dawn'].each {|s| s.force_encoding('BINARY')}
69
+ map {|c| [c].pack('H*') }
70
+ @plain = ['Plaintext', 'pedia', 'Attack at dawn'].each {|s| s.force_encoding('BINARY') }
71
71
  @keys = ['Key', 'Wiki', 'Secret']
72
72
  end
73
73
 
@@ -17,13 +17,17 @@ describe HexaPDF::Encryption::AES do
17
17
  end
18
18
 
19
19
  def process(data)
20
- raise "invalid data" if data.length == 0 || data.length % 16 != 0
20
+ raise "invalid data" if data.empty? || data.length % 16 != 0
21
21
  data
22
22
  end
23
23
  end
24
24
 
25
25
  @padding_data = (0..15).map do |length|
26
- {plain: '5' * length, cipher_padding: '5' * length + (16 - length).chr * (16 - length), length: 32}
26
+ {
27
+ plain: '5' * length,
28
+ cipher_padding: '5' * length + (16 - length).chr * (16 - length),
29
+ length: 32,
30
+ }
27
31
  end
28
32
  @padding_data << {plain: '5' * 16, cipher_padding: '5' * 16 + 16.chr * 16, length: 48}
29
33
  end
@@ -73,7 +77,8 @@ describe HexaPDF::Encryption::AES do
73
77
 
74
78
  it "returns the decrypted result without padding and with IV removed on decryption_fiber" do
75
79
  @padding_data.each do |data|
76
- result = @algorithm_class.decryption_fiber('some key' * 2, Fiber.new {'iv' * 8 + data[:cipher_padding]})
80
+ result = @algorithm_class.decryption_fiber('some key' * 2,
81
+ Fiber.new { 'iv' * 8 + data[:cipher_padding] })
77
82
  result = TestHelper.collector(result)
78
83
  assert_equal(data[:plain], result)
79
84
  end
@@ -106,7 +111,8 @@ describe HexaPDF::Encryption::AES do
106
111
  it "fails on decryption if not enough bytes are provided" do
107
112
  [4, 20, 40].each do |length|
108
113
  assert_raises(HexaPDF::EncryptionError) do
109
- TestHelper.collector(@algorithm_class.decryption_fiber('some' * 4, Fiber.new { 'a' * length }))
114
+ TestHelper.collector(@algorithm_class.decryption_fiber('some' * 4,
115
+ Fiber.new { 'a' * length }))
110
116
  end
111
117
  end
112
118
  end
@@ -15,7 +15,7 @@ describe HexaPDF::Encryption::Identity do
15
15
  end
16
16
 
17
17
  it "returns the source Fiber unmodified for encryption_fiber/decryption_fiber" do
18
- f = Fiber.new {'data'}
18
+ f = Fiber.new { 'data' }
19
19
  assert_equal(f, @algorithm_class.encryption_fiber('key', f))
20
20
  end
21
21
  end
@@ -58,7 +58,6 @@ describe HexaPDF::Encryption::SecurityHandler do
58
58
 
59
59
  end
60
60
 
61
-
62
61
  before do
63
62
  @document = HexaPDF::Document.new
64
63
  @obj = @document.add({})
@@ -70,7 +69,7 @@ describe HexaPDF::Encryption::SecurityHandler do
70
69
  @document.config['encryption.filter_map'][:Test] = TestHandler
71
70
  end
72
71
 
73
- describe "class set_up_encryption" do
72
+ describe "set_up_encryption" do
74
73
  it "fails if the requested security handler cannot be found" do
75
74
  assert_raises(HexaPDF::EncryptionError) do
76
75
  HexaPDF::Encryption::SecurityHandler.set_up_encryption(@document, :non_standard)
@@ -125,7 +124,7 @@ describe HexaPDF::Encryption::SecurityHandler do
125
124
  it "sets the correct /V value for the given key length and algorithm" do
126
125
  [[40, :arc4, 1], [128, :arc4, 2], [128, :arc4, 4],
127
126
  [128, :aes, 4], [256, :aes, 5]].each do |length, algorithm, version|
128
- @handler.set_up_encryption(key_length: length, algorithm: algorithm, force_V4: version == 4)
127
+ @handler.set_up_encryption(key_length: length, algorithm: algorithm, force_v4: version == 4)
129
128
  assert_equal(version, @handler.dict[:V])
130
129
  end
131
130
  end
@@ -200,9 +199,8 @@ describe HexaPDF::Encryption::SecurityHandler do
200
199
  end
201
200
  end
202
201
 
203
-
204
202
  describe "set_up_decryption" do
205
- it "sets the handlers's dictionary to the encryption dictionary wrapped in a custom class and returns it" do
203
+ it "wraps the given hash in an encryption dictionary class, uses it for its dict, returns it" do
206
204
  dict = @handler.set_up_decryption(Filter: :test, V: 1)
207
205
  assert_equal(dict, @handler.dict)
208
206
  assert_kind_of(HexaPDF::Encryption::EncryptionDictionary, @handler.dict)
@@ -222,13 +220,14 @@ describe HexaPDF::Encryption::SecurityHandler do
222
220
  it "selects the correct algorithm based on the /V and /CF values" do
223
221
  @enc = @handler.dup
224
222
 
225
- [[:arc4, 40, {V: 1}],
226
- [:arc4, 80, {V: 2, Length: 80}],
227
- [:arc4, 128, {V: 4, StrF: :Mine, CF: {Mine: {CFM: :V2}}}],
228
- [:aes, 128, {V: 4, StrF: :Mine, CF: {Mine: {CFM: :AESV2}}}],
229
- [:aes, 256, {V: 5, StrF: :Mine, CF: {Mine: {CFM: :AESV3}}}],
230
- [:identity, 128, {V: 4, StrF: :Mine, CF: {Mine: {CFM: :None}}}],
231
- [:identity, 128, {V: 4, CF: {Mine: {CFM: :AESV2}}}],
223
+ [
224
+ [:arc4, 40, {V: 1}],
225
+ [:arc4, 80, {V: 2, Length: 80}],
226
+ [:arc4, 128, {V: 4, StrF: :Mine, CF: {Mine: {CFM: :V2}}}],
227
+ [:aes, 128, {V: 4, StrF: :Mine, CF: {Mine: {CFM: :AESV2}}}],
228
+ [:aes, 256, {V: 5, StrF: :Mine, CF: {Mine: {CFM: :AESV3}}}],
229
+ [:identity, 128, {V: 4, StrF: :Mine, CF: {Mine: {CFM: :None}}}],
230
+ [:identity, 128, {V: 4, CF: {Mine: {CFM: :AESV2}}}],
232
231
  ].each do |alg, length, dict|
233
232
  @enc.strf = alg
234
233
  @enc.set_up_encryption(key_length: length, algorithm: (alg == :identity ? :aes : alg))
@@ -239,8 +238,8 @@ describe HexaPDF::Encryption::SecurityHandler do
239
238
  end
240
239
 
241
240
  it "selects the correct algorithm for string, stream and embedded file decryption" do
242
- @handler.set_up_decryption({V: 4, StrF: :Mine, StmF: :Mine, EFF: :Mine,
243
- CF: {Mine: {CFM: :V2}}})
241
+ @handler.set_up_decryption(V: 4, StrF: :Mine, StmF: :Mine, EFF: :Mine,
242
+ CF: {Mine: {CFM: :V2}})
244
243
  assert_equal(HexaPDF::Encryption::FastARC4, @handler.send(:embedded_file_algorithm))
245
244
  assert_equal(HexaPDF::Encryption::FastARC4, @handler.send(:string_algorithm))
246
245
  assert_equal(HexaPDF::Encryption::FastARC4, @handler.send(:stream_algorithm))
@@ -268,7 +267,6 @@ describe HexaPDF::Encryption::SecurityHandler do
268
267
  end
269
268
  end
270
269
 
271
-
272
270
  describe "decrypt" do
273
271
  before do
274
272
  @handler.set_up_decryption(V: 1)
@@ -307,7 +305,6 @@ describe HexaPDF::Encryption::SecurityHandler do
307
305
  end
308
306
  end
309
307
 
310
-
311
308
  describe "encryption" do
312
309
  before do
313
310
  @handler.set_up_encryption(key_length: 128, algorithm: :arc4)
@@ -337,7 +334,6 @@ describe HexaPDF::Encryption::SecurityHandler do
337
334
  end
338
335
  end
339
336
 
340
-
341
337
  it "works correctly with different decryption and encryption handlers" do
342
338
  test_file = File.join(TEST_DATA_DIR, 'standard-security-handler', 'nopwd-arc4-40bit-V1.pdf')
343
339
  doc = HexaPDF::Document.new(io: StringIO.new(File.read(test_file)))
@@ -89,7 +89,6 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
89
89
  end
90
90
  end
91
91
 
92
-
93
92
  before do
94
93
  @document = HexaPDF::Document.new
95
94
  @handler = HexaPDF::Encryption::StandardSecurityHandler.new(@document)
@@ -125,10 +124,12 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
125
124
 
126
125
  it "sets the correct revision independent /P value" do
127
126
  dict = @handler.set_up_encryption
128
- assert_equal(@handler.class::Permissions::ALL | @handler.class::Permissions::RESERVED - 2**32,
127
+ assert_equal(@handler.class::Permissions::ALL | \
128
+ @handler.class::Permissions::RESERVED - 2**32,
129
129
  dict[:P])
130
130
  dict = @handler.set_up_encryption(permissions: @handler.class::Permissions::COPY_CONTENT)
131
- assert_equal(@handler.class::Permissions::COPY_CONTENT | @handler.class::Permissions::RESERVED - 2**32,
131
+ assert_equal(@handler.class::Permissions::COPY_CONTENT | \
132
+ @handler.class::Permissions::RESERVED - 2**32,
132
133
  dict[:P])
133
134
  dict = @handler.set_up_encryption(permissions: [:modify_content, :modify_annotation])
134
135
  assert_equal(@handler.class::Permissions::MODIFY_CONTENT | \
@@ -171,7 +172,7 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
171
172
  assert_equal(:StdCF, d[:StmF])
172
173
  end
173
174
 
174
- dict = @handler.set_up_encryption(key_length: 128, algorithm: :arc4, force_V4: true)
175
+ dict = @handler.set_up_encryption(key_length: 128, algorithm: :arc4, force_v4: true)
175
176
  refute(dict.value.key?(:UE))
176
177
  refute(dict.value.key?(:OE))
177
178
  refute(dict.value.key?(:Perms))
@@ -190,12 +191,12 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
190
191
  crypt_filter.call(dict, 6, :AESV3, 32)
191
192
  end
192
193
 
193
- it "uses the password keyword as fallback, the user password as owner password if the latter is not set" do
194
- dict1 = @document.unwrap(@handler.set_up_encryption(password: 'user', owner_password: 'owner'))
195
- dict2 = @document.unwrap(@handler.set_up_encryption(password: 'owner', user_password: 'user'))
196
- dict3 = @document.unwrap(@handler.set_up_encryption(user_password: 'user', owner_password: 'owner'))
197
- dict4 = @document.unwrap(@handler.set_up_encryption(user_password: 'test', owner_password: 'test'))
198
- dict5 = @document.unwrap(@handler.set_up_encryption(user_password: 'test'))
194
+ it "uses the password keyword as fallback, the user password as owner password if necessary" do
195
+ dict1 = @handler.set_up_encryption(password: 'user', owner_password: 'owner')
196
+ dict2 = @handler.set_up_encryption(password: 'owner', user_password: 'user')
197
+ dict3 = @handler.set_up_encryption(user_password: 'user', owner_password: 'owner')
198
+ dict4 = @handler.set_up_encryption(user_password: 'test', owner_password: 'test')
199
+ dict5 = @handler.set_up_encryption(user_password: 'test')
199
200
 
200
201
  assert_equal(dict1[:U], dict2[:U])
201
202
  assert_equal(dict2[:U], dict3[:U])
@@ -213,7 +214,6 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
213
214
  end
214
215
  end
215
216
 
216
-
217
217
  describe "prepare_decryption" do
218
218
  it "fails if the /Filter value is incorrect" do
219
219
  exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
@@ -278,7 +278,7 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
278
278
  end
279
279
  end
280
280
 
281
- it "encryption key stays valid even if default dictionary values are set while setting up decryption" do
281
+ it "encryption key stays valid even if default dict values are set while setting up decryption" do
282
282
  @document.encrypt(key_length: 128, algorithm: :aes)
283
283
  assert(@document.security_handler.encryption_key_valid?)
284
284
 
@@ -13,8 +13,7 @@ describe HexaPDF::Filter::ASCII85Decode do
13
13
  ['Nov shmoz ka pop.12', ':2b:uF(fE/H6@!3+E27</ho*~>'],
14
14
  ['Nov shmoz ka pop.123', ':2b:uF(fE/H6@!3+E27</ho+;~>'],
15
15
  ["\0\0\0\0Nov shmoz ka pop.", 'z:2b:uF(fE/H6@!3+E27</c~>'],
16
- ["Nov \x0\x0\x0\x0shmoz ka pop.", ':2b:uzF(fE/H6@!3+E27</c~>'],
17
- ]
16
+ ["Nov \x0\x0\x0\x0shmoz ka pop.", ':2b:uzF(fE/H6@!3+E27</c~>']]
18
17
  @decoded = @all_test_cases[0][0]
19
18
  @encoded = @all_test_cases[0][1]
20
19
  end
@@ -25,7 +24,7 @@ describe HexaPDF::Filter::ASCII85Decode do
25
24
  end
26
25
 
27
26
  it "ignores whitespace in the input" do
28
- encoded = @encoded.dup.scan(/./).map {|a| "#{a} \r\t"}.join("\n")
27
+ encoded = @encoded.dup.scan(/./).map {|a| "#{a} \r\t" }.join("\n")
29
28
  assert_equal(@decoded, collector(@obj.decoder(feeder(encoded))))
30
29
  end
31
30
 
@@ -15,7 +15,8 @@ describe HexaPDF::Filter::ASCIIHexDecode do
15
15
 
16
16
  describe "decoder" do
17
17
  it "ignores whitespace in the input" do
18
- assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded.scan(/./).map {|a| "#{a} \r\t"}.join("\n"), 1))))
18
+ with_whitespace = @encoded.scan(/./).map {|a| "#{a} \r\t" }.join("\n")
19
+ assert_equal(@decoded, collector(@obj.decoder(feeder(with_whitespace, 1))))
19
20
  end
20
21
 
21
22
  it "works without the EOD marker" do
@@ -26,6 +27,10 @@ describe HexaPDF::Filter::ASCIIHexDecode do
26
27
  assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded + '4e6f7gzz'))))
27
28
  end
28
29
 
30
+ it "assumes the missing char is '0' if the input length is odd" do
31
+ assert_equal(@decoded.chop << ' ', collector(@obj.decoder(feeder(@encoded.chop.chop))))
32
+ end
33
+
29
34
  it "fails on invalid characters" do
30
35
  assert_raises(HexaPDF::FilterError) { @obj.decoder(feeder('f0f0z')).resume }
31
36
  end
@@ -18,7 +18,7 @@ describe HexaPDF::Filter::FlateDecode do
18
18
 
19
19
  describe "decoder" do
20
20
  it "applies the Predictor after decoding" do
21
- assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor.dup), @predictor_opts)))
21
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor), @predictor_opts)))
22
22
  end
23
23
 
24
24
  it "fails on invalid input" do
@@ -29,7 +29,7 @@ describe HexaPDF::Filter::FlateDecode do
29
29
 
30
30
  describe "encoder" do
31
31
  it "applies the Predictor before encoding" do
32
- assert_equal(@encoded_predictor, collector(@obj.encoder(feeder(@decoded.dup), @predictor_opts)))
32
+ assert_equal(@encoded_predictor, collector(@obj.encoder(feeder(@decoded), @predictor_opts)))
33
33
  end
34
34
  end
35
35
  end
@@ -8,18 +8,18 @@ describe HexaPDF::Filter::LZWDecode do
8
8
 
9
9
  before do
10
10
  @obj = HexaPDF::Filter::LZWDecode
11
- @all_test_cases ||= [["-----A---B", "\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01"],
12
- ['abcabcaaaabbbcdeffffffagggggg', "\x80\x18LF8\x14\x10\xC3\a1BLfC)\x9A\x1D\x0F0\x99\xE2Q8\b"],
13
- ].each {|a, b| a.force_encoding(Encoding::BINARY); b.force_encoding(Encoding::BINARY)}
11
+ @all_test_cases ||= [["-----A---B".b, "\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01".b],
12
+ ['abcabcaaaabbbcdeffffffagggggg'.b,
13
+ "\x80\x18LF8\x14\x10\xC3\a1BLfC)\x9A\x1D\x0F0\x99\xE2Q8\b".b]]
14
14
  @decoded = @all_test_cases[0][0]
15
15
  @encoded = @all_test_cases[0][1]
16
- @encoded_predictor = "\x80\x00\x85\xA0 \x04\x12\r\x05\n\x00\x9D\x90p\x10V\x02".force_encoding(Encoding::BINARY)
16
+ @encoded_predictor = "\x80\x00\x85\xA0 \x04\x12\r\x05\n\x00\x9D\x90p\x10V\x02".b
17
17
  @predictor_opts = {Predictor: 12}
18
18
  end
19
19
 
20
20
  describe "decoder" do
21
21
  it "applies the Predictor after decoding" do
22
- assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor.dup), @predictor_opts)))
22
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor), @predictor_opts)))
23
23
  end
24
24
 
25
25
  it "fails if an unknown code is found after CLEAR_TABLE" do
@@ -34,10 +34,10 @@ describe HexaPDF::Filter::LZWDecode do
34
34
  stream = HexaPDF::Utils::BitStreamWriter.new
35
35
  result = stream.write(256, 9)
36
36
  result << stream.write(65, 9)
37
- 258.upto(510) {|i| result << stream.write(i, 9)}
38
- 511.upto(1022) {|i| result << stream.write(i, 10)}
39
- 1023.upto(2046) {|i| result << stream.write(i, 11)}
40
- 2047.upto(4095) {|i| result << stream.write(i, 12)}
37
+ 258.upto(510) {|i| result << stream.write(i, 9) }
38
+ 511.upto(1022) {|i| result << stream.write(i, 10) }
39
+ 1023.upto(2046) {|i| result << stream.write(i, 11) }
40
+ 2047.upto(4095) {|i| result << stream.write(i, 12) }
41
41
  result << stream.write(96, 12)
42
42
  result << stream.finalize
43
43
  assert_raises(HexaPDF::FilterError) { @obj.decoder(feeder(result)).resume }
@@ -46,7 +46,7 @@ describe HexaPDF::Filter::LZWDecode do
46
46
 
47
47
  describe "encoder" do
48
48
  it "applies the Predictor before encoding" do
49
- assert_equal(@encoded_predictor, collector(@obj.encoder(feeder(@decoded.dup), @predictor_opts)))
49
+ assert_equal(@encoded_predictor, collector(@obj.encoder(feeder(@decoded), @predictor_opts)))
50
50
  end
51
51
  end
52
52
  end
@@ -9,13 +9,15 @@ describe HexaPDF::Filter::Predictor do
9
9
  module CommonPredictorTests
10
10
  def test_decoding_through_decoder_method
11
11
  @testcases.each do |name, data|
12
- assert_equal(data[:source], collector(@obj.decoder(feeder(data[:result].dup), data)), "test case: #{name}")
12
+ assert_equal(data[:source], collector(@obj.decoder(feeder(data[:result].dup), data)),
13
+ "test case: #{name}")
13
14
  end
14
15
  end
15
16
 
16
17
  def test_encoding_through_encoder_method
17
18
  @testcases.each do |name, data|
18
- assert_equal(data[:result], collector(@obj.encoder(feeder(data[:source].dup), data)), "test case: #{name}")
19
+ assert_equal(data[:result], collector(@obj.encoder(feeder(data[:source].dup), data)),
20
+ "test case: #{name}")
19
21
  end
20
22
  end
21
23
  end
@@ -31,6 +33,12 @@ describe HexaPDF::Filter::Predictor do
31
33
  end
32
34
  end
33
35
 
36
+ it "just returns the source if no processing needs to be done" do
37
+ source = feeder("test")
38
+ assert_same(source, @obj.encoder(source, Predictor: 1))
39
+ assert_same(source, @obj.encoder(source, {}))
40
+ end
41
+
34
42
  describe "png predictor" do
35
43
  include CommonPredictorTests
36
44
 
@@ -25,7 +25,7 @@ describe HexaPDF::Filter::RunLengthDecode do
25
25
 
26
26
  describe "encoder" do
27
27
  it "works with single byte input" do
28
- assert_equal(@encoded.chars.map {|a| "\0#{a}"}.join << "\x80".force_encoding(Encoding::BINARY),
28
+ assert_equal(@encoded.chars.map {|a| "\0#{a}" }.join << "\x80".b,
29
29
  collector(@obj.encoder(feeder(@encoded.dup, 1))))
30
30
  end
31
31
  end
@@ -6,46 +6,46 @@ require 'hexapdf/font/cmap/parser'
6
6
  describe HexaPDF::Font::CMap::Parser do
7
7
  describe "::parse" do
8
8
  it "parses CMap data correctly" do
9
- data = <<EOF
10
- /CIDInit /ProcSet findresource begin
11
- 12 dict begin
12
- begincmap
13
- /H usecmap
14
- /CIDSystemInfo
15
- << /Registry (Adobe)
16
- /Ordering (UCS)
17
- /Supplement 0
18
- >> def
19
- /CMapName /Adobe-Identity-UCS def
20
- /CMapType 2 def
21
- /WMode 0 def
22
- 4 begincodespacerange
23
- <00> <20>
24
- <8140> <9ffc>
25
- <a0> <de>
26
- <e040> <fbec>
27
- endcodespacerange
28
- 2 begincidchar
29
- <8143> 8286
30
- <8144> 8274
31
- endcidchar
32
- 2 begincidrange
33
- <8145> <8145> 8123
34
- <8146> <8148> 9000
35
- endcidrange
36
- 2 beginbfrange
37
- <0000> <005E> <0020>
38
- <1379> <137B> <90FE>
39
- <005F> <0061> [ <00660066> <00660069> <00660066006C> ]
40
- endbfrange
41
- 1 beginbfchar
42
- <3A51> <D840DC3E>
43
- endbfchar
44
- endcmap
45
- CMapName currentdict /CMap defineresource pop
46
- end
47
- end
48
- EOF
9
+ data = <<~EOF
10
+ /CIDInit /ProcSet findresource begin
11
+ 12 dict begin
12
+ begincmap
13
+ /H usecmap
14
+ /CIDSystemInfo
15
+ << /Registry (Adobe)
16
+ /Ordering (UCS)
17
+ /Supplement 0
18
+ >> def
19
+ /CMapName /Adobe-Identity-UCS def
20
+ /CMapType 2 def
21
+ /WMode 0 def
22
+ 4 begincodespacerange
23
+ <00> <20>
24
+ <8140> <9ffc>
25
+ <a0> <de>
26
+ <e040> <fbec>
27
+ endcodespacerange
28
+ 2 begincidchar
29
+ <8143> 8286
30
+ <8144> 8274
31
+ endcidchar
32
+ 2 begincidrange
33
+ <8145> <8145> 8123
34
+ <8146> <8148> 9000
35
+ endcidrange
36
+ 2 beginbfrange
37
+ <0000> <005E> <0020>
38
+ <1379> <137B> <90FE>
39
+ <005F> <0061> [ <00660066> <00660069> <00660066006C> ]
40
+ endbfrange
41
+ 1 beginbfchar
42
+ <3A51> <D840DC3E>
43
+ endbfchar
44
+ endcmap
45
+ CMapName currentdict /CMap defineresource pop
46
+ end
47
+ end
48
+ EOF
49
49
  cmap = HexaPDF::Font::CMap.parse(data)
50
50
  assert_equal("Adobe", cmap.registry)
51
51
  assert_equal("UCS", cmap.ordering)