hexapdf 0.15.8 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (446) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hexapdf/cli/batch.rb +1 -1
  3. data/lib/hexapdf/cli/command.rb +10 -1
  4. data/lib/hexapdf/cli/files.rb +1 -1
  5. data/lib/hexapdf/cli/fonts.rb +145 -0
  6. data/lib/hexapdf/cli/form.rb +27 -26
  7. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  8. data/lib/hexapdf/cli/images.rb +1 -10
  9. data/lib/hexapdf/cli/info.rb +1 -1
  10. data/lib/hexapdf/cli/inspect.rb +1 -1
  11. data/lib/hexapdf/cli/merge.rb +1 -1
  12. data/lib/hexapdf/cli/modify.rb +1 -1
  13. data/lib/hexapdf/cli/optimize.rb +1 -1
  14. data/lib/hexapdf/cli/split.rb +1 -1
  15. data/lib/hexapdf/cli/watermark.rb +1 -1
  16. data/lib/hexapdf/cli.rb +3 -1
  17. data/lib/hexapdf/composer.rb +1 -1
  18. data/lib/hexapdf/configuration.rb +11 -2
  19. data/lib/hexapdf/content/canvas.rb +658 -167
  20. data/lib/hexapdf/content/color_space.rb +185 -3
  21. data/lib/hexapdf/content/graphic_object/arc.rb +111 -12
  22. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  23. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  24. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  25. data/lib/hexapdf/content/graphic_object.rb +1 -1
  26. data/lib/hexapdf/content/graphics_state.rb +1 -1
  27. data/lib/hexapdf/content/operator.rb +1 -1
  28. data/lib/hexapdf/content/parser.rb +1 -1
  29. data/lib/hexapdf/content/processor.rb +1 -1
  30. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  31. data/lib/hexapdf/content.rb +1 -1
  32. data/lib/hexapdf/data_dir.rb +1 -1
  33. data/lib/hexapdf/dictionary.rb +1 -1
  34. data/lib/hexapdf/dictionary_fields.rb +30 -4
  35. data/lib/hexapdf/document/files.rb +3 -3
  36. data/lib/hexapdf/document/fonts.rb +1 -1
  37. data/lib/hexapdf/document/images.rb +1 -1
  38. data/lib/hexapdf/document/pages.rb +1 -1
  39. data/lib/hexapdf/document.rb +1 -1
  40. data/lib/hexapdf/encryption/aes.rb +1 -1
  41. data/lib/hexapdf/encryption/arc4.rb +1 -1
  42. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  43. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  44. data/lib/hexapdf/encryption/identity.rb +1 -1
  45. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  46. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  47. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  48. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  49. data/lib/hexapdf/encryption.rb +1 -1
  50. data/lib/hexapdf/error.rb +1 -1
  51. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  52. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  53. data/lib/hexapdf/filter/crypt.rb +1 -1
  54. data/lib/hexapdf/filter/encryption.rb +1 -1
  55. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  56. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  57. data/lib/hexapdf/filter/pass_through.rb +1 -1
  58. data/lib/hexapdf/filter/predictor.rb +1 -1
  59. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  60. data/lib/hexapdf/filter.rb +1 -1
  61. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  62. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  63. data/lib/hexapdf/font/cmap.rb +1 -1
  64. data/lib/hexapdf/font/encoding/base.rb +1 -1
  65. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  66. data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
  67. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  68. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  69. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  70. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  71. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  72. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  73. data/lib/hexapdf/font/encoding.rb +1 -1
  74. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  75. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  76. data/lib/hexapdf/font/true_type/font.rb +1 -1
  77. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  78. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  79. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  80. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  81. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  82. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  83. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  84. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  85. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  86. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  87. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  88. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  89. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  90. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  91. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  92. data/lib/hexapdf/font/true_type/table.rb +1 -1
  93. data/lib/hexapdf/font/true_type.rb +1 -1
  94. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  95. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  96. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  97. data/lib/hexapdf/font/type1/font.rb +1 -1
  98. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  99. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  100. data/lib/hexapdf/font/type1.rb +1 -1
  101. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  102. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  103. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  104. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  105. data/lib/hexapdf/font_loader.rb +1 -1
  106. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  107. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  108. data/lib/hexapdf/image_loader/png.rb +1 -1
  109. data/lib/hexapdf/image_loader.rb +1 -1
  110. data/lib/hexapdf/importer.rb +1 -1
  111. data/lib/hexapdf/layout/box.rb +4 -2
  112. data/lib/hexapdf/layout/frame.rb +1 -1
  113. data/lib/hexapdf/layout/image_box.rb +1 -1
  114. data/lib/hexapdf/layout/inline_box.rb +1 -1
  115. data/lib/hexapdf/layout/line.rb +1 -1
  116. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  117. data/lib/hexapdf/layout/style.rb +40 -2
  118. data/lib/hexapdf/layout/text_box.rb +1 -1
  119. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  120. data/lib/hexapdf/layout/text_layouter.rb +1 -1
  121. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  122. data/lib/hexapdf/layout/width_from_polygon.rb +2 -2
  123. data/lib/hexapdf/layout.rb +1 -1
  124. data/lib/hexapdf/name_tree_node.rb +1 -1
  125. data/lib/hexapdf/number_tree_node.rb +1 -1
  126. data/lib/hexapdf/object.rb +1 -1
  127. data/lib/hexapdf/parser.rb +2 -2
  128. data/lib/hexapdf/pdf_array.rb +1 -1
  129. data/lib/hexapdf/rectangle.rb +1 -1
  130. data/lib/hexapdf/reference.rb +1 -1
  131. data/lib/hexapdf/revision.rb +1 -1
  132. data/lib/hexapdf/revisions.rb +1 -1
  133. data/lib/hexapdf/serializer.rb +1 -1
  134. data/lib/hexapdf/stream.rb +1 -1
  135. data/lib/hexapdf/task/dereference.rb +1 -1
  136. data/lib/hexapdf/task/optimize.rb +1 -1
  137. data/lib/hexapdf/task.rb +1 -1
  138. data/lib/hexapdf/tokenizer.rb +1 -1
  139. data/lib/hexapdf/type/acro_form/appearance_generator.rb +14 -7
  140. data/lib/hexapdf/type/acro_form/button_field.rb +53 -28
  141. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  142. data/lib/hexapdf/type/acro_form/field.rb +21 -2
  143. data/lib/hexapdf/type/acro_form/form.rb +48 -29
  144. data/lib/hexapdf/type/acro_form/text_field.rb +2 -2
  145. data/lib/hexapdf/type/acro_form/variable_text_field.rb +17 -9
  146. data/lib/hexapdf/type/acro_form.rb +1 -1
  147. data/lib/hexapdf/type/action.rb +1 -1
  148. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  149. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  150. data/lib/hexapdf/type/actions/launch.rb +1 -1
  151. data/lib/hexapdf/type/actions/uri.rb +1 -1
  152. data/lib/hexapdf/type/actions.rb +1 -1
  153. data/lib/hexapdf/type/annotation.rb +1 -1
  154. data/lib/hexapdf/type/annotations/link.rb +1 -1
  155. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  156. data/lib/hexapdf/type/annotations/text.rb +1 -1
  157. data/lib/hexapdf/type/annotations/widget.rb +2 -2
  158. data/lib/hexapdf/type/annotations.rb +1 -1
  159. data/lib/hexapdf/type/catalog.rb +1 -1
  160. data/lib/hexapdf/type/cid_font.rb +1 -1
  161. data/lib/hexapdf/type/embedded_file.rb +1 -1
  162. data/lib/hexapdf/type/file_specification.rb +1 -1
  163. data/lib/hexapdf/type/font.rb +1 -1
  164. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  165. data/lib/hexapdf/type/font_simple.rb +1 -1
  166. data/lib/hexapdf/type/font_true_type.rb +1 -1
  167. data/lib/hexapdf/type/font_type0.rb +1 -1
  168. data/lib/hexapdf/type/font_type1.rb +1 -1
  169. data/lib/hexapdf/type/font_type3.rb +1 -1
  170. data/lib/hexapdf/type/form.rb +1 -1
  171. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  172. data/lib/hexapdf/type/icon_fit.rb +1 -1
  173. data/lib/hexapdf/type/image.rb +1 -1
  174. data/lib/hexapdf/type/info.rb +1 -1
  175. data/lib/hexapdf/type/names.rb +1 -1
  176. data/lib/hexapdf/type/object_stream.rb +1 -1
  177. data/lib/hexapdf/type/page.rb +15 -1
  178. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  179. data/lib/hexapdf/type/resources.rb +1 -1
  180. data/lib/hexapdf/type/trailer.rb +1 -1
  181. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  182. data/lib/hexapdf/type/xref_stream.rb +1 -1
  183. data/lib/hexapdf/type.rb +1 -1
  184. data/lib/hexapdf/utils/bit_field.rb +1 -1
  185. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  186. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  187. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  188. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  189. data/lib/hexapdf/utils/object_hash.rb +1 -1
  190. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  191. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  192. data/lib/hexapdf/version.rb +2 -2
  193. data/lib/hexapdf/writer.rb +1 -1
  194. data/lib/hexapdf/xref_section.rb +1 -1
  195. data/lib/hexapdf.rb +1 -1
  196. metadata +5 -264
  197. data/CHANGELOG.md +0 -954
  198. data/LICENSE +0 -29
  199. data/README.md +0 -120
  200. data/Rakefile +0 -108
  201. data/agpl-3.0.txt +0 -661
  202. data/examples/001-hello_world.rb +0 -16
  203. data/examples/002-graphics.rb +0 -275
  204. data/examples/003-arcs.rb +0 -50
  205. data/examples/004-optimizing.rb +0 -23
  206. data/examples/005-merging.rb +0 -27
  207. data/examples/006-standard_pdf_fonts.rb +0 -73
  208. data/examples/007-truetype.rb +0 -42
  209. data/examples/008-show_char_bboxes.rb +0 -55
  210. data/examples/009-text_layouter_alignment.rb +0 -47
  211. data/examples/010-text_layouter_inline_boxes.rb +0 -64
  212. data/examples/011-text_layouter_line_wrapping.rb +0 -57
  213. data/examples/012-text_layouter_styling.rb +0 -122
  214. data/examples/013-text_layouter_shapes.rb +0 -176
  215. data/examples/014-text_in_polygon.rb +0 -60
  216. data/examples/015-boxes.rb +0 -76
  217. data/examples/016-frame_automatic_box_placement.rb +0 -90
  218. data/examples/017-frame_text_flow.rb +0 -60
  219. data/examples/018-composer.rb +0 -44
  220. data/examples/019-acro_form.rb +0 -88
  221. data/examples/emoji-smile.png +0 -0
  222. data/examples/emoji-wink.png +0 -0
  223. data/examples/machupicchu.jpg +0 -0
  224. data/test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz +0 -0
  225. data/test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz +0 -0
  226. data/test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz +0 -0
  227. data/test/data/aes-test-vectors/CBCGFSbox-192-encrypt.data.gz +0 -0
  228. data/test/data/aes-test-vectors/CBCGFSbox-256-decrypt.data.gz +0 -0
  229. data/test/data/aes-test-vectors/CBCGFSbox-256-encrypt.data.gz +0 -0
  230. data/test/data/aes-test-vectors/CBCKeySbox-128-decrypt.data.gz +0 -0
  231. data/test/data/aes-test-vectors/CBCKeySbox-128-encrypt.data.gz +0 -0
  232. data/test/data/aes-test-vectors/CBCKeySbox-192-decrypt.data.gz +0 -0
  233. data/test/data/aes-test-vectors/CBCKeySbox-192-encrypt.data.gz +0 -0
  234. data/test/data/aes-test-vectors/CBCKeySbox-256-decrypt.data.gz +0 -0
  235. data/test/data/aes-test-vectors/CBCKeySbox-256-encrypt.data.gz +0 -0
  236. data/test/data/aes-test-vectors/CBCVarKey-128-decrypt.data.gz +0 -0
  237. data/test/data/aes-test-vectors/CBCVarKey-128-encrypt.data.gz +0 -0
  238. data/test/data/aes-test-vectors/CBCVarKey-192-decrypt.data.gz +0 -0
  239. data/test/data/aes-test-vectors/CBCVarKey-192-encrypt.data.gz +0 -0
  240. data/test/data/aes-test-vectors/CBCVarKey-256-decrypt.data.gz +0 -0
  241. data/test/data/aes-test-vectors/CBCVarKey-256-encrypt.data.gz +0 -0
  242. data/test/data/aes-test-vectors/CBCVarTxt-128-decrypt.data.gz +0 -0
  243. data/test/data/aes-test-vectors/CBCVarTxt-128-encrypt.data.gz +0 -0
  244. data/test/data/aes-test-vectors/CBCVarTxt-192-decrypt.data.gz +0 -0
  245. data/test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz +0 -0
  246. data/test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz +0 -0
  247. data/test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz +0 -0
  248. data/test/data/fonts/Ubuntu-Title.ttf +0 -0
  249. data/test/data/images/cmyk.jpg +0 -0
  250. data/test/data/images/fillbytes.jpg +0 -0
  251. data/test/data/images/gray.jpg +0 -0
  252. data/test/data/images/greyscale-1bit.png +0 -0
  253. data/test/data/images/greyscale-2bit.png +0 -0
  254. data/test/data/images/greyscale-4bit.png +0 -0
  255. data/test/data/images/greyscale-8bit.png +0 -0
  256. data/test/data/images/greyscale-alpha-8bit.png +0 -0
  257. data/test/data/images/greyscale-trns-8bit.png +0 -0
  258. data/test/data/images/greyscale-with-gamma1.0.png +0 -0
  259. data/test/data/images/greyscale-with-gamma1.5.png +0 -0
  260. data/test/data/images/indexed-1bit.png +0 -0
  261. data/test/data/images/indexed-2bit.png +0 -0
  262. data/test/data/images/indexed-4bit.png +0 -0
  263. data/test/data/images/indexed-8bit.png +0 -0
  264. data/test/data/images/indexed-alpha-4bit.png +0 -0
  265. data/test/data/images/indexed-alpha-8bit.png +0 -0
  266. data/test/data/images/rgb.jpg +0 -0
  267. data/test/data/images/truecolour-8bit.png +0 -0
  268. data/test/data/images/truecolour-alpha-8bit.png +0 -0
  269. data/test/data/images/truecolour-gama-chrm-8bit.png +0 -0
  270. data/test/data/images/truecolour-srgb-8bit.png +0 -0
  271. data/test/data/images/ycck.jpg +0 -0
  272. data/test/data/minimal.pdf +0 -44
  273. data/test/data/standard-security-handler/README +0 -9
  274. data/test/data/standard-security-handler/bothpwd-aes-128bit-V4.pdf +0 -44
  275. data/test/data/standard-security-handler/bothpwd-aes-256bit-V5.pdf +0 -0
  276. data/test/data/standard-security-handler/bothpwd-arc4-128bit-V2.pdf +0 -43
  277. data/test/data/standard-security-handler/bothpwd-arc4-128bit-V4.pdf +0 -43
  278. data/test/data/standard-security-handler/bothpwd-arc4-40bit-V1.pdf +0 -0
  279. data/test/data/standard-security-handler/nopwd-aes-128bit-V4.pdf +0 -43
  280. data/test/data/standard-security-handler/nopwd-aes-256bit-V5.pdf +0 -0
  281. data/test/data/standard-security-handler/nopwd-arc4-128bit-V2.pdf +0 -43
  282. data/test/data/standard-security-handler/nopwd-arc4-128bit-V4.pdf +0 -43
  283. data/test/data/standard-security-handler/nopwd-arc4-40bit-V1.pdf +0 -43
  284. data/test/data/standard-security-handler/ownerpwd-aes-128bit-V4.pdf +0 -0
  285. data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5.pdf +0 -43
  286. data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V2.pdf +0 -43
  287. data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V4.pdf +0 -43
  288. data/test/data/standard-security-handler/ownerpwd-arc4-40bit-V1.pdf +0 -43
  289. data/test/data/standard-security-handler/userpwd-aes-128bit-V4.pdf +0 -43
  290. data/test/data/standard-security-handler/userpwd-aes-256bit-V5.pdf +0 -43
  291. data/test/data/standard-security-handler/userpwd-arc4-128bit-V2.pdf +0 -0
  292. data/test/data/standard-security-handler/userpwd-arc4-128bit-V4.pdf +0 -0
  293. data/test/data/standard-security-handler/userpwd-arc4-40bit-V1.pdf +0 -43
  294. data/test/hexapdf/common_tokenizer_tests.rb +0 -236
  295. data/test/hexapdf/content/common.rb +0 -39
  296. data/test/hexapdf/content/graphic_object/test_arc.rb +0 -93
  297. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -90
  298. data/test/hexapdf/content/graphic_object/test_geom2d.rb +0 -79
  299. data/test/hexapdf/content/graphic_object/test_solid_arc.rb +0 -86
  300. data/test/hexapdf/content/test_canvas.rb +0 -1216
  301. data/test/hexapdf/content/test_color_space.rb +0 -164
  302. data/test/hexapdf/content/test_graphics_state.rb +0 -151
  303. data/test/hexapdf/content/test_operator.rb +0 -619
  304. data/test/hexapdf/content/test_parser.rb +0 -99
  305. data/test/hexapdf/content/test_processor.rb +0 -163
  306. data/test/hexapdf/content/test_transformation_matrix.rb +0 -64
  307. data/test/hexapdf/document/test_files.rb +0 -72
  308. data/test/hexapdf/document/test_fonts.rb +0 -60
  309. data/test/hexapdf/document/test_images.rb +0 -72
  310. data/test/hexapdf/document/test_pages.rb +0 -130
  311. data/test/hexapdf/encryption/common.rb +0 -87
  312. data/test/hexapdf/encryption/test_aes.rb +0 -129
  313. data/test/hexapdf/encryption/test_arc4.rb +0 -39
  314. data/test/hexapdf/encryption/test_fast_aes.rb +0 -17
  315. data/test/hexapdf/encryption/test_fast_arc4.rb +0 -12
  316. data/test/hexapdf/encryption/test_identity.rb +0 -21
  317. data/test/hexapdf/encryption/test_ruby_aes.rb +0 -23
  318. data/test/hexapdf/encryption/test_ruby_arc4.rb +0 -20
  319. data/test/hexapdf/encryption/test_security_handler.rb +0 -380
  320. data/test/hexapdf/encryption/test_standard_security_handler.rb +0 -322
  321. data/test/hexapdf/filter/common.rb +0 -53
  322. data/test/hexapdf/filter/test_ascii85_decode.rb +0 -59
  323. data/test/hexapdf/filter/test_ascii_hex_decode.rb +0 -38
  324. data/test/hexapdf/filter/test_crypt.rb +0 -21
  325. data/test/hexapdf/filter/test_encryption.rb +0 -24
  326. data/test/hexapdf/filter/test_flate_decode.rb +0 -44
  327. data/test/hexapdf/filter/test_lzw_decode.rb +0 -52
  328. data/test/hexapdf/filter/test_predictor.rb +0 -219
  329. data/test/hexapdf/filter/test_run_length_decode.rb +0 -32
  330. data/test/hexapdf/font/cmap/test_parser.rb +0 -102
  331. data/test/hexapdf/font/cmap/test_writer.rb +0 -66
  332. data/test/hexapdf/font/encoding/test_base.rb +0 -45
  333. data/test/hexapdf/font/encoding/test_difference_encoding.rb +0 -29
  334. data/test/hexapdf/font/encoding/test_glyph_list.rb +0 -59
  335. data/test/hexapdf/font/encoding/test_zapf_dingbats_encoding.rb +0 -16
  336. data/test/hexapdf/font/test_cmap.rb +0 -104
  337. data/test/hexapdf/font/test_encoding.rb +0 -27
  338. data/test/hexapdf/font/test_invalid_glyph.rb +0 -34
  339. data/test/hexapdf/font/test_true_type_wrapper.rb +0 -186
  340. data/test/hexapdf/font/test_type1_wrapper.rb +0 -107
  341. data/test/hexapdf/font/true_type/common.rb +0 -17
  342. data/test/hexapdf/font/true_type/table/common.rb +0 -27
  343. data/test/hexapdf/font/true_type/table/test_cmap.rb +0 -47
  344. data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +0 -141
  345. data/test/hexapdf/font/true_type/table/test_directory.rb +0 -30
  346. data/test/hexapdf/font/true_type/table/test_glyf.rb +0 -58
  347. data/test/hexapdf/font/true_type/table/test_head.rb +0 -56
  348. data/test/hexapdf/font/true_type/table/test_hhea.rb +0 -26
  349. data/test/hexapdf/font/true_type/table/test_hmtx.rb +0 -30
  350. data/test/hexapdf/font/true_type/table/test_kern.rb +0 -61
  351. data/test/hexapdf/font/true_type/table/test_loca.rb +0 -33
  352. data/test/hexapdf/font/true_type/table/test_maxp.rb +0 -50
  353. data/test/hexapdf/font/true_type/table/test_name.rb +0 -76
  354. data/test/hexapdf/font/true_type/table/test_os2.rb +0 -55
  355. data/test/hexapdf/font/true_type/table/test_post.rb +0 -78
  356. data/test/hexapdf/font/true_type/test_builder.rb +0 -42
  357. data/test/hexapdf/font/true_type/test_font.rb +0 -116
  358. data/test/hexapdf/font/true_type/test_optimizer.rb +0 -26
  359. data/test/hexapdf/font/true_type/test_subsetter.rb +0 -73
  360. data/test/hexapdf/font/true_type/test_table.rb +0 -48
  361. data/test/hexapdf/font/type1/common.rb +0 -6
  362. data/test/hexapdf/font/type1/test_afm_parser.rb +0 -65
  363. data/test/hexapdf/font/type1/test_font.rb +0 -104
  364. data/test/hexapdf/font/type1/test_font_metrics.rb +0 -22
  365. data/test/hexapdf/font/type1/test_pfb_parser.rb +0 -37
  366. data/test/hexapdf/font_loader/test_from_configuration.rb +0 -43
  367. data/test/hexapdf/font_loader/test_from_file.rb +0 -36
  368. data/test/hexapdf/font_loader/test_standard14.rb +0 -33
  369. data/test/hexapdf/image_loader/test_jpeg.rb +0 -93
  370. data/test/hexapdf/image_loader/test_pdf.rb +0 -47
  371. data/test/hexapdf/image_loader/test_png.rb +0 -259
  372. data/test/hexapdf/layout/test_box.rb +0 -152
  373. data/test/hexapdf/layout/test_frame.rb +0 -350
  374. data/test/hexapdf/layout/test_image_box.rb +0 -73
  375. data/test/hexapdf/layout/test_inline_box.rb +0 -71
  376. data/test/hexapdf/layout/test_line.rb +0 -206
  377. data/test/hexapdf/layout/test_style.rb +0 -779
  378. data/test/hexapdf/layout/test_text_box.rb +0 -140
  379. data/test/hexapdf/layout/test_text_fragment.rb +0 -375
  380. data/test/hexapdf/layout/test_text_layouter.rb +0 -758
  381. data/test/hexapdf/layout/test_text_shaper.rb +0 -62
  382. data/test/hexapdf/layout/test_width_from_polygon.rb +0 -108
  383. data/test/hexapdf/task/test_dereference.rb +0 -51
  384. data/test/hexapdf/task/test_optimize.rb +0 -162
  385. data/test/hexapdf/test_composer.rb +0 -258
  386. data/test/hexapdf/test_configuration.rb +0 -93
  387. data/test/hexapdf/test_data_dir.rb +0 -32
  388. data/test/hexapdf/test_dictionary.rb +0 -340
  389. data/test/hexapdf/test_dictionary_fields.rb +0 -245
  390. data/test/hexapdf/test_document.rb +0 -641
  391. data/test/hexapdf/test_filter.rb +0 -100
  392. data/test/hexapdf/test_importer.rb +0 -106
  393. data/test/hexapdf/test_object.rb +0 -258
  394. data/test/hexapdf/test_parser.rb +0 -637
  395. data/test/hexapdf/test_pdf_array.rb +0 -169
  396. data/test/hexapdf/test_rectangle.rb +0 -73
  397. data/test/hexapdf/test_reference.rb +0 -50
  398. data/test/hexapdf/test_revision.rb +0 -188
  399. data/test/hexapdf/test_revisions.rb +0 -196
  400. data/test/hexapdf/test_serializer.rb +0 -195
  401. data/test/hexapdf/test_stream.rb +0 -274
  402. data/test/hexapdf/test_tokenizer.rb +0 -80
  403. data/test/hexapdf/test_type.rb +0 -18
  404. data/test/hexapdf/test_writer.rb +0 -140
  405. data/test/hexapdf/test_xref_section.rb +0 -61
  406. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +0 -794
  407. data/test/hexapdf/type/acro_form/test_button_field.rb +0 -302
  408. data/test/hexapdf/type/acro_form/test_choice_field.rb +0 -220
  409. data/test/hexapdf/type/acro_form/test_field.rb +0 -247
  410. data/test/hexapdf/type/acro_form/test_form.rb +0 -353
  411. data/test/hexapdf/type/acro_form/test_signature_field.rb +0 -38
  412. data/test/hexapdf/type/acro_form/test_text_field.rb +0 -195
  413. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +0 -77
  414. data/test/hexapdf/type/actions/test_launch.rb +0 -24
  415. data/test/hexapdf/type/actions/test_uri.rb +0 -23
  416. data/test/hexapdf/type/annotations/test_markup_annotation.rb +0 -22
  417. data/test/hexapdf/type/annotations/test_text.rb +0 -34
  418. data/test/hexapdf/type/annotations/test_widget.rb +0 -225
  419. data/test/hexapdf/type/test_annotation.rb +0 -97
  420. data/test/hexapdf/type/test_catalog.rb +0 -48
  421. data/test/hexapdf/type/test_cid_font.rb +0 -61
  422. data/test/hexapdf/type/test_file_specification.rb +0 -141
  423. data/test/hexapdf/type/test_font.rb +0 -67
  424. data/test/hexapdf/type/test_font_descriptor.rb +0 -61
  425. data/test/hexapdf/type/test_font_simple.rb +0 -176
  426. data/test/hexapdf/type/test_font_true_type.rb +0 -31
  427. data/test/hexapdf/type/test_font_type0.rb +0 -120
  428. data/test/hexapdf/type/test_font_type1.rb +0 -142
  429. data/test/hexapdf/type/test_font_type3.rb +0 -26
  430. data/test/hexapdf/type/test_form.rb +0 -120
  431. data/test/hexapdf/type/test_image.rb +0 -261
  432. data/test/hexapdf/type/test_info.rb +0 -9
  433. data/test/hexapdf/type/test_object_stream.rb +0 -117
  434. data/test/hexapdf/type/test_page.rb +0 -587
  435. data/test/hexapdf/type/test_page_tree_node.rb +0 -315
  436. data/test/hexapdf/type/test_resources.rb +0 -209
  437. data/test/hexapdf/type/test_trailer.rb +0 -116
  438. data/test/hexapdf/type/test_xref_stream.rb +0 -143
  439. data/test/hexapdf/utils/test_bit_field.rb +0 -63
  440. data/test/hexapdf/utils/test_bit_stream.rb +0 -69
  441. data/test/hexapdf/utils/test_graphics_helpers.rb +0 -37
  442. data/test/hexapdf/utils/test_lru_cache.rb +0 -22
  443. data/test/hexapdf/utils/test_object_hash.rb +0 -120
  444. data/test/hexapdf/utils/test_pdf_doc_encoding.rb +0 -18
  445. data/test/hexapdf/utils/test_sorted_tree_node.rb +0 -239
  446. data/test/test_helper.rb +0 -58
