pdf-reader 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +5 -0
  3. data/lib/pdf/reader/aes_v2_security_handler.rb +41 -0
  4. data/lib/pdf/reader/aes_v3_security_handler.rb +38 -0
  5. data/lib/pdf/reader/buffer.rb +36 -34
  6. data/lib/pdf/reader/cmap.rb +64 -51
  7. data/lib/pdf/reader/error.rb +8 -0
  8. data/lib/pdf/reader/filter/ascii85.rb +1 -1
  9. data/lib/pdf/reader/filter/ascii_hex.rb +1 -1
  10. data/lib/pdf/reader/filter/depredict.rb +1 -1
  11. data/lib/pdf/reader/filter/flate.rb +3 -3
  12. data/lib/pdf/reader/filter/lzw.rb +1 -1
  13. data/lib/pdf/reader/filter/null.rb +1 -2
  14. data/lib/pdf/reader/filter/run_length.rb +1 -1
  15. data/lib/pdf/reader/filter.rb +1 -1
  16. data/lib/pdf/reader/font.rb +29 -17
  17. data/lib/pdf/reader/font_descriptor.rb +18 -17
  18. data/lib/pdf/reader/form_xobject.rb +14 -5
  19. data/lib/pdf/reader/key_builder_v5.rb +138 -0
  20. data/lib/pdf/reader/null_security_handler.rb +0 -4
  21. data/lib/pdf/reader/object_hash.rb +247 -42
  22. data/lib/pdf/reader/page.rb +38 -20
  23. data/lib/pdf/reader/page_state.rb +1 -1
  24. data/lib/pdf/reader/page_text_receiver.rb +4 -1
  25. data/lib/pdf/reader/parser.rb +9 -6
  26. data/lib/pdf/reader/point.rb +1 -1
  27. data/lib/pdf/reader/rc4_security_handler.rb +38 -0
  28. data/lib/pdf/reader/rectangle.rb +2 -2
  29. data/lib/pdf/reader/{resource_methods.rb → resources.rb} +15 -13
  30. data/lib/pdf/reader/security_handler_factory.rb +79 -0
  31. data/lib/pdf/reader/{standard_security_handler.rb → standard_key_builder.rb} +23 -95
  32. data/lib/pdf/reader/stream.rb +2 -2
  33. data/lib/pdf/reader/type_check.rb +52 -0
  34. data/lib/pdf/reader/validating_receiver.rb +262 -0
  35. data/lib/pdf/reader/width_calculator/true_type.rb +1 -1
  36. data/lib/pdf/reader/xref.rb +20 -3
  37. data/lib/pdf/reader.rb +17 -9
  38. data/rbi/pdf-reader.rbi +388 -173
  39. metadata +15 -9
  40. data/lib/pdf/reader/standard_security_handler_v5.rb +0 -92
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdf-reader
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Healy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-28 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: rake
@@ -200,6 +200,8 @@ files:
200
200
  - examples/version.rb
201
201
  - lib/pdf-reader.rb
202
202
  - lib/pdf/reader.rb
203
+ - lib/pdf/reader/aes_v2_security_handler.rb
204
+ - lib/pdf/reader/aes_v3_security_handler.rb
203
205
  - lib/pdf/reader/afm/Courier-Bold.afm
204
206
  - lib/pdf/reader/afm/Courier-BoldOblique.afm
205
207
  - lib/pdf/reader/afm/Courier-Oblique.afm
@@ -242,6 +244,7 @@ files:
242
244
  - lib/pdf/reader/glyph_hash.rb
243
245
  - lib/pdf/reader/glyphlist-zapfdingbats.txt
244
246
  - lib/pdf/reader/glyphlist.txt
247
+ - lib/pdf/reader/key_builder_v5.rb
245
248
  - lib/pdf/reader/lzw.rb
246
249
  - lib/pdf/reader/null_security_handler.rb
247
250
  - lib/pdf/reader/object_cache.rb
@@ -256,18 +259,21 @@ files:
256
259
  - lib/pdf/reader/parser.rb
257
260
  - lib/pdf/reader/point.rb
258
261
  - lib/pdf/reader/print_receiver.rb
262
+ - lib/pdf/reader/rc4_security_handler.rb
259
263
  - lib/pdf/reader/rectangle.rb
260
264
  - lib/pdf/reader/reference.rb
261
265
  - lib/pdf/reader/register_receiver.rb
262
- - lib/pdf/reader/resource_methods.rb
263
- - lib/pdf/reader/standard_security_handler.rb
264
- - lib/pdf/reader/standard_security_handler_v5.rb
266
+ - lib/pdf/reader/resources.rb
267
+ - lib/pdf/reader/security_handler_factory.rb
268
+ - lib/pdf/reader/standard_key_builder.rb
265
269
  - lib/pdf/reader/stream.rb
266
270
  - lib/pdf/reader/synchronized_cache.rb
267
271
  - lib/pdf/reader/text_run.rb
268
272
  - lib/pdf/reader/token.rb
269
273
  - lib/pdf/reader/transformation_matrix.rb
274
+ - lib/pdf/reader/type_check.rb
270
275
  - lib/pdf/reader/unimplemented_security_handler.rb
276
+ - lib/pdf/reader/validating_receiver.rb
271
277
  - lib/pdf/reader/width_calculator.rb
