hexapdf 0.17.1 → 0.17.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1024 -0
- data/LICENSE +29 -0
- data/README.md +129 -0
- data/Rakefile +109 -0
- data/agpl-3.0.txt +661 -0
- data/examples/001-hello_world.rb +16 -0
- data/examples/002-graphics.rb +275 -0
- data/examples/003-arcs.rb +50 -0
- data/examples/004-optimizing.rb +23 -0
- data/examples/005-merging.rb +27 -0
- data/examples/006-standard_pdf_fonts.rb +73 -0
- data/examples/007-truetype.rb +42 -0
- data/examples/008-show_char_bboxes.rb +55 -0
- data/examples/009-text_layouter_alignment.rb +47 -0
- data/examples/010-text_layouter_inline_boxes.rb +64 -0
- data/examples/011-text_layouter_line_wrapping.rb +57 -0
- data/examples/012-text_layouter_styling.rb +122 -0
- data/examples/013-text_layouter_shapes.rb +176 -0
- data/examples/014-text_in_polygon.rb +60 -0
- data/examples/015-boxes.rb +76 -0
- data/examples/016-frame_automatic_box_placement.rb +90 -0
- data/examples/017-frame_text_flow.rb +60 -0
- data/examples/018-composer.rb +44 -0
- data/examples/019-acro_form.rb +88 -0
- data/examples/emoji-smile.png +0 -0
- data/examples/emoji-wink.png +0 -0
- data/examples/machupicchu.jpg +0 -0
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -0
- data/lib/hexapdf/content/graphic_object/geom2d.rb +13 -0
- data/lib/hexapdf/version.rb +1 -1
- data/test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCGFSbox-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCKeySbox-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarKey-256-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-128-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-128-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-192-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz +0 -0
- data/test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz +0 -0
- data/test/data/fonts/Ubuntu-Title.ttf +0 -0
- data/test/data/images/cmyk.jpg +0 -0
- data/test/data/images/fillbytes.jpg +0 -0
- data/test/data/images/gray.jpg +0 -0
- data/test/data/images/greyscale-1bit.png +0 -0
- data/test/data/images/greyscale-2bit.png +0 -0
- data/test/data/images/greyscale-4bit.png +0 -0
- data/test/data/images/greyscale-8bit.png +0 -0
- data/test/data/images/greyscale-alpha-8bit.png +0 -0
- data/test/data/images/greyscale-trns-8bit.png +0 -0
- data/test/data/images/greyscale-with-gamma1.0.png +0 -0
- data/test/data/images/greyscale-with-gamma1.5.png +0 -0
- data/test/data/images/indexed-1bit.png +0 -0
- data/test/data/images/indexed-2bit.png +0 -0
- data/test/data/images/indexed-4bit.png +0 -0
- data/test/data/images/indexed-8bit.png +0 -0
- data/test/data/images/indexed-alpha-4bit.png +0 -0
- data/test/data/images/indexed-alpha-8bit.png +0 -0
- data/test/data/images/rgb.jpg +0 -0
- data/test/data/images/truecolour-8bit.png +0 -0
- data/test/data/images/truecolour-alpha-8bit.png +0 -0
- data/test/data/images/truecolour-gama-chrm-8bit.png +0 -0
- data/test/data/images/truecolour-srgb-8bit.png +0 -0
- data/test/data/images/ycck.jpg +0 -0
- data/test/data/minimal.pdf +44 -0
- data/test/data/standard-security-handler/README +9 -0
- data/test/data/standard-security-handler/bothpwd-aes-128bit-V4.pdf +44 -0
- data/test/data/standard-security-handler/bothpwd-aes-256bit-V5.pdf +0 -0
- data/test/data/standard-security-handler/bothpwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/bothpwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/bothpwd-arc4-40bit-V1.pdf +0 -0
- data/test/data/standard-security-handler/nopwd-aes-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-aes-256bit-V5.pdf +0 -0
- data/test/data/standard-security-handler/nopwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/nopwd-arc4-40bit-V1.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-aes-128bit-V4.pdf +0 -0
- data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V2.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/ownerpwd-arc4-40bit-V1.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-128bit-V4.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-aes-256bit-V5.pdf +43 -0
- data/test/data/standard-security-handler/userpwd-arc4-128bit-V2.pdf +0 -0
- data/test/data/standard-security-handler/userpwd-arc4-128bit-V4.pdf +0 -0
- data/test/data/standard-security-handler/userpwd-arc4-40bit-V1.pdf +43 -0
- data/test/hexapdf/common_tokenizer_tests.rb +236 -0
- data/test/hexapdf/content/common.rb +39 -0
- data/test/hexapdf/content/graphic_object/test_arc.rb +102 -0
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +90 -0
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +79 -0
- data/test/hexapdf/content/graphic_object/test_solid_arc.rb +86 -0
- data/test/hexapdf/content/test_canvas.rb +1279 -0
- data/test/hexapdf/content/test_color_space.rb +176 -0
- data/test/hexapdf/content/test_graphics_state.rb +151 -0
- data/test/hexapdf/content/test_operator.rb +619 -0
- data/test/hexapdf/content/test_parser.rb +99 -0
- data/test/hexapdf/content/test_processor.rb +163 -0
- data/test/hexapdf/content/test_transformation_matrix.rb +64 -0
- data/test/hexapdf/document/test_files.rb +72 -0
- data/test/hexapdf/document/test_fonts.rb +60 -0
- data/test/hexapdf/document/test_images.rb +72 -0
- data/test/hexapdf/document/test_pages.rb +130 -0
- data/test/hexapdf/encryption/common.rb +87 -0
- data/test/hexapdf/encryption/test_aes.rb +129 -0
- data/test/hexapdf/encryption/test_arc4.rb +39 -0
- data/test/hexapdf/encryption/test_fast_aes.rb +17 -0
- data/test/hexapdf/encryption/test_fast_arc4.rb +12 -0
- data/test/hexapdf/encryption/test_identity.rb +21 -0
- data/test/hexapdf/encryption/test_ruby_aes.rb +23 -0
- data/test/hexapdf/encryption/test_ruby_arc4.rb +20 -0
- data/test/hexapdf/encryption/test_security_handler.rb +380 -0
- data/test/hexapdf/encryption/test_standard_security_handler.rb +322 -0
- data/test/hexapdf/filter/common.rb +53 -0
- data/test/hexapdf/filter/test_ascii85_decode.rb +59 -0
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +38 -0
- data/test/hexapdf/filter/test_crypt.rb +21 -0
- data/test/hexapdf/filter/test_encryption.rb +24 -0
- data/test/hexapdf/filter/test_flate_decode.rb +44 -0
- data/test/hexapdf/filter/test_lzw_decode.rb +52 -0
- data/test/hexapdf/filter/test_predictor.rb +219 -0
- data/test/hexapdf/filter/test_run_length_decode.rb +32 -0
- data/test/hexapdf/font/cmap/test_parser.rb +102 -0
- data/test/hexapdf/font/cmap/test_writer.rb +66 -0
- data/test/hexapdf/font/encoding/test_base.rb +45 -0
- data/test/hexapdf/font/encoding/test_difference_encoding.rb +29 -0
- data/test/hexapdf/font/encoding/test_glyph_list.rb +59 -0
- data/test/hexapdf/font/encoding/test_zapf_dingbats_encoding.rb +16 -0
- data/test/hexapdf/font/test_cmap.rb +104 -0
- data/test/hexapdf/font/test_encoding.rb +27 -0
- data/test/hexapdf/font/test_invalid_glyph.rb +34 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +186 -0
- data/test/hexapdf/font/test_type1_wrapper.rb +107 -0
- data/test/hexapdf/font/true_type/common.rb +17 -0
- data/test/hexapdf/font/true_type/table/common.rb +27 -0
- data/test/hexapdf/font/true_type/table/test_cmap.rb +47 -0
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +141 -0
- data/test/hexapdf/font/true_type/table/test_directory.rb +30 -0
- data/test/hexapdf/font/true_type/table/test_glyf.rb +58 -0
- data/test/hexapdf/font/true_type/table/test_head.rb +56 -0
- data/test/hexapdf/font/true_type/table/test_hhea.rb +26 -0
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +30 -0
- data/test/hexapdf/font/true_type/table/test_kern.rb +61 -0
- data/test/hexapdf/font/true_type/table/test_loca.rb +33 -0
- data/test/hexapdf/font/true_type/table/test_maxp.rb +50 -0
- data/test/hexapdf/font/true_type/table/test_name.rb +76 -0
- data/test/hexapdf/font/true_type/table/test_os2.rb +55 -0
- data/test/hexapdf/font/true_type/table/test_post.rb +78 -0
- data/test/hexapdf/font/true_type/test_builder.rb +42 -0
- data/test/hexapdf/font/true_type/test_font.rb +116 -0
- data/test/hexapdf/font/true_type/test_optimizer.rb +26 -0
- data/test/hexapdf/font/true_type/test_subsetter.rb +73 -0
- data/test/hexapdf/font/true_type/test_table.rb +48 -0
- data/test/hexapdf/font/type1/common.rb +6 -0
- data/test/hexapdf/font/type1/test_afm_parser.rb +65 -0
- data/test/hexapdf/font/type1/test_font.rb +104 -0
- data/test/hexapdf/font/type1/test_font_metrics.rb +22 -0
- data/test/hexapdf/font/type1/test_pfb_parser.rb +37 -0
- data/test/hexapdf/font_loader/test_from_configuration.rb +43 -0
- data/test/hexapdf/font_loader/test_from_file.rb +36 -0
- data/test/hexapdf/font_loader/test_standard14.rb +33 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +93 -0
- data/test/hexapdf/image_loader/test_pdf.rb +47 -0
- data/test/hexapdf/image_loader/test_png.rb +259 -0
- data/test/hexapdf/layout/test_box.rb +154 -0
- data/test/hexapdf/layout/test_frame.rb +350 -0
- data/test/hexapdf/layout/test_image_box.rb +73 -0
- data/test/hexapdf/layout/test_inline_box.rb +71 -0
- data/test/hexapdf/layout/test_line.rb +206 -0
- data/test/hexapdf/layout/test_style.rb +790 -0
- data/test/hexapdf/layout/test_text_box.rb +140 -0
- data/test/hexapdf/layout/test_text_fragment.rb +375 -0
- data/test/hexapdf/layout/test_text_layouter.rb +758 -0
- data/test/hexapdf/layout/test_text_shaper.rb +62 -0
- data/test/hexapdf/layout/test_width_from_polygon.rb +109 -0
- data/test/hexapdf/task/test_dereference.rb +51 -0
- data/test/hexapdf/task/test_optimize.rb +162 -0
- data/test/hexapdf/test_composer.rb +258 -0
- data/test/hexapdf/test_configuration.rb +93 -0
- data/test/hexapdf/test_data_dir.rb +32 -0
- data/test/hexapdf/test_dictionary.rb +340 -0
- data/test/hexapdf/test_dictionary_fields.rb +269 -0
- data/test/hexapdf/test_document.rb +641 -0
- data/test/hexapdf/test_filter.rb +100 -0
- data/test/hexapdf/test_importer.rb +106 -0
- data/test/hexapdf/test_object.rb +258 -0
- data/test/hexapdf/test_parser.rb +645 -0
- data/test/hexapdf/test_pdf_array.rb +169 -0
- data/test/hexapdf/test_rectangle.rb +73 -0
- data/test/hexapdf/test_reference.rb +50 -0
- data/test/hexapdf/test_revision.rb +188 -0
- data/test/hexapdf/test_revisions.rb +196 -0
- data/test/hexapdf/test_serializer.rb +195 -0
- data/test/hexapdf/test_stream.rb +274 -0
- data/test/hexapdf/test_tokenizer.rb +80 -0
- data/test/hexapdf/test_type.rb +18 -0
- data/test/hexapdf/test_writer.rb +140 -0
- data/test/hexapdf/test_xref_section.rb +61 -0
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +795 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +308 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +220 -0
- data/test/hexapdf/type/acro_form/test_field.rb +259 -0
- data/test/hexapdf/type/acro_form/test_form.rb +357 -0
- data/test/hexapdf/type/acro_form/test_signature_field.rb +38 -0
- data/test/hexapdf/type/acro_form/test_text_field.rb +201 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +88 -0
- data/test/hexapdf/type/actions/test_launch.rb +24 -0
- data/test/hexapdf/type/actions/test_uri.rb +23 -0
- data/test/hexapdf/type/annotations/test_markup_annotation.rb +22 -0
- data/test/hexapdf/type/annotations/test_text.rb +34 -0
- data/test/hexapdf/type/annotations/test_widget.rb +225 -0
- data/test/hexapdf/type/test_annotation.rb +97 -0
- data/test/hexapdf/type/test_catalog.rb +48 -0
- data/test/hexapdf/type/test_cid_font.rb +61 -0
- data/test/hexapdf/type/test_file_specification.rb +141 -0
- data/test/hexapdf/type/test_font.rb +67 -0
- data/test/hexapdf/type/test_font_descriptor.rb +61 -0
- data/test/hexapdf/type/test_font_simple.rb +176 -0
- data/test/hexapdf/type/test_font_true_type.rb +31 -0
- data/test/hexapdf/type/test_font_type0.rb +120 -0
- data/test/hexapdf/type/test_font_type1.rb +142 -0
- data/test/hexapdf/type/test_font_type3.rb +26 -0
- data/test/hexapdf/type/test_form.rb +120 -0
- data/test/hexapdf/type/test_image.rb +261 -0
- data/test/hexapdf/type/test_info.rb +9 -0
- data/test/hexapdf/type/test_object_stream.rb +117 -0
- data/test/hexapdf/type/test_page.rb +598 -0
- data/test/hexapdf/type/test_page_tree_node.rb +315 -0
- data/test/hexapdf/type/test_resources.rb +209 -0
- data/test/hexapdf/type/test_trailer.rb +116 -0
- data/test/hexapdf/type/test_xref_stream.rb +143 -0
- data/test/hexapdf/utils/test_bit_field.rb +63 -0
- data/test/hexapdf/utils/test_bit_stream.rb +69 -0
- data/test/hexapdf/utils/test_graphics_helpers.rb +37 -0
- data/test/hexapdf/utils/test_lru_cache.rb +22 -0
- data/test/hexapdf/utils/test_object_hash.rb +120 -0
- data/test/hexapdf/utils/test_pdf_doc_encoding.rb +18 -0
- data/test/hexapdf/utils/test_sorted_tree_node.rb +239 -0
- data/test/test_helper.rb +58 -0
- metadata +263 -3
@@ -0,0 +1,163 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/content/processor'
|
5
|
+
require 'hexapdf/document'
|
6
|
+
|
7
|
+
describe HexaPDF::Content::Processor::GlyphBox do
|
8
|
+
before do
|
9
|
+
@box = HexaPDF::Content::Processor::GlyphBox.new(5, "5", 1, 2, 3, 4, 5, 6)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the correct bounding box coordinates" do
|
13
|
+
assert_equal([1, 2], @box.lower_left)
|
14
|
+
assert_equal([3, 4], @box.lower_right)
|
15
|
+
assert_equal([5, 6], @box.upper_left)
|
16
|
+
assert_equal([7, 8], @box.upper_right)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns all box corners in one array when using #points" do
|
20
|
+
assert_equal([1, 2, 3, 4, 7, 8, 5, 6], @box.points)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe HexaPDF::Content::Processor::CompositeBox do
|
25
|
+
before do
|
26
|
+
@glyph_box1 = HexaPDF::Content::Processor::GlyphBox.new(4, "4", 1, 1, 2, 1, 1, 2)
|
27
|
+
@glyph_box2 = HexaPDF::Content::Processor::GlyphBox.new(2, "2", 3, 1, 7, 1, 3, 2)
|
28
|
+
@boxes = HexaPDF::Content::Processor::CompositeBox.new
|
29
|
+
end
|
30
|
+
|
31
|
+
it "allows appending and retrieving of glyph boxes" do
|
32
|
+
result = (@boxes << @glyph_box1)
|
33
|
+
assert_equal(@boxes, result)
|
34
|
+
assert_equal(@glyph_box1, @boxes[0])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "allows iterating over the glyph boxes " do
|
38
|
+
@boxes << @glyph_box1 << @glyph_box2
|
39
|
+
assert_equal([@glyph_box1, @glyph_box2], @boxes.each.to_a)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns the concatenated string of the individual boxes" do
|
43
|
+
@boxes << @glyph_box1 << @glyph_box2
|
44
|
+
assert_equal("42", @boxes.string)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns the correct bounding box coordinates" do
|
48
|
+
@boxes << @glyph_box1 << @glyph_box2
|
49
|
+
assert_equal([1, 1], @boxes.lower_left)
|
50
|
+
assert_equal([7, 1], @boxes.lower_right)
|
51
|
+
assert_equal([1, 2], @boxes.upper_left)
|
52
|
+
assert_equal([7, 2], @boxes.upper_right)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe HexaPDF::Content::Processor do
|
57
|
+
before do
|
58
|
+
@processor = HexaPDF::Content::Processor.new
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "initialization" do
|
62
|
+
it "has a prepopulated operators mapping" do
|
63
|
+
assert_kind_of(HexaPDF::Content::Operator::BaseOperator, @processor.operators[:q])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "graphics_object" do
|
68
|
+
it "default to :none on initialization" do
|
69
|
+
assert_equal(:none, @processor.graphics_object)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "process" do
|
74
|
+
it "invokes the specified operator implementation" do
|
75
|
+
op = Minitest::Mock.new
|
76
|
+
op.expect(:invoke, nil, [@processor, :arg])
|
77
|
+
@processor.operators[:test] = op
|
78
|
+
@processor.process(:test, [:arg])
|
79
|
+
assert(op.verify)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "invokes the mapped message name" do
|
83
|
+
val = nil
|
84
|
+
@processor.define_singleton_method(:save_graphics_state) { val = :arg }
|
85
|
+
@processor.process(:q)
|
86
|
+
assert_equal(:arg, val)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "paint_xobject" do
|
91
|
+
it "processes the contents of a Form xobject" do
|
92
|
+
test_case = self
|
93
|
+
invoked = false
|
94
|
+
|
95
|
+
@processor.define_singleton_method(:set_line_width) do |_width|
|
96
|
+
test_case.assert_equal([2, 0, 0, 2, 10, 10], graphics_state.ctm.to_a)
|
97
|
+
invoked = true
|
98
|
+
end
|
99
|
+
@processor.resources = resources = Object.new
|
100
|
+
@processor.resources.define_singleton_method(:xobject) do |_name|
|
101
|
+
obj = {Matrix: [2, 0, 0, 2, 10, 10], Subtype: :Form}
|
102
|
+
obj.define_singleton_method(:process_contents) do |processor, original_resources:|
|
103
|
+
test_case.assert_same(resources, original_resources)
|
104
|
+
processor.process(:w, [10])
|
105
|
+
end
|
106
|
+
obj
|
107
|
+
end
|
108
|
+
|
109
|
+
@processor.process(:Do, [:Name])
|
110
|
+
assert(invoked)
|
111
|
+
assert_equal([1, 0, 0, 1, 0, 0], @processor.graphics_state.ctm.to_a)
|
112
|
+
assert_same(resources, @processor.resources)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "text decoding" do
|
117
|
+
before do
|
118
|
+
@doc = HexaPDF::Document.new
|
119
|
+
@processor.process(:BT)
|
120
|
+
@processor.graphics_state.font = @font = @doc.add({Type: :Font, Subtype: :Type1,
|
121
|
+
Encoding: :WinAnsiEncoding,
|
122
|
+
BaseFont: :"Times-Roman"})
|
123
|
+
@processor.graphics_state.font_size = 10
|
124
|
+
@processor.graphics_state.text_rise = 10
|
125
|
+
@processor.graphics_state.character_spacing = 1
|
126
|
+
@processor.graphics_state.word_spacing = 2
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "decode_text" do
|
130
|
+
it "decodes text provided via one or the other of the two show show text operators" do
|
131
|
+
assert_equal("Hülle", @processor.send(:decode_text, "Hülle".encode("Windows-1252")))
|
132
|
+
arr = ["Hül".encode("Windows-1252"), 20, "le".encode("Windows-1252")]
|
133
|
+
assert_equal("Hülle", @processor.send(:decode_text, arr))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "decode_text_with_positioning" do
|
138
|
+
it "returns a composite box with positioning information" do
|
139
|
+
lly = @font.bounding_box[1] / 1000.0 * @processor.graphics_state.font_size +
|
140
|
+
@processor.graphics_state.text_rise
|
141
|
+
lry = @font.bounding_box[3] / 1000.0 * @processor.graphics_state.font_size +
|
142
|
+
@processor.graphics_state.text_rise
|
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) }
|
145
|
+
width = (width - 20) * @processor.graphics_state.scaled_font_size +
|
146
|
+
6 * @processor.graphics_state.scaled_character_spacing +
|
147
|
+
@processor.graphics_state.scaled_word_spacing
|
148
|
+
|
149
|
+
box = @processor.send(:decode_text_with_positioning, arr)
|
150
|
+
assert_equal("Hül le", box.string)
|
151
|
+
assert_in_delta(0, box[0].lower_left[0])
|
152
|
+
assert_in_delta(lly, box[0].lower_left[1])
|
153
|
+
assert_in_delta(width, box[5].upper_right[0])
|
154
|
+
assert_in_delta(lry, box[5].upper_right[1])
|
155
|
+
end
|
156
|
+
|
157
|
+
it "fails if the current font is a vertical font" do
|
158
|
+
@processor.graphics_state.font.define_singleton_method(:writing_mode) { :vertical }
|
159
|
+
assert_raises(NotImplementedError) { @processor.send(:decode_text_with_positioning, "a") }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/content/transformation_matrix'
|
5
|
+
|
6
|
+
describe HexaPDF::Content::TransformationMatrix do
|
7
|
+
before do
|
8
|
+
@matrix = HexaPDF::Content::TransformationMatrix.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "initialize" do
|
12
|
+
it "initializes to the identity matrix" do
|
13
|
+
assert_equal(1, @matrix.a)
|
14
|
+
assert_equal(0, @matrix.b)
|
15
|
+
assert_equal(0, @matrix.c)
|
16
|
+
assert_equal(1, @matrix.d)
|
17
|
+
assert_equal(0, @matrix.e)
|
18
|
+
assert_equal(0, @matrix.f)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can use arbitrary values" do
|
22
|
+
@matrix = HexaPDF::Content::TransformationMatrix.new(2, 3, 4, 5, 6, 7)
|
23
|
+
assert_equal(2, @matrix.a)
|
24
|
+
assert_equal(3, @matrix.b)
|
25
|
+
assert_equal(4, @matrix.c)
|
26
|
+
assert_equal(5, @matrix.d)
|
27
|
+
assert_equal(6, @matrix.e)
|
28
|
+
assert_equal(7, @matrix.f)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "correctly evaluates a point" do
|
33
|
+
assert_equal([2, 3], @matrix.evaluate(2, 3))
|
34
|
+
end
|
35
|
+
|
36
|
+
it "correctly translates the matrix" do
|
37
|
+
@matrix.translate(5, 10)
|
38
|
+
assert_equal([7, 13], @matrix.evaluate(2, 3))
|
39
|
+
end
|
40
|
+
|
41
|
+
it "correctly rotates the matrix" do
|
42
|
+
@matrix.rotate(90)
|
43
|
+
assert_equal([-3, 2], @matrix.evaluate(2, 3))
|
44
|
+
end
|
45
|
+
|
46
|
+
it "correctly scales the matrix" do
|
47
|
+
@matrix.scale(5, 10)
|
48
|
+
assert_equal([10, 30], @matrix.evaluate(2, 3))
|
49
|
+
end
|
50
|
+
|
51
|
+
it "correctly skews the matrix" do
|
52
|
+
assert_equal([2, 5], @matrix.dup.skew(45, 0).evaluate(2, 3))
|
53
|
+
assert_equal([5, 3], @matrix.dup.skew(0, 45).evaluate(2, 3))
|
54
|
+
end
|
55
|
+
|
56
|
+
it "can be compared to another matrix" do
|
57
|
+
assert_equal(HexaPDF::Content::TransformationMatrix.new, @matrix)
|
58
|
+
refute_equal(HexaPDF::Content::TransformationMatrix.new(5), @matrix)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "allows the conversion of the matrix into an array" do
|
62
|
+
assert_equal([1, 0, 0, 1, 0, 0], @matrix.to_a)
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'tempfile'
|
6
|
+
require 'hexapdf/document'
|
7
|
+
|
8
|
+
describe HexaPDF::Document::Files do
|
9
|
+
before do
|
10
|
+
@doc = HexaPDF::Document.new
|
11
|
+
@data = "embed-test"
|
12
|
+
@file = Tempfile.new('file-embed-test')
|
13
|
+
@file.write(@data)
|
14
|
+
@file.close
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
@file.unlink
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "add" do
|
22
|
+
it "adds a file using a filename and embeds it" do
|
23
|
+
spec = @doc.files.add(@file.path)
|
24
|
+
assert_equal(File.basename(@file.path), spec.path)
|
25
|
+
assert_equal(@data, spec.embedded_file_stream.stream)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "adds a reference to a file" do
|
29
|
+
spec = @doc.files.add(@file.path, embed: false)
|
30
|
+
assert_equal(File.basename(@file.path), spec.path)
|
31
|
+
refute(spec.embedded_file?)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "adds a file using an IO" do
|
35
|
+
@file.open
|
36
|
+
spec = @doc.files.add(@file, name: 'test', embed: false)
|
37
|
+
assert_equal('test', spec.path)
|
38
|
+
assert_equal(@data, spec.embedded_file_stream.stream)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "optionally sets the description of the file" do
|
42
|
+
spec = @doc.files.add(@file.path, description: 'Some file')
|
43
|
+
assert_equal('Some file', spec[:Desc])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "requires the name argument when given an IO object" do
|
47
|
+
assert_raises(ArgumentError) { @doc.files.add(StringIO.new) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "each" do
|
52
|
+
it "iterates only over named embedded files and file annotations if search=false" do
|
53
|
+
@doc.add({Type: :Filespec})
|
54
|
+
spec1 = @doc.files.add(__FILE__)
|
55
|
+
spec2 = @doc.add({Type: :Filespec})
|
56
|
+
@doc.pages.add # page without annot
|
57
|
+
@doc.pages.add[:Annots] = [
|
58
|
+
{Subtype: :FileAttachment, FS: HexaPDF::Reference.new(spec1.oid, spec1.gen)},
|
59
|
+
{Subtype: :FileAttachment, FS: spec2},
|
60
|
+
{},
|
61
|
+
]
|
62
|
+
assert_equal([spec1, spec2], @doc.files.to_a)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "iterates over all file specifications of the document if search=true" do
|
66
|
+
specs = []
|
67
|
+
specs << @doc.add({Type: :Filespec})
|
68
|
+
specs << @doc.add({Type: :Filespec})
|
69
|
+
assert_equal(specs, @doc.files.each(search: true).to_a)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
|
6
|
+
describe HexaPDF::Document::Fonts do
|
7
|
+
before do
|
8
|
+
@doc = HexaPDF::Document.new
|
9
|
+
@doc.config['font_loader'] = []
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "add" do
|
13
|
+
before do
|
14
|
+
@doc.config['font_loader'] << lambda do |doc, name, **options|
|
15
|
+
assert_equal(@doc, doc)
|
16
|
+
if name == :TestFont
|
17
|
+
x = Object.new
|
18
|
+
x.define_singleton_method(:name) do
|
19
|
+
options[:variant] == :bold ? :BoldFont : :NormalFont
|
20
|
+
end
|
21
|
+
x
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "loads the specified font" do
|
29
|
+
assert_equal(:NormalFont, @doc.fonts.add(:TestFont).name)
|
30
|
+
assert_equal(:BoldFont, @doc.fonts.add(:TestFont, variant: :bold).name)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "caches loaded fonts" do
|
34
|
+
font = @doc.fonts.add(:TestFont)
|
35
|
+
assert_same(font, @doc.fonts.add(:TestFont))
|
36
|
+
assert_same(font, @doc.fonts.add(:TestFont, variant: :none))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "fails if the requested font is not found" do
|
40
|
+
@doc.config['font_loader'] << 'HexaPDF::FontLoader::Standard14'
|
41
|
+
error = assert_raises(HexaPDF::Error) { @doc.fonts.add("Unknown") }
|
42
|
+
assert_match(/Times \(none/, error.message)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises an error if a font loader cannot be correctly retrieved" do
|
46
|
+
@doc.config['font_loader'][0] = 'UnknownFontLoader'
|
47
|
+
assert_raises(HexaPDF::Error) { @doc.fonts.add(:Other) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns the configured fonts" do
|
52
|
+
@doc.config['font_loader'] << 'HexaPDF::FontLoader::Standard14'
|
53
|
+
@doc.config['font_loader'] << 'HexaPDF::FontLoader::FromConfiguration'
|
54
|
+
@doc.config['font.map'] = {'Times' => {heavy: 'none', none: 'none'}, 'Other' => {none: 'none'}}
|
55
|
+
fonts = @doc.fonts.configured_fonts
|
56
|
+
assert_equal([:none], fonts['Symbol'])
|
57
|
+
assert_equal([:none, :bold, :italic, :bold_italic, :heavy], fonts['Times'])
|
58
|
+
assert_equal([:none], fonts['Other'])
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/document'
|
6
|
+
|
7
|
+
describe HexaPDF::Document::Images do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "add" do
|
13
|
+
describe "using a custom image loader" do
|
14
|
+
before do
|
15
|
+
@loader = Object.new
|
16
|
+
@loader.define_singleton_method(:handles?) {|*| true }
|
17
|
+
@loader.define_singleton_method(:load) do |doc, s|
|
18
|
+
s = HexaPDF::StreamData.new(s) if s.kind_of?(IO)
|
19
|
+
doc.add({Type: :XObject, Subtype: :Image}, stream: s)
|
20
|
+
end
|
21
|
+
@doc.config['image_loader'].unshift(@loader)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "adds an image using a filename" do
|
25
|
+
data = 'test'
|
26
|
+
image = @doc.images.add(data)
|
27
|
+
assert_equal(data, image.stream)
|
28
|
+
assert_equal(File.absolute_path(data), image.source_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "adds an image using an IO" do
|
32
|
+
File.open(__FILE__, 'rb') do |file|
|
33
|
+
image = @doc.images.add(file)
|
34
|
+
assert_equal(File.read(__FILE__), image.stream)
|
35
|
+
assert_equal(File.absolute_path(__FILE__), image.source_path)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "doesn't add an image twice" do
|
40
|
+
data = 'test'
|
41
|
+
image = @doc.images.add(data)
|
42
|
+
image1 = @doc.images.add(data)
|
43
|
+
assert_same(image, image1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "fails if the needed image loader can't be resolved" do
|
48
|
+
@doc.config['image_loader'].unshift('SomeUnknownConstantHere')
|
49
|
+
exp = assert_raises(HexaPDF::Error) { @doc.images.add(StringIO.new('test')) }
|
50
|
+
assert_match(/image loader from configuration/, exp.message)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "fails if no image loader is found" do
|
54
|
+
exp = assert_raises(HexaPDF::Error) { @doc.images.add(StringIO.new('test')) }
|
55
|
+
assert_match(/suitable image loader/, exp.message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "each" do
|
60
|
+
it "iterates over all non-mask images" do
|
61
|
+
@doc.add(5)
|
62
|
+
images = []
|
63
|
+
images << @doc.add({Type: :XObject, Subtype: :Image})
|
64
|
+
images << @doc.add({Type: :XObject, Subtype: :Image, Mask: [5, 6]})
|
65
|
+
images << @doc.add({Type: :XObject, Subtype: :Image,
|
66
|
+
Mask: @doc.add({Type: :XObject, Subtype: :Image})})
|
67
|
+
images << @doc.add({Type: :XObject, Subtype: :Image,
|
68
|
+
SMask: @doc.add({Type: :XObject, Subtype: :Image})})
|
69
|
+
assert_equal(images.sort, @doc.images.to_a.sort)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
|
6
|
+
describe HexaPDF::Document::Pages do
|
7
|
+
before do
|
8
|
+
@doc = HexaPDF::Document.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "root" do
|
12
|
+
it "returns the root of the page tree" do
|
13
|
+
assert_same(@doc.catalog.pages, @doc.pages.root)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "add" do
|
18
|
+
it "adds a new empty page when no page is given" do
|
19
|
+
page = @doc.pages.add
|
20
|
+
assert_equal([page], @doc.pages.root[:Kids].value)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "adds a new empty page with the given dimensions" do
|
24
|
+
page = @doc.pages.add([0, 0, 20, 20])
|
25
|
+
assert_same(page, @doc.pages[0])
|
26
|
+
assert_equal([0, 0, 20, 20], @doc.pages[0].box(:media).value)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "adds a new empty page with the given page format" do
|
30
|
+
page = @doc.pages.add(:A4, orientation: :landscape)
|
31
|
+
assert_same(page, @doc.pages[0])
|
32
|
+
assert_equal([0, 0, 842, 595], @doc.pages[0].box(:media).value)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "adds the given page to the end" do
|
36
|
+
page = @doc.pages.add
|
37
|
+
new_page = @doc.add({Type: :Page})
|
38
|
+
assert_same(new_page, @doc.pages.add(new_page))
|
39
|
+
assert_equal([page, new_page], @doc.pages.root[:Kids].value)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "fails if an unknown page format is given" do
|
43
|
+
assert_raises(HexaPDF::Error) { @doc.pages.add(:A953) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "<<" do
|
48
|
+
it "works like add but always needs a page returns self" do
|
49
|
+
page1 = @doc.add({Type: :Page})
|
50
|
+
page2 = @doc.add({Type: :Page})
|
51
|
+
@doc.pages << page1 << page2
|
52
|
+
assert_equal([page1, page2], @doc.pages.root[:Kids].value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "insert" do
|
57
|
+
before do
|
58
|
+
@doc.pages.add
|
59
|
+
@doc.pages.add
|
60
|
+
@doc.pages.add
|
61
|
+
end
|
62
|
+
|
63
|
+
it "insert a new page at a given index" do
|
64
|
+
page = @doc.pages.insert(2)
|
65
|
+
assert_equal(page, @doc.pages.root[:Kids][2])
|
66
|
+
end
|
67
|
+
|
68
|
+
it "insert a given page at a given index" do
|
69
|
+
new_page = @doc.add({Type: :Page})
|
70
|
+
assert_same(new_page, @doc.pages.insert(2, new_page))
|
71
|
+
assert_equal(new_page, @doc.pages.root[:Kids][2])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "delete" do
|
76
|
+
it "deletes a given page" do
|
77
|
+
page1 = @doc.pages.add
|
78
|
+
page2 = @doc.pages.add
|
79
|
+
|
80
|
+
@doc.pages.delete(page1)
|
81
|
+
assert_equal([page2], @doc.pages.root[:Kids].value)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "delete_at" do
|
86
|
+
it "deletes a page at a given index" do
|
87
|
+
page1 = @doc.pages.add
|
88
|
+
@doc.pages.add
|
89
|
+
page3 = @doc.pages.add
|
90
|
+
@doc.pages.delete_at(1)
|
91
|
+
assert_equal([page1, page3], @doc.pages.root[:Kids].value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "[]" do
|
96
|
+
it "returns the page at the given index" do
|
97
|
+
page1 = @doc.pages.add
|
98
|
+
page2 = @doc.pages.add
|
99
|
+
page3 = @doc.pages.add
|
100
|
+
|
101
|
+
assert_equal(page1, @doc.pages[0])
|
102
|
+
assert_equal(page2, @doc.pages[1])
|
103
|
+
assert_equal(page3, @doc.pages[2])
|
104
|
+
assert_nil(@doc.pages[3])
|
105
|
+
assert_equal(page3, @doc.pages[-1])
|
106
|
+
assert_equal(page2, @doc.pages[-2])
|
107
|
+
assert_equal(page1, @doc.pages[-3])
|
108
|
+
assert_nil(@doc.pages[-4])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "each" do
|
113
|
+
it "iterates over all pages" do
|
114
|
+
page1 = @doc.pages.add
|
115
|
+
page2 = @doc.pages.add
|
116
|
+
page3 = @doc.pages.add
|
117
|
+
assert_equal([page1, page2, page3], @doc.pages.to_a)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "count" do
|
122
|
+
it "returns the number of pages in the page tree" do
|
123
|
+
assert_equal(0, @doc.pages.count)
|
124
|
+
@doc.pages.add
|
125
|
+
@doc.pages.add
|
126
|
+
@doc.pages.add
|
127
|
+
assert_equal(3, @doc.pages.count)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# Contains tests that validate that an encryption algorithm's class conforms to the general
|
6
|
+
# interface.
|
7
|
+
#
|
8
|
+
# The algorithm class needs to be available in the @algorithm_class variable.
|
9
|
+
module EncryptionAlgorithmInterfaceTests
|
10
|
+
|
11
|
+
def test_responds_to_necessary_methods
|
12
|
+
[:encrypt, :decrypt, :encryption_fiber, :decryption_fiber].each do |method|
|
13
|
+
assert_respond_to(@algorithm_class, method)
|
14
|
+
assert_equal(2, @algorithm_class.method(method).arity)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
# Contains common tests for AES algorithms.
|
21
|
+
#
|
22
|
+
# The algorithm class needs to be available in the @algorithm_class variable.
|
23
|
+
module AESEncryptionTests
|
24
|
+
|
25
|
+
include EncryptionAlgorithmInterfaceTests
|
26
|
+
|
27
|
+
TEST_VECTOR_FILES = Dir[File.join(TEST_DATA_DIR, 'aes-test-vectors', '*')]
|
28
|
+
|
29
|
+
def test_processes_the_aes_test_vectors
|
30
|
+
TEST_VECTOR_FILES.each do |filename|
|
31
|
+
name, size, mode = File.basename(filename, '.data.gz').split('-')
|
32
|
+
size = size.to_i / 8
|
33
|
+
data = Zlib::GzipReader.open(filename, &:read).force_encoding(Encoding::BINARY)
|
34
|
+
data.scan(/(.{#{size}})(.{16})(.{16})(.{16})/m).each_with_index do |(key, iv, plain, cipher), index|
|
35
|
+
aes = @algorithm_class.new(key, iv, mode.intern)
|
36
|
+
assert_equal(cipher, aes.process(plain),
|
37
|
+
"name: #{name}, size: #{size * 8}, mode: #{mode}, index: #{index}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_can_accept_one_big_chunk_or_multiple_smaller_ones
|
43
|
+
big = @algorithm_class.new('t' * 16, '0' * 16, :encrypt)
|
44
|
+
small = @algorithm_class.new('t' * 16, '0' * 16, :encrypt)
|
45
|
+
assert_equal(big.process('some' * 16),
|
46
|
+
small.process('some' * 8) << small.process('some' * 4) << small.process('some' * 4))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_raises_error_on_invalid_key_length
|
50
|
+
assert_raises(HexaPDF::EncryptionError) { @algorithm_class.new('t' * 7, '0' * 16, :encrypt) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_raises_error_on_invalid_iv_length
|
54
|
+
assert_raises(HexaPDF::EncryptionError) { @algorithm_class.new('t' * 16, '0' * 7, :encrypt) }
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# Contains common tests for AES algorithms.
|
60
|
+
#
|
61
|
+
# The algorithm class needs to be available in the @algorithm_class variable.
|
62
|
+
module ARC4EncryptionTests
|
63
|
+
|
64
|
+
include EncryptionAlgorithmInterfaceTests
|
65
|
+
|
66
|
+
def setup
|
67
|
+
super
|
68
|
+
@encrypted = ['BBF316E8D940AF0AD3', '1021BF0420', '45A01F645FC35B383552544B9BF5'].
|
69
|
+
map {|c| [c].pack('H*') }
|
70
|
+
@plain = ['Plaintext', 'pedia', 'Attack at dawn'].each {|s| s.force_encoding('BINARY') }
|
71
|
+
@keys = ['Key', 'Wiki', 'Secret']
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_processes_the_test_vectors_from_the_rc4_wikipeda_page
|
75
|
+
@keys.each_with_index do |key, i|
|
76
|
+
assert_equal(@encrypted[i], @algorithm_class.new(key).process(@plain[i]))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_can_accept_one_big_chunk_or_multiple_smaller_ones
|
81
|
+
big = @algorithm_class.new('key')
|
82
|
+
small = @algorithm_class.new('key')
|
83
|
+
assert_equal(big.process('some big data chunk'),
|
84
|
+
small.process('some') << small.process(' big') << small.process(' data chunk'))
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|