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