Sha256: bd389e077b39d83f544b919fec65e6775dc09686aa7ddc9ba096f5cf5bd8401b

Contents?: true

Size: 1.9 KB

Versions: 2

Compression:

Stored size: 1.9 KB

Contents

# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true

cs__scoped_require 'contrast/core_extensions/object'

module Contrast
  module Utils
    # Utility methods for exploring the complete space of objects
    class ClassUtil
      def self.ancestors_of clazz
        arr = []
        ObjectSpace.each_object(Module) do |obj|
          next unless obj <= clazz

          arr << obj
        end
        arr
      end

      # some classes have had things prepended to them, like Marshal in Rails
      # 5 and higher. Their ActiveSupport::MarshalWithAutoloading will break
      # our alias patching approach, as will any other prepend on something
      # that we touch. Prepend and Alias are inherently incompatible monkey
      # patching approaches. As such, we need to know if something has been
      # prepended to.
      #
      # return true if the given module is not its first ancestor
      def self.prepended? mod, ancestors = nil
        ancestors ||= mod.ancestors
        ancestors[0] != mod
      end

      def self.determine_target_class mod, is_instance
        return mod if mod.singleton_class?

        return mod.cs__singleton_class unless is_instance

        mod
      end

      # return true if the given method is overwritten by one of the ancestors
      # in the ancestor change that comes before the given module
      def self.prepended_method? mod, method_policy
        target_module = determine_target_class mod, method_policy.instance_method
        ancestors = target_module.ancestors
        return false unless prepended?(target_module, ancestors)

        ancestors.each do |ancestor|
          break if ancestor == target_module

          methods = ancestor.instance_methods(false)
          return true if methods.include?(method_policy.method_name)
        end
        false
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
contrast-agent-3.8.5 lib/contrast/utils/class_util.rb
contrast-agent-3.8.4 lib/contrast/utils/class_util.rb