Parent

Included Modules

Class/Module Index [+]

Quicksearch

Brakeman::FindReturnValue

Attempts to determine the return value of a method.

Preferred usage:

Brakeman::FindReturnValue.return_value exp

Public Class Methods

new() click to toggle source
# File lib/brakeman/processors/lib/find_return_value.rb, line 18
def initialize
  @uses_ivars = false
  @return_values = []
end
return_value(exp, env = nil) click to toggle source

Returns a guess at the return value of a given method or other block of code.

If multiple return values are possible, returns all values in an :or Sexp.

# File lib/brakeman/processors/lib/find_return_value.rb, line 14
def self.return_value exp, env = nil
  self.new.get_return_value exp, env
end

Public Instance Methods

find_explicit_return_values(exp) click to toggle source

Searches expression for return statements.

# File lib/brakeman/processors/lib/find_return_value.rb, line 59
def find_explicit_return_values exp
  todo = [exp]

  until todo.empty?
    current = todo.shift

    @uses_ivars = true if node_type? current, :ivar

    if node_type? current, :return
      @return_values << current.value unless current.value.nil?
    elsif sexp? current
      todo = current[1..-1].concat todo
    end
  end
end
get_return_value(exp, env = nil) click to toggle source

Find return value of Sexp. Takes an optional starting environment.

# File lib/brakeman/processors/lib/find_return_value.rb, line 28
def get_return_value exp, env = nil
  process_method exp, env
  value = make_return_value
  value.original_line(exp.line)
  value
end
last_value(exp) click to toggle source

Determines the "last value" of an expression.

# File lib/brakeman/processors/lib/find_return_value.rb, line 76
def last_value exp
  case exp.node_type
  when :rlist, :block, :scope, Sexp
    last_value exp.last
  when :if
    then_clause = exp.then_clause
    else_clause = exp.else_clause

    if then_clause.nil?
      last_value else_clause
    elsif else_clause.nil?
      last_value then_clause
    else
      true_branch = last_value then_clause
      false_branch = last_value else_clause

      if true_branch and false_branch
        value = make_or(true_branch, false_branch)
        value.original_line(value.rhs.line)
        value
      else #Unlikely?
        true_branch or false_branch
      end
    end
  when :lasgn, :iasgn
    exp.rhs
  when :return
    exp.value
  else
    exp.original_line(exp.line) unless exp.original_line
    exp
  end
end
make_or(lhs, rhs) click to toggle source
# File lib/brakeman/processors/lib/find_return_value.rb, line 110
def make_or lhs, rhs
  #Better checks in future
  if lhs == rhs
    lhs
  else
    Sexp.new(:or, lhs, rhs)
  end
end
make_return_value() click to toggle source

Turns the array of return values into an :or Sexp

# File lib/brakeman/processors/lib/find_return_value.rb, line 120
def make_return_value
  @return_values.compact!
  @return_values.uniq!

  if @return_values.empty?
    Sexp.new(:nil)
  elsif @return_values.length == 1
    @return_values.first
  else
    @return_values.reduce do |value, sexp|
      make_or value, sexp
    end
  end
end
process_method(exp, env = nil) click to toggle source

Process method (or, actually, any Sexp) for return value.

# File lib/brakeman/processors/lib/find_return_value.rb, line 36
def process_method exp, env = nil
  exp = Brakeman::AliasProcessor.new.process_safely exp, env

  find_explicit_return_values exp

  if node_type? exp, :methdef, :selfdef, :defn, :defs
    body = exp.body

    unless body.empty?
      @return_values << last_value(body)
    else
      Brakeman.debug "FindReturnValue: Empty method? #{exp.inspect}"
    end
  elsif exp
    @return_values << last_value(exp)
  else
     Brakeman.debug "FindReturnValue: Given something strange? #{exp.inspect}"
  end

  exp
end
uses_ivars?() click to toggle source
# File lib/brakeman/processors/lib/find_return_value.rb, line 23
def uses_ivars?
  @uses_ivars
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.