diff --git a/lib/pdf/reader.rb b/lib/pdf/reader.rb index 5d0ff8cf..a31e3f3b 100644 --- a/lib/pdf/reader.rb +++ b/lib/pdf/reader.rb @@ -277,6 +277,7 @@ def root require 'pdf/reader/register_receiver' require 'pdf/reader/null_security_handler' require 'pdf/reader/standard_security_handler' +require 'pdf/reader/unimplemented_security_handler' require 'pdf/reader/stream' require 'pdf/reader/text_run' require 'pdf/reader/page_state' diff --git a/lib/pdf/reader/null_security_handler.rb b/lib/pdf/reader/null_security_handler.rb index d8d780e6..88e311fc 100644 --- a/lib/pdf/reader/null_security_handler.rb +++ b/lib/pdf/reader/null_security_handler.rb @@ -2,10 +2,10 @@ class PDF::Reader - # A null object security handler. Used when we don't support the encryption type in a file. + # A null object security handler. Used when a PDF is unencrypted. class NullSecurityHandler - def decrypt(buf, ref) - raise PDF::Reader::EncryptedPDFError, "Unsupported encryption style" + def decrypt(buf, _ref) + buf end end end diff --git a/lib/pdf/reader/object_hash.rb b/lib/pdf/reader/object_hash.rb index 355177ed..4ae9d23e 100644 --- a/lib/pdf/reader/object_hash.rb +++ b/lib/pdf/reader/object_hash.rb @@ -45,6 +45,7 @@ def initialize(input, opts = {}) @pdf_version = read_version @trailer = @xref.trailer @cache = opts[:cache] || PDF::Reader::ObjectCache.new + @sec_handler = NullSecurityHandler.new @sec_handler = build_security_handler(opts) end @@ -286,15 +287,15 @@ def deref_internal!(key, seen) end def build_security_handler(opts = {}) - return nil if trailer[:Encrypt].nil? + return NullSecurityHandler.new if trailer[:Encrypt].nil? enc = deref(trailer[:Encrypt]) filter = enc.fetch(:Filter, :Standard) version = enc.fetch(:V, 0) if filter == :Standard && version >= 5 - NullSecurityHandler.new + UnimplementedSecurityHandler.new elsif filter == :Standard && version >= 4 && enc.fetch(:CF, {}).fetch(enc[:StmF], {}).fetch(:CFM, nil) == :AESV2 - NullSecurityHandler.new + UnimplementedSecurityHandler.new elsif filter == :Standard encmeta = enc.has_key?(:EncryptMetadata)? enc[:EncryptMetadata].to_s == "true" : true @@ -309,13 +310,11 @@ def build_security_handler(opts = {}) password: opts[:password] ) else - raise PDF::Reader::EncryptedPDFError, "Unsupported encryption method (#{enc[:Filter]})" + UnimplementedSecurityHandler.new end end def decrypt(ref, obj) - return obj unless sec_handler? - case obj when PDF::Reader::Stream then obj.data = sec_handler.decrypt(obj.data, ref) diff --git a/lib/pdf/reader/unimplemented_security_handler.rb b/lib/pdf/reader/unimplemented_security_handler.rb new file mode 100644 index 00000000..9294b77e --- /dev/null +++ b/lib/pdf/reader/unimplemented_security_handler.rb @@ -0,0 +1,12 @@ +# coding: utf-8 + +class PDF::Reader + + # Security handler for when we don't support the flavour of encryption + # used in a PDF. + class UnimplementedSecurityHandler + def decrypt(buf, ref) + raise PDF::Reader::EncryptedPDFError, "Unsupported encryption style" + end + end +end