Included Modules

Class/Module Index [+]

Quicksearch

Brakeman::ControllerAliasProcessor

Processes aliasing in controllers, but includes following renders in routes and putting variables into templates

Public Class Methods

new(app_tree, tracker, only_method = nil) click to toggle source

If only_method is specified, only that method will be processed, other methods will be skipped. This is for rescanning just a single action.

# File lib/brakeman/processors/controller_alias_processor.rb, line 13
def initialize app_tree, tracker, only_method = nil
  super()
  @app_tree = app_tree
  @only_method = only_method
  @tracker = tracker
  @rendered = false
  @current_class = @current_module = @current_method = nil
  @method_cache = {} #Cache method lookups
end

Public Instance Methods

before_filter_list(method, klass) click to toggle source

Get list of filters, including those that are inherited

# File lib/brakeman/processors/controller_alias_processor.rb, line 222
def before_filter_list method, klass
  controller = @tracker.controllers[klass]
  filters = []

  while controller
    filters = get_before_filters(method, controller) + filters

    controller = @tracker.controllers[controller[:parent]]
  end

  filters
end
before_filter_to_hash(args) click to toggle source

Returns a before filter as a hash table

# File lib/brakeman/processors/controller_alias_processor.rb, line 266
def before_filter_to_hash args
  filter = {}

  #Process args for the uncommon but possible situation
  #in which some variables are used in the filter.
  args.each do |a|
    if sexp? a
      a = process_default a
    end
  end

  filter[:methods] = [args[0][1]]

  args[1..-1].each do |a|
    filter[:methods] << a[1] if a.node_type == :lit
  end

  if args[-1].node_type == :hash
    option = args[-1][1][1]
    value = args[-1][2]
    case value.node_type
    when :array
      filter[option] = value[1..-1].map {|v| v[1] }
    when :lit, :str
      filter[option] = value[1]
    else
      Brakeman.debug "[Notice] Unknown before_filter value: #{option} => #{value}"
    end
  else
    filter[:all] = true
  end

  filter
end
find_method(method_name, klass) click to toggle source

Finds a method in the given class or a parent class

Returns nil if the method could not be found.

If found, returns hash table with controller name and method sexp.

# File lib/brakeman/processors/controller_alias_processor.rb, line 306
def find_method method_name, klass
  return nil if sexp? method_name
  method_name = method_name.to_sym

  if method = @method_cache[method_name]
    return method
  end

  controller = @tracker.controllers[klass]
  controller ||= @tracker.libs[klass]

  if klass and controller
    method = controller[:public][method_name]
    method ||= controller[:private][method_name]
    method ||= controller[:protected][method_name]

    if method.nil?
      controller[:includes].each do |included|
        method = find_method method_name, included
        if method
          @method_cache[method_name] = method
          return method
        end
      end

      @method_cache[method_name] = find_method method_name, controller[:parent]
    else
      @method_cache[method_name] = { :controller => controller[:name], :method => method }
    end
  else
    nil
  end
end
get_before_filters(method, controller) click to toggle source

Returns an array of filter names

# File lib/brakeman/processors/controller_alias_processor.rb, line 236
def get_before_filters method, controller
  return [] unless controller[:options] and controller[:options][:before_filters]

  filters = []

  if controller[:before_filter_cache].nil?
    filter_cache = []

    controller[:options][:before_filters].each do |filter|
      filter_cache << before_filter_to_hash(filter)
    end

    controller[:before_filter_cache] = filter_cache
  end

  controller[:before_filter_cache].each do |f|
    if f[:all] or
      (f[:only] == method) or
      (f[:only].is_a? Array and f[:only].include? method) or
      (f[:except].is_a? Symbol and f[:except] != method) or
      (f[:except].is_a? Array and not f[:except].include? method)

      filters.concat f[:methods]
    end
  end

  filters
end
layout_name() click to toggle source

Determines default layout name

# File lib/brakeman/processors/controller_alias_processor.rb, line 198
def layout_name
  controller = @tracker.controllers[@current_class]

  return controller[:layout] if controller[:layout]
  return false if controller[:layout] == false

  app_controller = @tracker.controllers[:ApplicationController]

  return app_controller[:layout] if app_controller and app_controller[:layout]

  nil
end
process_before_filter(name) click to toggle source

Processes a call to a before filter. Basically, adds any instance variable assignments to the environment. TODO: method arguments?

# File lib/brakeman/processors/controller_alias_processor.rb, line 145
def process_before_filter name
  filter = find_method name, @current_class

  if filter.nil?
    Brakeman.debug "[Notice] Could not find filter #{name}"
    return
  end

  method = filter[:method]

  if ivars = @tracker.filter_cache[[filter[:controller], name]]
    ivars.each do |variable, value|
      env[variable] = value
    end
  else
    processor = Brakeman::AliasProcessor.new @tracker
    processor.process_safely(method.body_list, only_ivars(:include_request_vars))

    ivars = processor.only_ivars(:include_request_vars).all

    @tracker.filter_cache[[filter[:controller], name]] = ivars

    ivars.each do |variable, value|
      env[variable] = value
    end
  end