272
278
  - lib/pdf/reader/width_calculator/built_in.rb
273
279
  - lib/pdf/reader/width_calculator/composite.rb
@@ -282,9 +288,9 @@ licenses:
282
288
  - MIT
283
289
  metadata:
284
290
  bug_tracker_uri: https://github.com/yob/pdf-reader/issues
285
- changelog_uri: https://github.com/yob/pdf-reader/blob/v2.8.0/CHANGELOG
286
- documentation_uri: https://www.rubydoc.info/gems/pdf-reader/2.8.0
287
- source_code_uri: https://github.com/yob/pdf-reader/tree/v2.8.0
291
+ changelog_uri: https://github.com/yob/pdf-reader/blob/v2.9.0/CHANGELOG
292
+ documentation_uri: https://www.rubydoc.info/gems/pdf-reader/2.9.0
293
+ source_code_uri: https://github.com/yob/pdf-reader/tree/v2.9.0
288
294
  post_install_message:
289
295
  rdoc_options:
290
296
  - "--title"
@@ -305,7 +311,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
305
311
  - !ruby/object:Gem::Version
306
312
  version: '0'
307
313
  requirements: []
308
- rubygems_version: 3.2.3
314
+ rubygems_version: 3.1.6
309
315
  signing_key:
310
316
  specification_version: 4
311
317
  summary: A library for accessing the content of PDF files
@@ -1,92 +0,0 @@
1
- # coding: utf-8
2
- # typed: true
3
- # frozen_string_literal: true
4
-
5
- require 'digest'
6
- require 'openssl'
7
-
8
- class PDF::Reader
9
-
10
- # class creates interface to encrypt dictionary for use in Decrypt
11
- class StandardSecurityHandlerV5
12
-
13
- attr_reader :key_length, :encrypt_key
14
-
15
- def initialize(opts = {})
16
- @key_length = 256
17
- @O = opts[:O] # hash(32B) + validation salt(8B) + key salt(8B)
18
- @U = opts[:U] # hash(32B) + validation salt(8B) + key salt(8B)
19
- @OE = opts[:OE] # decryption key, encrypted w/ owner password
20
- @UE = opts[:UE] # decryption key, encrypted w/ user password
21
- @encrypt_key = build_standard_key(opts[:password] || '')
22
- end
23
-
24
- # This handler supports AES-256 encryption defined in PDF 1.7 Extension Level 3
25
- def self.supports?(encrypt)
26
- return false if encrypt.nil?
27
-
28
- filter = encrypt.fetch(:Filter, :Standard)
29
- version = encrypt.fetch(:V, 0)
30
- revision = encrypt.fetch(:R, 0)
31
- algorithm = encrypt.fetch(:CF, {}).fetch(encrypt[:StmF], {}).fetch(:CFM, nil)
32
- (filter == :Standard) && (encrypt[:StmF] == encrypt[:StrF]) &&
33
- ((version == 5) && (revision == 5) && (algorithm == :AESV3))
34
- end
35
-
36
- ##7.6.2 General Encryption Algorithm
37
- #
38
- # Algorithm 1: Encryption of data using the RC4 or AES algorithms
39
- #
40
- # used to decrypt RC4/AES encrypted PDF streams (buf)
41
- #
42
- # buf - a string to decrypt
43
- # ref - a PDF::Reader::Reference for the object to decrypt
44
- #
45
- def decrypt( buf, ref )
46
- cipher = OpenSSL::Cipher.new("AES-#{@key_length}-CBC")
47
- cipher.decrypt
48
- cipher.key = @encrypt_key.dup
49
- cipher.iv = buf[0..15]
50
- cipher.update(buf[16..-1]) + cipher.final
51
- end
52
-
53
- private
54
- # Algorithm 3.2a - Computing an encryption key
55
- #
56
- # Defined in PDF 1.7 Extension Level 3
57
- #
58
- # if the string is a valid user/owner password, this will return the decryption key
59
- #
60
- def auth_owner_pass(password)
61
- if Digest::SHA256.digest(password + @O[32..39] + @U) == @O[0..31]
62
- cipher = OpenSSL::Cipher.new('AES-256-CBC')
63
- cipher.decrypt
64
- cipher.key = Digest::SHA256.digest(password + @O[40..-1] + @U)
65
- cipher.iv = "\x00" * 16
66
- cipher.padding = 0
67
- cipher.update(@OE) + cipher.final
68
- end
69
- end
70
-
71
- def auth_user_pass(password)
72
- if Digest::SHA256.digest(password + @U[32..39]) == @U[0..31]
73
- cipher = OpenSSL::Cipher.new('AES-256-CBC')
74
- cipher.decrypt
75
- cipher.key = Digest::SHA256.digest(password + @U[40..-1])
76
- cipher.iv = "\x00" * 16
77
- cipher.padding = 0
78
- cipher.update(@UE) + cipher.final
79
- end
80
- end
81
-
82
- def build_standard_key(pass)
83
- pass = pass.byteslice(0...127) # UTF-8 encoded password. first 127 bytes
84
-
85
- encrypt_key = auth_owner_pass(pass)
86
- encrypt_key ||= auth_user_pass(pass)
87
-
88
- raise PDF::Reader::EncryptedPDFError, "Invalid password (#{pass})" if encrypt_key.nil?
89
- encrypt_key
90
- end
91
- end
92
- end