Class: Brakeman::FindReturnValue
- Inherits:
-
Object
- Object
- Brakeman::FindReturnValue
- Includes:
- Util
- Defined in:
- lib/brakeman/processors/lib/find_return_value.rb
Overview
Attempts to determine the return value of a method.
Preferred usage:
Brakeman::FindReturnValue.return_value exp
Constant Summary
Constants included from Util
Util::ALL_COOKIES, Util::ALL_PARAMETERS, Util::COOKIES, Util::COOKIES_SEXP, Util::DIR_CONST, Util::LITERALS, Util::PARAMETERS, Util::PARAMS_SEXP, Util::PATH_PARAMETERS, Util::QUERY_PARAMETERS, Util::REQUEST_COOKIES, Util::REQUEST_ENV, Util::REQUEST_PARAMETERS, Util::REQUEST_PARAMS, Util::REQUEST_REQUEST_PARAMETERS, Util::SAFE_LITERAL, Util::SESSION, Util::SESSION_SEXP, Util::SIMPLE_LITERALS
Class Method Summary collapse
-
.return_value(exp, env = nil) ⇒ Object
Returns a guess at the return value of a given method or other block of code.
Instance Method Summary collapse
-
#find_explicit_return_values(exp) ⇒ Object
Searches expression for return statements.
-
#get_return_value(exp, env = nil) ⇒ Object
Find return value of Sexp.
-
#initialize ⇒ FindReturnValue
constructor
A new instance of FindReturnValue.
-
#last_value(exp) ⇒ Object
Determines the “last value” of an expression.
- #make_or(lhs, rhs) ⇒ Object
-
#make_return_value ⇒ Object
Turns the array of return values into an :or Sexp.
-
#process_method(exp, env = nil) ⇒ Object
Process method (or, actually, any Sexp) for return value.
- #uses_ivars? ⇒ Boolean
Methods included from Util
#all_literals?, #array?, #block?, #call?, #camelize, #class_name, #constant?, #contains_class?, #cookies?, #dir_glob?, #false?, #hash?, #hash_access, #hash_insert, #hash_iterate, #hash_values, #integer?, #kwsplat?, #literal?, #make_call, #node_type?, #number?, #params?, #pluralize, #rails_version, #recurse_check?, #regexp?, #remove_kwsplat, #request_env?, #request_value?, #result?, #safe_literal, #safe_literal?, #safe_literal_target?, #set_env_defaults, #sexp?, #simple_literal?, #string?, #string_interp?, #symbol?, #template_path_to_name, #true?, #underscore
Constructor Details
#initialize ⇒ FindReturnValue
Returns a new instance of FindReturnValue.
18 19 20 21 |
# File 'lib/brakeman/processors/lib/find_return_value.rb', line 18 def initialize @uses_ivars = false @return_values = [] end |
Class Method Details
.return_value(exp, env = nil) ⇒ Object
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.
14 15 16 |
# 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 |
Instance Method Details
#find_explicit_return_values(exp) ⇒ Object
Searches expression for return statements.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# 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 << last_value(current.value) if current.value elsif sexp? current todo = current[1..-1].concat todo end end end |
#get_return_value(exp, env = nil) ⇒ Object
Find return value of Sexp. Takes an optional starting environment.
28 29 30 31 32 33 |
# 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) ⇒ Object
Determines the “last value” of an expression.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# 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? and else_clause.nil? nil elsif 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, :op_asgn_or, :attrasgn last_value exp.rhs when :rescue values = [] exp.each_sexp do |e| if node_type? e, :resbody if e.last values << last_value(e.last) end elsif sexp? e values << last_value(e) end end values.reject! do |v| v.nil? or node_type? v, :nil end if values.length > 1 values.inject do |m, v| make_or(m, v) end else values.first end when :return if exp.value last_value exp.value else nil end when :nil nil else exp.original_line = exp.line unless exp.original_line exp end end |
#make_or(lhs, rhs) ⇒ Object
142 143 144 145 146 147 148 149 |
# File 'lib/brakeman/processors/lib/find_return_value.rb', line 142 def make_or lhs, rhs #Better checks in future if lhs == rhs lhs else Sexp.new(:or, lhs, rhs) end end |
#make_return_value ⇒ Object
Turns the array of return values into an :or Sexp
152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/brakeman/processors/lib/find_return_value.rb', line 152 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) ⇒ Object
Process method (or, actually, any Sexp) for return value.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# 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, :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? ⇒ Boolean
23 24 25 |
# File 'lib/brakeman/processors/lib/find_return_value.rb', line 23 def uses_ivars? @uses_ivars end |