end
process_call(exp) click to toggle source

Look for calls to head()

# File lib/brakeman/processors/controller_alias_processor.rb, line 114
def process_call exp
  exp = super
  return exp unless call? exp

  method = exp.method

  if method == :head
    @rendered = true
  elsif @tracker.options[:interprocedural] and
    @current_method and (exp.target.nil? or exp.target.node_type == :self)

    exp = get_call_value(exp)
  end

  exp
end
process_call_with_block(exp) click to toggle source

Check for respond_to

# File lib/brakeman/processors/controller_alias_processor.rb, line 132
def process_call_with_block exp
  process_default exp

  if call? exp.block_call and exp.block_call.method == :respond_to
    @rendered = true
  end

  exp
end
process_class(exp) click to toggle source

Processes a class which is probably a controller. (This method should be retired - only classes should ever be processed

and @current_module will never be set, leading to inaccurate class names)
# File lib/brakeman/processors/controller_alias_processor.rb, line 70
def process_class exp
  @current_class = class_name(exp.class_name)
  if @current_module
    @current_class = ("#@current_module::#@current_class").to_sym
  end

  process_default exp
end
process_controller(name, src) click to toggle source
# File lib/brakeman/processors/controller_alias_processor.rb, line 23
def process_controller name, src
  if not node_type? src, :class
    Brakeman.debug "#{name} is not a class, it's a #{src.node_type}"
    return
  else
    @current_class = name

    process_default src

    process_mixins
  end
end
process_default_render(exp) click to toggle source

Processes the default template for the current action

# File lib/brakeman/processors/controller_alias_processor.rb, line 174
def process_default_render exp
  process_layout
  process_template template_name, nil
end
process_methdef(exp) click to toggle source

Processes a method definition, which may include processing any rendered templates.

# File lib/brakeman/processors/controller_alias_processor.rb, line 81
def process_methdef exp
  meth_name = exp.method_name

  #Skip if instructed to only process a specific method
  #(but don't skip if this method was called from elsewhere)
  return exp if @current_method.nil? and @only_method and @only_method != meth_name

  is_route = route? meth_name
  other_method = @current_method
  @current_method = meth_name
  @rendered = false if is_route

  env.scope do
    set_env_defaults

    if is_route
      before_filter_list(@current_method, @current_class).each do |f|
        process_before_filter f
      end
    end

    process_all exp.body

    if is_route and not @rendered
      process_default_render exp
    end
  end

  @current_method = other_method
  exp
end
process_mixins() click to toggle source

Process modules mixed into the controller, in case they contain actions.

# File lib/brakeman/processors/controller_alias_processor.rb, line 37
def process_mixins
  controller = @tracker.controllers[@current_class]

  controller[:includes].each do |i|
    mixin = @tracker.libs[i]

    next unless mixin

    #Process methods in alphabetical order for consistency
    methods = mixin[:public].keys.map { |n| n.to_s }.sort.map { |n| n.to_sym }

    methods.each do |name|
      #Need to process the method like it was in a controller in order
      #to get the renders set
      processor = Brakeman::ControllerProcessor.new(@app_tree, @tracker)
      method = mixin[:public][name]

      if node_type? method, :methdef
        method = processor.process_defn method
      else
        #Should be a methdef, but this will catch other cases
        method = processor.process method
      end

      #Then process it like any other method in the controller
      process method
    end
  end
end
process_template(name, args) click to toggle source

Process template and add the current class and method name as called_from info

# File lib/brakeman/processors/controller_alias_processor.rb, line 180
def process_template name, args
  super name, args, ["#@current_class##@current_method"]
end
route?(method) click to toggle source

Returns true if the given method name is also a route

# File lib/brakeman/processors/controller_alias_processor.rb, line 212
def route? method
  if @tracker.routes[:allow_all_actions] or @tracker.options[:assume_all_routes]
    true
  else
    routes = @tracker.routes[@current_class]
    routes and (routes == :allow_all_actions or routes.include? method)
  end
end
template_name(name = nil) click to toggle source

Turns a method name into a template name

# File lib/brakeman/processors/controller_alias_processor.rb, line 185
def template_name name = nil
  name ||= @current_method
  name = name.to_s
  if name.include? "/"
    name
  else
    controller = @current_class.to_s.gsub("Controller", "")
    controller.gsub!("::", "/")
    underscore(controller + "/" + name.to_s)
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.