This file is indexed.

/usr/lib/ruby/vendor_ruby/pry/method/patcher.rb is in pry 0.10.3-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
class Pry
  class Method
    class Patcher
      attr_accessor :method

      @@source_cache = {}

      def initialize(method)
        @method = method
      end

      def self.code_for(filename)
        @@source_cache[filename]
      end

      # perform the patch
      def patch_in_ram(source)
        if method.alias?
          with_method_transaction do
            redefine source
          end
        else
          redefine source
        end
      end

      private

      def redefine(source)
        @@source_cache[cache_key] = source
        TOPLEVEL_BINDING.eval wrap(source), cache_key
      end

      def cache_key
        "pry-redefined(0x#{method.owner.object_id.to_s(16)}##{method.name})"
      end

      # Run some code ensuring that at the end target#meth_name will not have changed.
      #
      # When we're redefining aliased methods we will overwrite the method at the
      # unaliased name (so that super continues to work). By wrapping that code in a
      # transation we make that not happen, which means that alias_method_chains, etc.
      # continue to work.
      #
      # @param [String] meth_name  The method name before aliasing
      # @param [Module] target  The owner of the method

      def with_method_transaction
        temp_name = "__pry_#{method.original_name}__"
        method = self.method
        method.owner.class_eval do
          alias_method temp_name, method.original_name
          yield
          alias_method method.name, method.original_name
          alias_method method.original_name, temp_name
        end

      ensure
        method.send(:remove_method, temp_name) rescue nil
      end

      # Update the definition line so that it can be eval'd directly on the Method's
      # owner instead of from the original context.
      #
      # In particular this takes `def self.foo` and turns it into `def foo` so that we
      # don't end up creating the method on the singleton class of the singleton class
      # by accident.
      #
      # This is necessarily done by String manipulation because we can't find out what
      # syntax is needed for the argument list by ruby-level introspection.
      #
      # @param [String] line The original definition line. e.g. def self.foo(bar, baz=1)
      # @return [String]  The new definition line. e.g. def foo(bar, baz=1)
      def definition_for_owner(line)
        if line =~ /\Adef (?:.*?\.)?#{Regexp.escape(method.original_name)}(?=[\(\s;]|$)/
          "def #{method.original_name}#{$'}"
        else
          raise CommandError, "Could not find original `def #{method.original_name}` line to patch."
        end
      end

      # Apply wrap_for_owner and wrap_for_nesting successively to `source`
      # @param [String] source
      # @return [String] The wrapped source.
      def wrap(source)
        wrap_for_nesting(wrap_for_owner(source))
      end

      # Update the source code so that when it has the right owner when eval'd.
      #
      # This (combined with definition_for_owner) is backup for the case that
      # wrap_for_nesting fails, to ensure that the method will stil be defined in
      # the correct place.
      #
      # @param [String] source  The source to wrap
      # @return [String]
      def wrap_for_owner(source)
        Pry.current[:pry_owner] = method.owner
        owner_source = definition_for_owner(source)
        visibility_fix = "#{method.visibility.to_s} #{method.name.to_sym.inspect}"
        "Pry.current[:pry_owner].class_eval do; #{owner_source}\n#{visibility_fix}\nend"
      end

      # Update the new source code to have the correct Module.nesting.
      #
      # This method uses syntactic analysis of the original source file to determine
      # the new nesting, so that we can tell the difference between:
      #
      #   class A; def self.b; end; end
      #   class << A; def b; end; end
      #
      # The resulting code should be evaluated in the TOPLEVEL_BINDING.
      #
      # @param [String] source  The source to wrap.
      # @return [String]
      def wrap_for_nesting(source)
        nesting = Pry::Code.from_file(method.source_file).nesting_at(method.source_line)

        (nesting + [source] + nesting.map{ "end" } + [""]).join(";")
      rescue Pry::Indent::UnparseableNestingError
        source
      end
    end
  end
end