lib/contrast/agent/patching/policy/method_policy.rb in contrast-agent-4.13.1 vs lib/contrast/agent/patching/policy/method_policy.rb in contrast-agent-4.14.0
- old
+ new
@@ -1,14 +1,17 @@
# Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true
+require 'contrast/agent/patching/policy/method_policy_extend'
+
module Contrast
module Agent
module Patching
module Policy
# This class is used to map each method to the trigger node that applies to it
class MethodPolicy
+ extend Contrast::Agent::Patching::Policy::MethodPolicyExtend
attr_reader :deadzone_node, :inventory_node, :propagation_node, :protect_node, :trigger_node
attr_accessor :source_node, :method_name, :method_visibility, :instance_method
def initialize(source_node: nil, propagation_node: nil,
trigger_node: nil, inventory_node: nil,
@@ -57,98 +60,9 @@
def method_scopes
# Implicitly, the scope precedence is the node order
# defined by #nodes.
@_method_scopes ||= nodes.flat_map(&:method_scope).tap(&:compact!).tap(&:uniq!)
- end
-
- class << self
- # Given a Contrast::Agent::Patching::Policy::ModulePolicy, parse
- # out its information for the given method in order to construct a
- # Contrast::Agent::Patching::Policy::MethodPolicy
- #
- # @param method_name [Symbol] the name of the method for this policy
- # @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy]
- # the entire policy for this module
- # @param instance_method [Boolean] true if this method is an
- # instance method
- # @return [Contrast::Agent::Patching::Policy::MethodPolicy]
- def build_method_policy method_name, module_policy, instance_method
- source_node = find_method_node(module_policy.source_nodes, method_name, instance_method)
- propagation_node = find_method_node(module_policy.propagator_nodes, method_name, instance_method)
- trigger_node = find_method_node(module_policy.trigger_nodes, method_name, instance_method)
- protect_node = find_method_node(module_policy.protect_nodes, method_name, instance_method)
- inventory_node = find_method_node(module_policy.inventory_nodes, method_name, instance_method)
- deadzone_node = find_method_node(module_policy.deadzone_nodes, method_name, instance_method)
- method_visibility = find_visibility(source_node, propagation_node, trigger_node, protect_node,
- inventory_node, deadzone_node)
- method_policy = MethodPolicy.new(method_name: method_name,
- method_visibility: method_visibility,
- instance_method: instance_method,
- source_node: source_node,
- propagation_node: propagation_node,
- trigger_node: trigger_node,
- protect_node: protect_node,
- inventory_node: inventory_node,
- deadzone_node: deadzone_node)
-
- return method_policy unless check_method_policy_nodes_empty? source_node, propagation_node, trigger_node,
- protect_node, inventory_node, deadzone_node
-
- create_new_node(module_policy, method_policy) if module_policy.deadzone_nodes&.any?
- method_policy
- end
-
- def find_method_node nodes, method_name, is_instance_method
- return unless nodes
-
- nodes.find do |node|
- node.instance_method? == is_instance_method && node.method_name == method_name
- end
- end
-
- def find_visibility *nodes
- nodes.find { |node| node }&.method_visibility
- end
-
- def check_method_policy_nodes_empty?(source_node, propagation_node, trigger_node, protect_node,
- inventory_node, deadzone_node)
- return false unless source_node.nil? && propagation_node.nil? && trigger_node.nil? && protect_node.nil? &&
- inventory_node.nil? && deadzone_node.nil?
-
- true
- end
-
- private
-
- def create_new_node module_policy, method_policy
- return if module_policy.deadzone_nodes.empty?
-
- module_policy.deadzone_nodes.map do |node|
- next unless node.method_name.nil?
-
- klass = Module.cs__const_get(node.class_name)
- next unless it_defined? klass, method_policy.method_name
-
- new_node = {}
- new_node['instance_method'] = method_policy.instance_method
- new_node['method_visibility'] =
- klass.private_method_defined?(method_policy.method_name) ? 'private' : 'public'
- new_node['method_name'] = method_policy.method_name
- new_node['class_name'] = node.class_name
- new_node = Contrast::Agent::Deadzone::Policy::DeadzoneNode.new(new_node)
- method_policy.instance_variable_set(:@method_visibility, new_node.method_visibility)
- method_policy.instance_variable_set(:@deadzone_node, new_node)
- module_policy.deadzone_nodes << new_node
- break unless method_policy.deadzone_node.nil?
- end
- end
-
- def it_defined? klass, method_name
- klass.instance_methods(false).include?(method_name) ||
- klass.private_instance_methods(false).include?(method_name) ||
- klass.singleton_methods(false).include?(method_name)
- end
end
end
end
end
end