Class: Brakeman::CallIndex

Inherits:
Object
  • Object
show all
Defined in:
lib/brakeman/call_index.rb

Overview

Stores call sites to look up later.

Instance Method Summary collapse

Constructor Details

#initialize(calls) ⇒ CallIndex

Initialize index with calls from FindAllCalls



7
8
9
10
11
12
# File 'lib/brakeman/call_index.rb', line 7

def initialize calls
  @calls_by_method = Hash.new { |h, k| h[k] = [] }
  @calls_by_target = Hash.new { |h, k| h[k] = [] }

  index_calls calls
end

Instance Method Details

#find_calls(options) ⇒ Object

Find calls matching specified option hash.

Options:

* :target - symbol, array of symbols, or regular expression to match target(s)
* :method - symbol, array of symbols, or regular expression to match method(s)
* :chained - boolean, whether or not to match against a whole method chain (false by default)
* :nested - boolean, whether or not to match against a method call that is a target itself (false by default)


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
# File 'lib/brakeman/call_index.rb', line 22

def find_calls options
  target = options[:target] || options[:targets]
  method = options[:method] || options[:methods]
  nested = options[:nested]

  if options[:chained]
    return find_chain options
  #Find by narrowest category
  elsif target and method and target.is_a? Array and method.is_a? Array
    if target.length > method.length
      calls = filter_by_target calls_by_methods(method), target
    else
      calls = calls_by_targets(target)
      calls = filter_by_method calls, method
    end

  #Find by target, then by methods, if provided
  elsif target
    calls = calls_by_target target

    if calls and method
      calls = filter_by_method calls, method
    end

  #Find calls with no explicit target
  #with either :target => nil or :target => false
  elsif (options.key? :target or options.key? :targets) and not target and method
    calls = calls_by_method method
    calls = filter_by_target calls, nil

  #Find calls by method
  elsif method
    calls = calls_by_method method
  else
    raise "Invalid arguments to CallCache#find_calls: #{options.inspect}"
  end

  return [] if calls.nil?

  #Remove calls that are actually targets of other calls
  #Unless those are explicitly desired
  calls = filter_nested calls unless nested

  calls
end

#index_calls(calls) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/brakeman/call_index.rb', line 88

def index_calls calls
  calls.each do |call|
    @calls_by_method[call[:method]] << call

    target = call[:target]

    if not target.is_a? Sexp
      @calls_by_target[target] << call
    elsif target.node_type == :params or target.node_type == :session
      @calls_by_target[target.node_type] << call
    end
  end
end

#remove_indexes_by_class(classes) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/brakeman/call_index.rb', line 78

def remove_indexes_by_class classes
  [@calls_by_method, @calls_by_target].each do |calls_by|
    calls_by.each do |_name, calls|
      calls.delete_if do |call|
        call[:location][:type] == :class and classes.include? call[:location][:class]
      end
    end
  end
end

#remove_template_indexes(template_name = nil) ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/brakeman/call_index.rb', line 68

def remove_template_indexes template_name = nil
  [@calls_by_method, @calls_by_target].each do |calls_by|
    calls_by.each do |_name, calls|
      calls.delete_if do |call|
        from_template call, template_name
      end
    end
  end
end