@@ -1,637 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'test_helper'
4
- require 'hexapdf/document'
5
- require 'hexapdf/parser'
6
- require 'stringio'
7
-
8
- describe HexaPDF::Parser do
9
- before do
10
- @document = HexaPDF::Document.new
11
- @document.config['parser.try_xref_reconstruction'] = false
12
- @document.add(@document.wrap(10, oid: 1, gen: 0))
13
-
14
- create_parser(<<~EOF)
15
- %PDF-1.7
16
-
17
- 1 0 obj
18
- 10
19
- endobj
20
-
21
- 2 0 obj
22
- [ 5 6 <</Length 10 >> (name) <4E6F762073 686D6F7A20 6B612070
23
- 6F702E>]
24
- endobj
25
-
26
- 3 15 obj<< /Length 1 0 R/Hallo 6/Filter /Fl/DecodeParms<<>> >>stream
27
- Hallo PDF!endstream
28
- endobj
29
-
30
- 4 0 obj
31
- <</Type /XRef /Length 3 /W [1 1 1] /Index [1 1] /Size 2 >> stream
32
- \x01\x0A\x00
33
- endstream
34
- endobj
35
-
36
- xref
37
- 0 4
38
- 0000000000 65535 f
39
- 0000000010 00000 n
40
- 0000000029 00000 n
41
- 0000000000 65535 f
42
- 3 1
43
- 0000000556 00000 n
44
- trailer
45
- << /Test (now) >>
46
- startxref
47
- 308
48
- %%EOF
49
- EOF
50
- end
51
-
52
- def create_parser(str)
53
- @parse_io = StringIO.new(str)
54
- @parser = HexaPDF::Parser.new(@parse_io, @document)
55
- end
56
-
57
- describe "parse_indirect_object" do
58
- it "reads indirect objects sequentially" do
59
- object, oid, gen, stream = @parser.parse_indirect_object
60
- assert_equal(1, oid)
61
- assert_equal(0, gen)
62
- assert_equal(10, object)
63
- assert_nil(stream)
64
-
65
- object, oid, gen, stream = @parser.parse_indirect_object
66
- assert_equal(2, oid)
67
- assert_equal(0, gen)
68
- assert_equal([5, 6, {Length: 10}, "name", "Nov shmoz ka pop."], object)
69
- assert_nil(stream)
70
-
71
- object, oid, gen, stream = @parser.parse_indirect_object
72
- assert_equal(3, oid)
73
- assert_equal(15, gen)
74
- assert_kind_of(HexaPDF::StreamData, stream)
75
- assert_equal([:Fl], stream.filter)
76
- assert_equal([{}], stream.decode_parms)
77
- assert_equal({Length: 10, Hallo: 6, Filter: :Fl, DecodeParms: {}}, object)
78
- end
79
-
80
- it "handles empty indirect objects by using PDF null for them" do
81
- create_parser("1 0 obj\nendobj")
82
- object, * = @parser.parse_indirect_object
83
- assert_nil(object)
84
- end
85
-
86
- it "handles keyword stream followed only by CR without LF" do
87
- create_parser("1 0 obj<</Length 2>> stream\r12\nendstream endobj")
88
- *, stream = @parser.parse_indirect_object
89
- assert_equal('12', TestHelper.collector(stream.fiber))
90
- end
91
-
92
- it "handles keyword stream followed by space and CR or LF" do
93
- create_parser("1 0 obj<</Length 2>> stream \n12\nendstream endobj")
94
- *, stream = @parser.parse_indirect_object
95
- assert_equal('12', TestHelper.collector(stream.fiber))
96
- end
97
-
98
- it "handles keyword stream followed by space and CR LF" do
99
- create_parser("1 0 obj<</Length 2>> stream \r\n12\nendstream endobj")
100
- *, stream = @parser.parse_indirect_object
101
- assert_equal('12', TestHelper.collector(stream.fiber))
102
- end
103
-
104
- it "handles invalid indirect object value consisting of number followed by endobj without space" do
105
- create_parser("1 0 obj 749endobj")
106
- object, * = @parser.parse_indirect_object
107
- assert_equal(749, object)
108
- end
109
-
110
- it "treats indirect objects with invalid values as null objects" do
111
- create_parser("1 0 obj <</test ( /other (end)>> endobj")
112
- object, * = @parser.parse_indirect_object
113
- assert_nil(object)
114
- end
115
-
116
- it "recovers from an invalid stream length value" do
117
- create_parser("1 0 obj<</Length 4>> stream\n12endstream endobj")
118
- obj, _, _, stream = @parser.parse_indirect_object
119
- assert_equal(2, obj[:Length])
120
- assert_equal('12', TestHelper.collector(stream.fiber))
121
- end
122
-
123
- it "works even if the keyword endobj is missing or mangled" do
124
- create_parser("1 0 obj<</Length 4>>5")
125
- object, * = @parser.parse_indirect_object
126
- assert_equal({Length: 4}, object)
127
- create_parser("1 0 obj<</Length 4>>endobjk")
128
- object, * = @parser.parse_indirect_object
129
- assert_equal({Length: 4}, object)
130
- end
131
-
132
- it "fails if the oid, gen or 'obj' keyword is invalid" do
133
- create_parser("a 0 obj\n5\nendobj")
134
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
135
- assert_match(/No valid object/, exp.message)
136
- create_parser("1 a obj\n5\nendobj")
137
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
138
- assert_match(/No valid object/, exp.message)
139
- create_parser("1 0 dobj\n5\nendobj")
140
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
141
- assert_match(/No valid object/, exp.message)
142
- end
143
-
144
- it "fails if the value of a stream is not a dictionary" do
145
- create_parser("1 0 obj\n(fail)\nstream\nendstream\nendobj\n")
146
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
147
- assert_match(/stream.*dictionary/, exp.message)
148
- end
149
-
150
- it "fails if the 'stream' keyword isn't followed by EOL" do
151
- create_parser("1 0 obj\n<< >>\nstream endstream\nendobj\n")
152
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object(0) }
153
- assert_match(/stream.*followed by LF/, exp.message)
154
- end
155
-
156
- it "fails if the 'endstream' keyword is missing" do
157
- create_parser("1 0 obj\n<< >>\nstream\nendobj\n")
158
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object(0) }
159
- assert_match(/stream.*followed by.*endstream/i, exp.message)
160
- end
161
-
162
- describe "with strict parsing" do
163
- before do
164
- @document.config['parser.on_correctable_error'] = proc { true }
165
- end
166
-
167
- it "fails if an empty indirect object is found" do
168
- create_parser("1 0 obj\nendobj")
169
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
170
- assert_match(/no indirect object value/i, exp.message)
171
- end
172
-
173
- it "fails if keyword stream is followed only by CR without LF" do
174
- create_parser("1 0 obj<</Length 2>> stream\r12\nendstream endobj")
175
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
176
- assert_match(/not CR alone/, exp.message)
177
- end
178
-
179
- it "fails if keyword stream is followed by space and CR or LF instead of LF or CR/LF" do
180
- create_parser("1 0 obj<</Length 2>> stream \n12\nendstream endobj")
181
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
182
- assert_match(/followed by space instead/, exp.message)
183
- end
184
-
185
- it "fails if keyword stream is followed by space and CR LF instead of LF or CR/LF" do
186
- create_parser("1 0 obj<</Length 2>> stream \r\n12\nendstream endobj")
187
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
188
- assert_match(/followed by space instead/, exp.message)
189
- end
190
-
191
- it "fails for numbers followed by endobj without space" do
192
- create_parser("1 0 obj 749endobj")
193
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
194
- assert_match(/Missing whitespace after number/, exp.message)
195
- end
196
-
197
- it "fails for invalid values" do
198
- create_parser("1 0 obj <</test ( /other (end)>> endobj")
199
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
200
- assert_match(/Invalid value after '1 0 obj'/, exp.message)
201
- end
202
-
203
- it "fails if the stream length value is invalid" do
204
- create_parser("1 0 obj<</Length 4>> stream\n12endstream endobj")
205
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
206
- assert_match(/invalid stream length/i, exp.message)
207
- end
208
-
209
- it "fails if the keyword endobj is mangled" do
210
- create_parser("1 0 obj\n<< >>\nendobjd\n")
211
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
212
- assert_match(/keyword endobj/, exp.message)
213
- end
214
-
215
- it "fails if the keyword endobj is missing" do
216
- create_parser("1 0 obj\n<< >>")
217
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object }
218
- assert_match(/keyword endobj/, exp.message)
219
- end
220
-
221
- it "fails if there is data between 'endstream' and 'endobj'" do
222
- create_parser("1 0 obj\n<< >>\nstream\nendstream\ntest\nendobj\n")
223
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_indirect_object(0) }
224
- assert_match(/keyword endobj/, exp.message)
225
- end
226
- end
227
- end
228
-
229
- describe "load_object" do
230
- before do
231
- @entry = HexaPDF::XRefSection.in_use_entry(2, 0, 29)
232
- end
233
-
234
- it "can load an indirect object" do
235
- obj = @parser.load_object(@entry)
236
- assert_kind_of(HexaPDF::Object, obj)
237
- assert_equal(5, obj.value[0])
238
- assert_equal(2, obj.oid)
239
- assert_equal(0, obj.gen)
240
- end
241
-
242
- it "can load a free object" do
243
- obj = @parser.load_object(HexaPDF::XRefSection.free_entry(0, 0))
244
- assert_kind_of(HexaPDF::Object, obj)
245
- assert_nil(obj.value)
246
- end
247
-
248
- it "can load a compressed object" do
249
- def (@document).object(_oid)
250
- obj = Object.new
251
- def obj.parse_stream
252
- HexaPDF::Type::ObjectStream::Data.new("5 [1 2]", [1, 2], [0, 2])
253
- end
254
- obj
255
- end
256
-
257
- obj = @parser.load_object(HexaPDF::XRefSection.compressed_entry(2, 3, 1))
258
- assert_kind_of(HexaPDF::Object, obj)
259
- assert_equal([1, 2], obj.value)
260
- end
261
-
262
- it "handles an invalid indirect object offset of 0" do
263
- obj = @parser.load_object(HexaPDF::XRefSection.in_use_entry(2, 0, 0))
264
- assert(obj.null?)
265
- assert_equal(2, obj.oid)
266
- assert_equal(0, obj.gen)
267
- end
268
-
269
- describe "with strict parsing" do
270
- it "raises an error if an indirect object has an offset of 0" do
271
- @document.config['parser.on_correctable_error'] = proc { true }
272
- exp = assert_raises(HexaPDF::MalformedPDFError) do
273
- @parser.load_object(HexaPDF::XRefSection.in_use_entry(2, 0, 0))
274
- end
275
- assert_match(/has offset 0/, exp.message)
276
- end
277
- end
278
-
279
- it "fails if another object is found instead of an object stream" do
280
- def (@document).object(_oid)
281
- :invalid
282
- end
283
- exp = assert_raises(HexaPDF::MalformedPDFError) do
284
- @parser.load_object(HexaPDF::XRefSection.compressed_entry(2, 1, 1))
285
- end
286
- assert_match(/not an object stream/, exp.message)
287
- end
288
-
289
- it "fails if the xref entry type is invalid" do
290
- exp = assert_raises(HexaPDF::MalformedPDFError) do
291
- @parser.load_object(HexaPDF::XRefSection::Entry.new(:invalid))
292
- end
293
- assert_match(/invalid cross-reference type/i, exp.message)
294
- end
295
-
296
- it "fails if the object/generation numbers don't match" do
297
- exp = assert_raises(HexaPDF::MalformedPDFError) do
298
- @entry.gen = 2
299
- @parser.load_object(@entry)
300
- end
301
- assert_match(/oid,gen.*don't match/, exp.message)
302
- end
303
- end
304
-
305
- describe "startxref_offset" do
306
- it "caches the offset value" do
307
- assert_equal(308, @parser.startxref_offset)
308
- @parser.instance_eval { @io }.string.sub!(/308\n/, "309\n")
309
- assert_equal(308, @parser.startxref_offset)
310
- end
311
-
312
- it "returns the correct offset" do
313
- assert_equal(308, @parser.startxref_offset)
314
- end
315
-
316
- it "ignores garbage at the end of the file" do
317
- create_parser("startxref\n5\n%%EOF" << "\nhallo" * 150)
318
- assert_equal(5, @parser.startxref_offset)
319
- end
320
-
321
- it "uses the last startxref if there are more than one" do
322
- create_parser("startxref\n5\n%%EOF\n\nsome garbage\n\nstartxref\n555\n%%EOF\n")
323
- assert_equal(555, @parser.startxref_offset)
324
- end
325
-
326
- it "finds the startxref anywhere in file" do
327
- create_parser("startxref\n5\n%%EOF" << "\nhallo" * 5000)
328
- assert_equal(5, @parser.startxref_offset)
329
- create_parser("startxref\n5\n%%EOF\n" << "h" * 1017)
330
- assert_equal(5, @parser.startxref_offset)
331
- end
332
-
333
- it "fails even in big files when nothing is found" do
334
- create_parser("\nhallo" * 5000)
335
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.startxref_offset }
336
- assert_match(/end-of-file marker not found/, exp.message)
337
- end
338
-
339
- it "fails if the %%EOF marker is missing" do
340
- create_parser("startxref\n5")
341
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.startxref_offset }
342
- assert_match(/end-of-file marker not found/, exp.message)
343
-
344
- create_parser("")
345
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.startxref_offset }
346
- assert_match(/end-of-file marker not found/, exp.message)
347
- end
348
-
349
- it "fails if the startxref keyword is missing" do
350
- create_parser("somexref\n5\n%%EOF")
351
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.startxref_offset }
352
- assert_match(/missing startxref/, exp.message)
353
- end
354
-
355
- it "fails on strict parsing if the startxref is not in the last part of the file" do
356
- @document.config['parser.on_correctable_error'] = proc { true }
357
- create_parser("startxref\n5\n%%EOF" << "\nhallo" * 5000)
358
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.startxref_offset }
359
- assert_match(/end-of-file marker not found/, exp.message)
360
- end
361
- end
362
-
363
- describe "file_header_version" do
364
- it "returns the correct version" do
365
- assert_equal('1.7', @parser.file_header_version)
366
- end
367
-
368
- it "fails if the header is mangled" do
369
- create_parser("%PDF-1\n")
370
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.file_header_version }
371
- assert_match(/file header/, exp.message)
372
- end
373
-
374
- it "fails if the header is missing" do
375
- create_parser("no header")
376
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.file_header_version }
377
- assert_match(/file header/, exp.message)
378
- end
379
-
380
- it "ignores junk at the beginning of the file and correctly calculates offset" do
381
- create_parser("junk" * 200 << "\n%PDF-1.4\n")
382
- assert_equal('1.4', @parser.file_header_version)
383
- assert_equal(801, @parser.instance_variable_get(:@header_offset))
384
- end
385
- end
386
-
387
- it "xref_section?" do
388
- assert(@parser.xref_section?(@parser.startxref_offset))
389
- refute(@parser.xref_section?(53))
390
- end
391
-
392
- describe "parse_xref_section_and_trailer" do
393
- it "works on a section with multiple sub sections" do
394
- section, trailer = @parser.parse_xref_section_and_trailer(@parser.startxref_offset)
395
- assert_equal({Test: 'now'}, trailer)
396
- assert_equal(HexaPDF::XRefSection.free_entry(0, 65535), section[0, 65535])
397
- assert_equal(HexaPDF::XRefSection.free_entry(3, 65535), section[3, 65535])
398
- assert_equal(HexaPDF::XRefSection.in_use_entry(1, 0, 10), section[1])
399
- end
400
-
401
- it "works for an empty section" do
402
- create_parser("xref\n0 0\ntrailer\n<</Name /Value >>\n")
403
- _, trailer = @parser.parse_xref_section_and_trailer(0)
404
- assert_equal({Name: :Value}, trailer)
405
- end
406
-
407
- it "handles xref type=n with offset=0" do
408
- create_parser("xref\n0 2\n0000000000 00000 n \n0000000000 00000 n \ntrailer\n<<>>\n")
409
- section, _trailer = @parser.parse_xref_section_and_trailer(0)
410
- assert_equal(HexaPDF::XRefSection.free_entry(1, 0), section[1])
411
- end
412
-
413
- it "handles xref type=n with gen>65535" do
414
- create_parser("xref\n0 2\n0000000000 00000 n \n0000000000 65536 n \ntrailer\n<<>>\n")
415
- section, _trailer = @parser.parse_xref_section_and_trailer(0)
416
- assert_equal(HexaPDF::XRefSection.free_entry(1, 65536), section[1])
417
- end
418
-
419
- it "handles xref with missing whitespace at end" do
420
- create_parser("xref\n0 2\n0000000000 00000 n\n0000000000 65536 n\ntrailer\n<<>>\n")
421
- section, _trailer = @parser.parse_xref_section_and_trailer(0)
422
- assert_equal(HexaPDF::XRefSection.free_entry(1, 65536), section[1])
423
- end
424
-
425
- it "fails if the xref keyword is missing/mangled" do
426
- create_parser("xTEf\n0 d\n0000000000 00000 n \ntrailer\n<< >>\n")
427
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
428
- assert_match(/keyword xref/, exp.message)
429
- end
430
-
431
- it "fails if a sub section header is mangled" do
432
- create_parser("xref\n0 d\n0000000000 00000 n \ntrailer\n<< >>\n")
433
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
434
- assert_match(/invalid cross-reference subsection/i, exp.message)
435
- end
436
-
437
- it "fails if a sub section entry is mangled" do
438
- create_parser("xref\n0 2\n000a000000 00000 n\n0000000000 65535 n\ntrailer\n<<>>\n")
439
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
440
- assert_match(/invalid cross-reference entry/i, exp.message)
441
- end
442
-
443
- it "fails if there is no trailer" do
444
- create_parser("xref\n0 1\n0000000000 00000 n \n")
445
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
446
- assert_match(/keyword trailer/i, exp.message)
447
- end
448
-
449
- it "fails if the trailer is not a PDF dictionary" do
450
- create_parser("xref\n0 1\n0000000000 00000 n \ntrailer\n(base)")
451
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
452
- assert_match(/dictionary/, exp.message)
453
- end
454
-
455
- describe "invalid numbering of main xref section" do
456
- it "handles the xref if the numbering is off by N" do
457
- create_parser(" 1 0 obj 1 endobj\n" \
458
- "xref\n1 2\n0000000000 65535 f \n0000000001 00000 n \ntrailer\n<<>>\n")
459
- section, _trailer = @parser.parse_xref_section_and_trailer(17)
460
- assert_equal(HexaPDF::XRefSection.in_use_entry(1, 0, 1), section[1])
461
- end
462
-
463
- it "fails if the first entry is not the one for oid=0" do
464
- create_parser(" 1 0 obj 1 endobj\n" \
465
- "xref\n1 2\n0000000000 00005 f \n0000000001 00000 n \ntrailer\n<<>>\n")
466
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(17) }
467
- assert_match(/Main.*invalid numbering/i, exp.message)
468
-
469
- create_parser(" 1 0 obj 1 endobj\n" \
470
- "xref\n1 2\n0000000001 00000 n \n0000000001 00000 n \ntrailer\n<<>>\n")
471
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(17) }
472
- assert_match(/Main.*invalid numbering/i, exp.message)
473
- end
474
-
475
- it "fails if the tested entry position is invalid" do
476
- create_parser(" 1 0 obj 1 endobj\n" \
477
- "xref\n1 2\n0000000000 65535 f \n0000000005 00000 n \ntrailer\n<<>>\n")
478
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(17) }
479
- assert_match(/Main.*invalid numbering/i, exp.message)
480
- end
481
-
482
- it "fails if the tested entry position's oid doesn't match the corrected entry oid" do
483
- create_parser(" 2 0 obj 1 endobj\n" \
484
- "xref\n1 2\n0000000000 65535 f \n0000000001 00000 n \ntrailer\n<<>>\n")
485
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(17) }
486
- assert_match(/Main.*invalid numbering/i, exp.message)
487
- end
488
- end
489
-
490
- describe "with strict parsing" do
491
- before do
492
- @document.config['parser.on_correctable_error'] = proc { true }
493
- end
494
-
495
- it "fails if xref type=n with offset=0" do
496
- create_parser("xref\n0 2\n0000000000 00000 n \n0000000000 00000 n \ntrailer\n<<>>\n")
497
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
498
- assert_match(/invalid.*cross-reference entry/i, exp.message)
499
- end
500
-
501
- it " fails xref type=n with gen>65535" do
502
- create_parser("xref\n0 2\n0000000000 00000 n \n0000000000 65536 n \ntrailer\n<<>>\n")
503
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
504
- assert_match(/invalid.*cross-reference entry/i, exp.message)
505
- end
506
-
507
- it "fails if trailing second whitespace is missing" do
508
- create_parser("xref\n0 1\n0000000000 00000 n\ntrailer\n<<>>\n")
509
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
510
- assert_match(/invalid.*cross-reference entry/i, exp.message)
511
- end
512
-
513
- it "fails if the main cross-reference section has invalid numbering" do
514
- create_parser("xref\n1 1\n0000000001 00000 n \ntrailer\n<<>>\n")
515
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.parse_xref_section_and_trailer(0) }
516
- assert_match(/Main.*invalid numbering/i, exp.message)
517
- end
518
- end
519
- end
520
-
521
- describe "load_revision" do
522
- it "works for a simple cross-reference section" do
523
- xref_section, trailer = @parser.load_revision(@parser.startxref_offset)
524
- assert_equal({Test: 'now'}, trailer)
525
- assert(xref_section[1].in_use?)
526
- end
527
-
528
- it "works for a cross-reference stream" do
529
- xref_section, trailer = @parser.load_revision(212)
530
- assert_equal({Size: 2}, trailer)
531
- assert(xref_section[1].in_use?)
532
- end
533
-
534
- it "fails if another object is found instead of a cross-reference stream" do
535
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.load_revision(10) }
536
- assert_match(/not a cross-reference stream/, exp.message)
537
- end
538
-
539
- it "fails if the cross-reference stream is missing data" do
540
- @parse_io.string[287..288] = ''
541
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.load_revision(212) }
542
- assert_match(/missing data/, exp.message)
543
- assert_equal(212, exp.pos)
544
- end
545
-
546
- it "fails on strict parsing if the cross-reference stream doesn't contain an entry for itself" do
547
- @document.config['parser.on_correctable_error'] = proc { true }
548
- create_parser("2 0 obj\n<</Type/XRef/Length 3/W [1 1 1]/Size 1>>" \
549
- "stream\n\x01\x0A\x00\nendstream endobj")
550
- exp = assert_raises(HexaPDF::MalformedPDFError) { @parser.load_revision(0) }
551
- assert_match(/entry for itself/, exp.message)
552
- end
553
- end
554
-
555
- describe "reconstruct_revision" do
556
- before do
557
- @document.config['parser.try_xref_reconstruction'] = true
558
- @xref = HexaPDF::XRefSection.in_use_entry(1, 0, 100)
559
- end
560
-
561
- it "serially parses the contents" do
562
- create_parser("1 0 obj\n5\nendobj\n1 0 obj\n6\nendobj\ntrailer\n<</Size 1>>")
563
- assert_equal(6, @parser.load_object(@xref).value)
564
- end
565
-
566
- it "uses a security handler for decrypting indirect objects if necessary" do
567
- handler = Minitest::Mock.new
568
- handler.expect(:decrypt, HexaPDF::Object.new(:result, oid: 1), [HexaPDF::Object])
569
- @document.instance_variable_set(:@security_handler, handler)
570
- create_parser("1 0 obj\n6\nendobj\ntrailer\n<</Size 1>>")
571
- assert_equal(:result, @parser.load_object(@xref).value)
572
- assert(handler.verify)
573
- end
574
-
575
- it "ignores parts where the starting line is split across lines" do
576
- create_parser("1 0 obj\n5\nendobj\n1 0\nobj\n6\nendobj\ntrailer\n<</Size 1>>")
577
- assert_equal(5, @parser.load_object(@xref).value)
578
- end
579
-
580
- it "handles the case when the specified object had an xref entry but is not found" do
581
- create_parser("3 0 obj\n5\nendobj\ntrailer\n<</Size 1>>")
582
- assert(@parser.load_object(@xref).null?)
583
- end
584
-
585
- it "handles cases where the line contains an invalid string that exceeds the read buffer" do
586
- create_parser("(1" << "(abc" * 32188 << "\n1 0 obj\n6\nendobj\ntrailer\n<</Size 1>>")
587
- assert_equal(6, @parser.load_object(@xref).value)
588
- end
589
-
590
- it "handles pathalogical cases which contain many opened literal strings" do
591
- time = Time.now
592
- create_parser("(1" << "(abc\n" * 10000 << "\n1 0 obj\n6\nendobj\ntrailer\n<</Size 1>>")
593
- assert_equal(6, @parser.load_object(@xref).value)
594
- assert(Time.now - time < 0.5, "Xref reconstruction takes too long")
595
- end
596
-
597
- it "ignores invalid objects" do
598
- create_parser("1 x obj\n5\nendobj\n1 0 xobj\n6\nendobj\n1 0 obj 4\nendobj\ntrailer\n<</Size 1>>")
599
- assert_equal(4, @parser.load_object(@xref).value)
600
- end
601
-
602
- it "ignores invalid lines" do
603
- create_parser("1 0 obj\n5\nendobj\nhello there\n1 0 obj\n6\nendobj\ntrailer\n<</Size 1>>")
604
- assert_equal(6, @parser.load_object(@xref).value)
605
- end
606
-
607
- it "uses the last trailer" do
608
- create_parser("trailer <</Size 1>>\ntrailer <</Size 2/Prev 342>>")
609
- assert_equal({Size: 2}, @parser.reconstructed_revision.trailer.value)
610
- end
611
-
612
- it "uses the first trailer in case of a linearized file" do
613
- create_parser("1 0 obj\n<</Linearized true>>\nendobj\ntrailer <</Size 1/Prev 342>>\ntrailer <</Size 2>>")
614
- assert_equal({Size: 1}, @parser.reconstructed_revision.trailer.value)
615
- end
616
-
617
- it "tries the trailer specified at the startxref position if no other is found" do
618
- create_parser("1 0 obj\n5\nendobj\nquack xref trailer <</Size 1/Prev 5>>\nstartxref\n22\n%%EOF")
619
- assert_equal({Size: 1}, @parser.reconstructed_revision.trailer.value)
620
- end
621
-
622
- it "constructs a trailer with a /Root entry if no valid trailer was found" do
623
- create_parser("1 0 obj\n<</Type /Catalog/Pages 2 0 R>>\nendobj\nxref trailer <</Size 1/Prev 5\n%%EOF")
624
- assert_equal({Root: HexaPDF::Reference.new(1, 0)}, @parser.reconstructed_revision.trailer.value)
625
- end
626
-
627
- it "fails if no valid trailer is found and couldn't be constructed" do
628
- create_parser("1 0 obj\n5\nendobj\nquack trailer <</Size 1>>\nstartxref\n22\n%%EOF")
629
- assert_raises(HexaPDF::MalformedPDFError) { @parser.reconstructed_revision.trailer }
630
- end
631
-
632
- it "fails if no valid trailer is found" do
633
- create_parser("1 0 obj\n5\nendobj")
634
- assert_raises(HexaPDF::MalformedPDFError) { @parser.load_object(@xref) }
635
- end
636
- end
637
- end