Included Modules

Class/Module Index [+]

Quicksearch

Brakeman::Rails2RoutesProcessor

Processes the Sexp from routes.rb. Stores results in tracker.routes.

Note that it is only interested in determining what methods on which controllers are used as routes, not the generated URLs for routes.

Attributes

current_controller[R]
map[R]
nested[R]

Public Class Methods

new(tracker) click to toggle source
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 12
def initialize tracker
  super
  @map = Sexp.new(:lvar, :map)
  @nested = nil  #used for identifying nested targets
  @prefix = [] #Controller name prefix (a module name, usually)
  @current_controller = nil
  @with_options = nil #For use inside map.with_options
end

Public Instance Methods

process_call(exp) click to toggle source

Looking for mapping of routes

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 30
def process_call exp
  target = exp.target

  if target == map or (not target.nil? and target == nested)
    process_map exp
  else
    process_default exp
  end

  exp
end
process_collection(exp) click to toggle source

Process collection option

:collection => { :some_action => :http_actions }
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 256
def process_collection exp
  return unless exp.node_type == :hash
  routes = @tracker.routes[@current_controller]

  hash_iterate(exp) do |action, type|
    routes << action.value
  end
end
process_connect(exp) click to toggle source

Process

map.connect '/something', :controller => 'blah', :action => 'whatever'
# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 181
def process_connect exp
  return if exp.empty?

  controller = check_for_controller_name exp
  self.current_controller = controller if controller
  
  #Check for default route
  if string? exp.first
    if exp.first.value == ":controller/:action/:id"
      @tracker.routes[:allow_all_actions] = exp.first
    elsif exp.first.value.include? ":action"
      @tracker.routes[@current_controller] = [:allow_all_actions, exp.line]
      return
    end
  end

  #This -seems- redundant, but people might connect actions
  #to a controller which already allows them all
  return if @tracker.routes[@current_controller].is_a? Array and @tracker.routes[@current_controller][0] == :allow_all_actions

  exp.last.each_with_index do |e,i|
    if symbol? e and e.value == :action
      action = exp.last[i + 1]
      
      if node_type? action, :lit
        @tracker.routes[@current_controller] << action.value.to_sym
      end

      return
    end
  end
end
process_iter(exp) click to toggle source

Look for map calls that take a block. Otherwise, just do the default processing.

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 63
def process_iter exp
  target = exp.block_call.target

  if target == map or target == nested
    method = exp.block_call.method
    case method
    when :namespace
      process_namespace exp
    when :resources, :resource
      process_resources exp.block_call.args
      process_default exp.block if exp.block
    when :with_options
      process_with_options exp
    end
    exp
  else
    super
  end
end
process_map(exp) click to toggle source

Process a map.something call based on the method used

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 44
def process_map exp
  args = exp.args

  case exp.method
  when :resource
    process_resource args
  when :resources
    process_resources args
  when :connect, :root
    process_connect args
  else
    process_named_route args
  end

  exp
end
process_named_route(exp) click to toggle source

map.something_abnormal '/blah', :controller => 'something', :action => 'wohoo'

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 250
def process_named_route exp
  process_connect exp
end
process_namespace(exp) click to toggle source

map.namespace :something do |something|

something.resources :blah

end

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 233
def process_namespace exp
  call = exp.block_call
  formal_args = exp.block_args
  block = exp.block

  @prefix << camelize(call.first_arg.value)

  if formal_args
    @nested = Sexp.new(:lvar, formal_args.value)
  end

  process block

  @prefix.pop
end
process_option_except(exp) click to toggle source

Process route option :except => ...

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 153
def process_option_except exp
  return unless exp.node_type == :array
  routes = @tracker.routes[@current_controller]

  exp[1..-1].each do |e|
    routes.delete e.value
  end
end
process_option_only(exp) click to toggle source

Process route option :only => ...

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 139
def process_option_only exp
  routes = @tracker.routes[@current_controller]
  [:index, :new, :create, :show, :edit, :update, :destroy].each do |r|
    routes.delete r
  end

  if exp.node_type == :array
    exp[1..-1].each do |e|
      routes << e.value
    end
  end
end
process_resource(exp) click to toggle source

map.resource :x, ..

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 163
def process_resource exp
  controller = check_for_controller_name exp
  if controller
    self.current_controller = controller
    process_resource_options exp.last
  else
    exp.each do |argument|
      if node_type? argument, :lit
        self.current_controller = pluralize(exp.first.value.to_s)
        add_resource_routes
        process_resource_options exp.last
      end
    end
  end
end
process_resource_options(exp) click to toggle source

Process all the options that might be in the hash passed to map.resource, et al.

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 104
def process_resource_options exp
  if exp.nil? and @with_options
    exp = @with_options
  elsif @with_options
    exp = exp.concat @with_options[1..-1]
  end
  return unless exp.node_type == :hash

  hash_iterate(exp) do |option, value|
    case option[1]
    when :controller, :requirements, :singular, :path_prefix, :as,
      :path_names, :shallow, :name_prefix, :member_path, :nested_member_path,
      :belongs_to, :conditions, :active_scaffold
      #should be able to skip
    when :collection, :member, :new
      process_collection value
    when :has_one
      save_controller = current_controller
      process_resource value[1..-1] #Verify this is proper behavior
      self.current_controller = save_controller
    when :has_many
      save_controller = current_controller
      process_resources value[1..-1]
      self.current_controller = save_controller
    when :only
      process_option_only value
    when :except
      process_option_except value
    else
      Brakeman.notify "[Notice] Unhandled resource option, please report: #{option}"
    end
  end
end
process_resources(exp) click to toggle source

Process

map.resources :x, :controller => :y, :member => ...

etc.

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 86
def process_resources exp
  controller = check_for_controller_name exp
  if controller
    self.current_controller = controller
    process_resource_options exp[-1]
  else
    exp.each do |argument|
      if node_type? argument, :lit
        self.current_controller = exp.first.value
        add_resources_routes
        process_resource_options exp.last
      end
    end
  end
end
process_routes(exp) click to toggle source

Call this with parsed route file information.

This method first calls RouteAliasProcessor#process_safely on the exp, so it does not modify the exp.

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 25
def process_routes exp
  process Brakeman::RouteAliasProcessor.new.process_safely(exp)
end
process_with_options(exp) click to toggle source

map.with_options :controller => 'something' do |something|

something.resources :blah

end

# File lib/brakeman/processors/lib/rails2_route_processor.rb, line 217
def process_with_options exp
  @with_options = exp.block_call.last_arg
  @nested = Sexp.new(:lvar, exp.block_args.value)

  self.current_controller = check_for_controller_name exp.block_call.args
  
  #process block
  process exp.block

  @with_options = nil
  @nested = nil
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.