hexapdf 0.20.2 → 0.20.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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