hexapdf 0.20.2 → 0.20.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84eb73cfede7538e77c381d6c9b3119e77f620d6aab119ec32c667e4179b78c1
4
- data.tar.gz: ff8107702d942c278a42812fe10e6a82ad4d96d109af607a1c6ec3e2fc72421c
3
+ metadata.gz: edc0879019c00378efa5e596e5a24db8d094e8baf682f434c052e62f6a84a563
4
+ data.tar.gz: 9eb7a38c31ae34d9bdf2d4006a01419b29d0c21faabd9b6b2ff31a3079c4617f
5
5
  SHA512:
6
- metadata.gz: 981b590a35b0a2fdc37b883f6294efb6a2b6fe58bb4ada80a1ea6805b14f600c44c5e1d19b6eb74c8969291136bcdb5102ea363b1ba923e61d79d149a91401e0
7
- data.tar.gz: b802c3ecde178abdc7a438b56fada5cb45fe5f951960c71fc2a12aac9d7679f834d4105c211b3b12cc8e2b251c89748b9b249e11fc8d7bbcc3d8792983b89989
6
+ metadata.gz: 259aa6bcd520b74bec173c91d92b660681d09f0543287783aacc216fbf633c754e3d05dbcd56e84bff3227551e074193bbcf9d2d79d9435dad33dff6d85f89bf
7
+ data.tar.gz: 91ba8e27297a9c0769b19531e219987b749e8d356911bd03f22e579dff66cb90788efe1db8a56eb10ee4405eca39469022bafe6aebf597be4faf2285a908d1d5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 0.20.3 - 2022-01-24
2
+
3
+ ### Changed
4
+
5
+ * Appearance of signature field values when using the `hexapdf form` command
6
+
7
+ ### Fixed
8
+
9
+ * Writing of encrypted PDF files in incremental node in case the encryption was
10
+ changed
11
+ * [HexaPDF::Type::Annotation#appearance] to return correctly wrapped object in
12
+ case of Form XObjects missing required data
13
+ * Decrypting of files with multiple revisions
14
+
15
+
1
16
  ## 0.20.2 - 2022-01-17
2
17
 
3
18
  ### Fixed
@@ -135,12 +135,20 @@ module HexaPDF
135
135
  concrete_field_type = field.concrete_field_type
136
136
  nice_field_type = concrete_field_type.to_s.split('_').map(&:capitalize).join(' ')
137
137
  position = "(#{widget[:Rect].left}, #{widget[:Rect].bottom})"
138
+ field_value = if !field.field_value || concrete_field_type != :signature_field
139
+ field.field_value.inspect
140
+ else
141
+ sig = field.field_value
142
+ temp = "#{sig.signer_name} (#{sig.signing_time})"
143
+ temp << " (#{sig.signing_reason})" if sig.signing_reason
144
+ temp
145
+ end
138
146
 
139
147
  puts " #{field_name}"
140
148
  if command_parser.verbosity_info?
141
149
  printf(" └─ %-22s | %-20s\n", nice_field_type, position)
142
150
  end
143
- puts " └─ #{field.field_value.inspect}"
151
+ puts " └─ #{field_value}"
144
152
  if command_parser.verbosity_info?
145
153
  if field.field_type == :Ch
146
154
  puts " └─ Options: #{field.option_items.map(&:inspect).join(', ')}"
@@ -249,6 +249,10 @@ module HexaPDF
249
249
  @document = document
250
250
  @encrypt_dict_hash = nil
251
251
  @encryption_details = {}
252
+
253
+ @is_encrypt_dict = document.revisions.each.with_object({}) do |rev, hash|
254
+ hash[rev.trailer[:Encrypt]] = true
255
+ end
252
256
  end
253
257
 
254
258
  # Checks if the encryption key computed by this security handler is derived from the
@@ -262,7 +266,7 @@ module HexaPDF
262
266
  #
263
267
  # See: PDF1.7 s7.6.2
264
268
  def decrypt(obj)
265
- return obj if obj == document.trailer[:Encrypt] || obj.type == :XRef
269
+ return obj if @is_encrypt_dict[obj] || obj.type == :XRef
266
270
 
267
271
  key = object_key(obj.oid, obj.gen, string_algorithm)
268
272
  each_string_in_object(obj.value) do |str|
@@ -160,7 +160,7 @@ module HexaPDF
160
160
  end
161
161
  return unless entry.kind_of?(HexaPDF::Stream)
162
162
 
163
- if entry.type == :XObject && entry[:Subtype] == :Form
163
+ if entry.type == :XObject && entry[:Subtype] == :Form && !entry.instance_of?(HexaPDF::Stream)
164
164
  entry
165
165
  elsif (entry[:Type].nil? || entry[:Type] == :XObject) &&
166
166
  (entry[:Subtype].nil? || entry[:Subtype] == :Form) && entry[:BBox]
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.20.2'
40
+ VERSION = '0.20.3'
41
41
 
42
42
  end
@@ -90,12 +90,20 @@ module HexaPDF
90
90
  #
91
91
  # For this method to work the document must have been created from an existing file.
92
92
  def write_incremental
93
- @document.revisions.parser.io.seek(0, IO::SEEK_SET)
94
- IO.copy_stream(@document.revisions.parser.io, @io)
93
+ parser = @document.revisions.parser
94
+
95
+ _, orig_trailer = parser.load_revision(parser.startxref_offset)
96
+ orig_trailer = @document.wrap(orig_trailer, type: :XXTrailer)
97
+ if @document.revisions.current.trailer[:Encrypt]&.value != orig_trailer[:Encrypt]&.value
98
+ raise HexaPDF::Error, "Used encryption cannot be modified when doing incremental writing"
99
+ end
100
+
101
+ parser.io.seek(0, IO::SEEK_SET)
102
+ IO.copy_stream(parser.io, @io)
95
103
  @io << "\n"
96
104
 
97
105
  @rev_size = @document.revisions.current.next_free_oid
98
- @use_xref_streams = @document.revisions.parser.contains_xref_streams?
106
+ @use_xref_streams = parser.contains_xref_streams?
99
107
 
100
108
  revision = Revision.new(@document.revisions.current.trailer)
101
109
  @document.revisions.each do |rev|
@@ -294,9 +294,17 @@ describe HexaPDF::Encryption::SecurityHandler do
294
294
  assert_equal('string', obj.stream)
295
295
  end
296
296
 
297
- it "doesn't decrypt a document's Encrypt dictionary" do
298
- @document.trailer[:Encrypt] = @obj
299
- assert_equal(@encrypted, @handler.decrypt(@obj)[:Key])
297
+ it "doesn't decrypt a document's Encrypt dictionaries" do
298
+ @document = HexaPDF::Document.new
299
+ @document.trailer[:Encrypt] = @document.add({Key: "Something"})
300
+ @document.revisions.add
301
+ @document.trailer[:Encrypt] = @document.add({Key: "Otherthing"})
302
+ @handler = TestHandler.new(@document)
303
+
304
+ assert_equal("Something",
305
+ @handler.decrypt(@document.revisions[0].trailer[:Encrypt])[:Key])
306
+ assert_equal("Otherthing",
307
+ @handler.decrypt(@document.revisions[1].trailer[:Encrypt])[:Key])
300
308
  end
301
309
 
302
310
  it "defers handling encryption to a Crypt filter is specified" do
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.20.2)>>
43
+ <</Producer(HexaPDF version 0.20.3)>>
44
44
  endobj
