lib/contrast/agent/assess/policy/preshift.rb in contrast-agent-4.11.0 vs lib/contrast/agent/assess/policy/preshift.rb in contrast-agent-4.12.0
- old
+ new
@@ -1,19 +1,21 @@
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true
require 'contrast/components/logger'
+require 'contrast/utils/lru_cache'
module Contrast
module Agent
module Assess
# In order to properly shift tags to account for the changes this method
# caused, we'll need to store the state before the change occurred.
class PreShift
include Contrast::Components::Logger::InstanceMethods
extend Contrast::Components::Logger::InstanceMethods
+ @lru_cache = Contrast::Utils::LRUCache.new
UNDUPLICABLE_MODULES = [
Enumerator # dup'ing results in 'can't copy execution context'
].cs__freeze
attr_accessor :object, :object_length, :args, :arg_lengths
@@ -68,36 +70,47 @@
!UNDUPLICABLE_MODULES.include?(check)
end
def append_object_details preshift, initializing, object
can = can_dup?(initializing, object)
- preshift.object = can ? object.dup : object
+ preshift.object = if @lru_cache.key?(object.__id__) && !Contrast::Agent::Assess::Tracker.tracked?(object)
+ @lru_cache[object.__id__]
+ else
+ can ? object.dup : object
+ end
preshift.object_length = if Contrast::Utils::DuckUtils.quacks_to?(preshift.object, :length)
object.length
else
0
end
+
return unless can
+
return unless Contrast::Agent::Assess::Tracker.tracked?(object)
Contrast::Agent::Assess::Tracker.copy(object, preshift.object)
+ @lru_cache[object.__id__] = object
end
def append_arg_details preshift, args
args_length = args.length
preshift.args = Array.new(args_length)
preshift.arg_lengths = Array.new(args_length)
idx = 0
while idx < args_length
- original_arg = args[idx]
- p_arg = can_dup?(false, original_arg) ? original_arg.dup : original_arg
+ or_arg = args[idx]
+ p_arg = if @lru_cache.key?(or_arg.__id__)
+ @lru_cache[or_arg.__id__]
+ else
+ can_dup?(false, or_arg) ? or_arg.dup : or_arg
+ end
preshift.args[idx] = p_arg
preshift.arg_lengths[idx] = Contrast::Utils::DuckUtils.quacks_to?(p_arg, :length) ? p_arg.length : 0
idx += 1
- next if p_arg.__id__ == original_arg.__id__
- next unless Contrast::Agent::Assess::Tracker.tracked?(original_arg)
+ next if p_arg.__id__ == or_arg.__id__
- Contrast::Agent::Assess::Tracker.copy(original_arg, p_arg)
+ Contrast::Agent::Assess::Tracker.copy(or_arg, p_arg)
+ @lru_cache[p_arg.__id__] = p_arg
end
end
end
end
end