Class/Module Index [+]

Quicksearch

Brakeman::ControllerProcessor

Processes controller. Results are put in tracker.controllers

Constants

FORMAT_HTML

Public Class Methods

new(app_tree, tracker) click to toggle source
# File lib/brakeman/processors/controller_processor.rb, line 7
def initialize app_tree, tracker
  super(tracker)
  @app_tree = app_tree
  @controller = nil
  @current_method = nil
  @current_module = nil
  @visibility = :public
  @file_name = nil
end

Public Instance Methods

add_fake_filter(exp) click to toggle source

This is to handle before_filter do |controller| ... end

We build a new method and process that the same way as usual methods and filters.

# File lib/brakeman/processors/controller_processor.rb, line 188
def add_fake_filter exp
  filter_name = ("fake_filter" + rand.to_s[/\d+$/]).to_sym
  args = exp.block_call.arglist
  args.insert(1, Sexp.new(:lit, filter_name))
  before_filter_call = make_call(nil, :before_filter, args)

  if exp.block_args.length > 1
    block_variable = exp.block_args[1]
  else
    block_variable = :temp
  end

  if node_type? exp.block, :block
    block_inner = exp.block[1..-1]
  else
    block_inner = [exp.block]
  end

  #Build Sexp for filter method
  body = Sexp.new(:lasgn,
                  block_variable, 
                  Sexp.new(:call, Sexp.new(:const, @controller[:name]), :new))

  filter_method = Sexp.new(:defn, filter_name, Sexp.new(:args), body).concat(block_inner).line(exp.line)

  vis = @visibility
  @visibility = :private
  process_defn filter_method
  @visibility = vis
  process before_filter_call
  exp
end
process_call(exp) click to toggle source

Look for specific calls inside the controller

# File lib/brakeman/processors/controller_processor.rb, line 60
def process_call exp
  target = exp.target
  if sexp? target
    target = process target
  end

  method = exp.method
  first_arg = exp.first_arg
  last_arg = exp.last_arg

  #Methods called inside class definition
  #like attr_* and other settings
  if @current_method.nil? and target.nil? and @controller
    if first_arg.nil? #No args
      case method
      when :private, :protected, :public
        @visibility = method
      when :protect_from_forgery
        @controller[:options][:protect_from_forgery] = true
      else
        #??
      end
    else
      case method
      when :include
        @controller[:includes] << class_name(first_arg) if @controller
      when :before_filter
        @controller[:options][:before_filters] ||= []
        @controller[:options][:before_filters] << exp.args
      when :layout
        if string? last_arg
          #layout "some_layout"

          name = last_arg.value.to_s
          if @app_tree.layout_exists?(name)
            @controller[:layout] = "layouts/#{name}"
          else
            Brakeman.debug "[Notice] Layout not found: #{name}"
          end
        elsif node_type? last_arg, :nil, :false
          #layout :false or layout nil
          @controller[:layout] = false
        end
      else
        @controller[:options][method] ||= []
        @controller[:options][method] << exp
      end
    end

    exp
  elsif target == nil and method == :render
    make_render exp
  elsif exp == FORMAT_HTML and context[1] != :iter
    #This is an empty call to
    # format.html
    #Which renders the default template if no arguments
    #Need to make more generic, though.
    call = Sexp.new :render, :default, @current_method
    call.line(exp.line)
    call
  else
    call = make_call target, method, process_all!(exp.args)
    call.line(exp.line)
    call
  end
end
process_class(exp) click to toggle source

s(:class, NAME, PARENT, s(:scope ...))

# File lib/brakeman/processors/controller_processor.rb, line 24
def process_class exp
  name = class_name(exp.class_name)

  if @controller
    Brakeman.debug "[Notice] Skipping inner class: #{name}"
    return ignore
  end

  if @current_module
    name = (@current_module.to_s + "::" + name.to_s).to_sym
  end

  begin
    parent = class_name exp.parent_name
  rescue StandardError => e
    Brakeman.debug e
    parent = nil
  end

  @controller = { :name => name,
                  :parent => parent,
                  :includes => [],
                  :public => {},
                  :private => {},
                  :protected => {},
                  :options => {},
                  :src => exp,
                  :file => @file_name }
  @tracker.controllers[@controller[:name]] = @controller
  exp.body = process_all! exp.body
  set_layout_name
  @controller = nil
  exp
end
process_controller(src, file_name = nil) click to toggle source

Use this method to process a Controller

# File lib/brakeman/processors/controller_processor.rb, line 18
def process_controller src, file_name = nil
  @file_name = file_name
  process src
end
process_defn(exp) click to toggle source

Process method definition and store in Tracker

# File lib/brakeman/processors/controller_processor.rb, line 128
def process_defn exp
  name = exp.method_name
  @current_method = name
  res = Sexp.new :methdef, name, exp.formal_args, *process_all!(exp.body)
  res.line(exp.line)
  @current_method = nil
  @controller[@visibility][name] = res unless @controller.nil?
  res
end
process_defs(exp) click to toggle source

Process self.method definition and store in Tracker

# File lib/brakeman/processors/controller_processor.rb, line 139
def process_defs exp
  name = exp.method_name

  if exp[1].node_type == :self
    if @controller
      target = @controller[:name]
    elsif @current_module
      target = @current_module
    else
      target = nil
    end
  else
    target = class_name exp[1]
  end

  @current_method = name
  res = Sexp.new :selfdef, target, name, exp.formal_args, *process_all!(exp.body)
  res.line(exp.line)
  @current_method = nil
  @controller[@visibility][name] = res unless @controller.nil?

  res
end
process_iter(exp) click to toggle source

Look for before_filters and add fake ones if necessary

# File lib/brakeman/processors/controller_processor.rb, line 164
def process_iter exp
  if exp.block_call.method == :before_filter
    add_fake_filter exp
  else
    super
  end
end
set_layout_name() click to toggle source

Sets default layout for renders inside Controller

# File lib/brakeman/processors/controller_processor.rb, line 173
def set_layout_name
  return if @controller[:layout]

  name = underscore(@controller[:name].to_s.split("::")[-1].gsub("Controller", ''))

  #There is a layout for this Controller
  if @app_tree.layout_exists?(name)
    @controller[:layout] = "layouts/#{name}"
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.