45
45
  xref
46
46
  3 1
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
72
72
  141
73
73
  %%EOF
74
74
  6 0 obj
75
- <</Producer(HexaPDF version 0.20.2)>>
75
+ <</Producer(HexaPDF version 0.20.3)>>
76
76
  endobj
77
77
  2 0 obj
78
78
  <</Length 10>>stream
@@ -123,6 +123,17 @@ describe HexaPDF::Writer do
123
123
  HexaPDF::Writer.write(doc, output_io, incremental: true)
124
124
  refute_match(/^trailer/, output_io.string)
125
125
  end
126
+
127
+ it "raises an error if the used encryption was changed" do
128
+ io = StringIO.new
129
+ doc = HexaPDF::Document.new
130
+ doc.encrypt
131
+ doc.write(io)
132
+
133
+ doc = HexaPDF::Document.new(io: io)
134
+ doc.encrypt(owner_password: 'test')
135
+ assert_raises(HexaPDF::Error) { doc.write('notused', incremental: true) }
136
+ end
126
137
  end
127
138
 
128
139
  it "creates an xref stream if no xref stream is in a revision but object streams are" do
@@ -77,7 +77,13 @@ describe HexaPDF::Type::Annotation do
77
77
  stream[:BBox] = [1, 2, 3, 4]
78
78
  appearance = @annot.appearance
79
79
  assert_same(stream.data, appearance.data)
80
- assert_equal(:Form, appearance[:Subtype])
80
+ assert_kind_of(HexaPDF::Type::Form, appearance)
81
+
82
+ stream[:Type] = :XObject
83
+ stream[:Subtype] = :Form
84
+ appearance = @annot.appearance
85
+ assert_same(stream.data, appearance.data)
86
+ assert_kind_of(HexaPDF::Type::Form, appearance)
81
87
 
82
88
  @annot[:AP][:N] = {X: {}}
83
89
  assert_nil(@annot.appearance)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.2
4
+ version: 0.20.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-17 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse