diff --git a/lib/pdf/reader/object_hash.rb b/lib/pdf/reader/object_hash.rb index e08c4879..652a650a 100644 --- a/lib/pdf/reader/object_hash.rb +++ b/lib/pdf/reader/object_hash.rb @@ -81,7 +81,7 @@ def [](key) @cache[key] elsif xref[key].is_a?(Integer) buf = new_buffer(xref[key]) - @cache[key] = decrypt(key, Parser.new(buf, self).object(key.id, key.gen)) + @cache[key] = decrypt(key, Parser.new(buf, self).object(key.id, key.gen), {}) elsif xref[key].is_a?(PDF::Reader::Reference) container_key = xref[key] object_streams[container_key] ||= PDF::Reader::ObjectStream.new(object(container_key)) @@ -308,16 +308,27 @@ def build_security_handler(opts = {}) end end - def decrypt(ref, obj) + def decrypt(ref, obj, seen) + seen_key = obj.object_id + + return seen[seen_key] if seen.key?(seen_key) + case obj when PDF::Reader::Stream then obj.data = sec_handler.decrypt(obj.data, ref) obj when Hash then - arr = obj.map { |key,val| [key, decrypt(ref, val)] }.flatten(1) - Hash[*arr] + seen[seen_key] ||= {} + obj.each do |key,val| + seen[seen_key][key] = decrypt(ref, val, seen) + end + seen[seen_key] when Array then - obj.collect { |item| decrypt(ref, item) } + seen[seen_key] ||= [] + obj.each do |item| + seen[seen_key] << decrypt(ref, item, seen) + end + seen[seen_key] when String sec_handler.decrypt(obj, ref) else