class Brakeman::CallIndex
Stores call sites to look up later.
Public Class Methods
new(calls)
click to toggle source
Initialize index with calls from FindAllCalls
# File lib/brakeman/call_index.rb, line 7 def initialize calls @calls_by_method = {} @calls_by_target = {} index_calls calls end
Public Instance Methods
find_calls(options)
click to toggle source
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)
# 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.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 elsif target.is_a? Regexp and method calls = filter_by_target(calls_by_method(method), target) elsif method.is_a? Regexp and target calls = filter_by_method(calls_by_target(target), method) #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)
click to toggle source
# File lib/brakeman/call_index.rb, line 104 def index_calls calls calls.each do |call| @calls_by_method[call[:method]] ||= [] @calls_by_method[call[:method]] << call target = call[:target] if not target.is_a? Sexp @calls_by_target[target] ||= [] @calls_by_target[target] << call elsif target.node_type == :params or target.node_type == :session @calls_by_target[target.node_type] ||= [] @calls_by_target[target.node_type] << call end end end
remove_indexes_by_class(classes)
click to toggle source
# File lib/brakeman/call_index.rb, line 84 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_indexes_by_file(file)
click to toggle source
# File lib/brakeman/call_index.rb, line 94 def remove_indexes_by_file file [@calls_by_method, @calls_by_target].each do |calls_by| calls_by.each do |_name, calls| calls.delete_if do |call| call[:location][:file] == file end end end end
remove_template_indexes(template_name = nil)
click to toggle source
# File lib/brakeman/call_index.rb, line 74 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
Private Instance Methods
calls_by_method(method)
click to toggle source
# File lib/brakeman/call_index.rb, line 168 def calls_by_method method case method when Array calls_by_methods method when Regexp calls_by_methods_regex method else @calls_by_method[method.to_sym] || [] end end
calls_by_methods(methods)
click to toggle source
# File lib/brakeman/call_index.rb, line 179 def calls_by_methods methods methods = methods.map { |m| m.to_sym } calls = [] methods.each do |method| calls.concat @calls_by_method[method] if @calls_by_method.key? method end calls end
calls_by_methods_regex(methods_regex)
click to toggle source
# File lib/brakeman/call_index.rb, line 190 def calls_by_methods_regex methods_regex calls = [] @calls_by_method.each do |key, value| calls.concat value if key.match methods_regex end calls end
calls_by_target(target)
click to toggle source
# File lib/brakeman/call_index.rb, line 134 def calls_by_target target case target when Array calls_by_targets target when Regexp calls_by_targets_regex target else @calls_by_target[target] || [] end end
calls_by_targets(targets)
click to toggle source
# File lib/brakeman/call_index.rb, line 145 def calls_by_targets targets calls = [] targets.each do |target| calls.concat @calls_by_target[target] if @calls_by_target.key? target end calls end
calls_by_targets_regex(targets_regex)
click to toggle source
# File lib/brakeman/call_index.rb, line 155 def calls_by_targets_regex targets_regex calls = [] @calls_by_target.each do |key, value| case key when String, Symbol calls.concat value if key.match targets_regex end end calls end
filter(calls, key, value)
click to toggle source
# File lib/brakeman/call_index.rb, line 200 def filter calls, key, value case value when Array values = Set.new value calls.select do |call| values.include? call[key] end when Regexp calls.select do |call| case call[key] when String, Symbol call[key].match value end end else calls.select do |call| call[key] == value end end end
filter_by_chain(calls, target)
click to toggle source
# File lib/brakeman/call_index.rb, line 234 def filter_by_chain calls, target case target when Array targets = Set.new target calls.select do |call| targets.include? call[:chain].first end when Regexp calls.select do |call| case call[:chain].first when String, Symbol call[:chain].first.match target end end else calls.select do |call| call[:chain].first == target end end end
filter_by_method(calls, method)
click to toggle source
# File lib/brakeman/call_index.rb, line 222 def filter_by_method calls, method filter calls, :method, method end
filter_by_target(calls, target)
click to toggle source
# File lib/brakeman/call_index.rb, line 226 def filter_by_target calls, target filter calls, :target, target end
filter_nested(calls)
click to toggle source
# File lib/brakeman/call_index.rb, line 230 def filter_nested calls filter calls, :nested, false end
find_chain(options)
click to toggle source
# File lib/brakeman/call_index.rb, line 123 def find_chain options target = options[:target] || options[:targets] method = options[:method] || options[:methods] calls = calls_by_method method return [] if calls.nil? calls = filter_by_chain calls, target end
from_template(call, template_name)
click to toggle source
# File lib/brakeman/call_index.rb, line 256 def from_template call, template_name return false unless call[:location][:type] == :template return true if template_name.nil? call[:location][:template] == template_name end