lib/brakeman/processors/alias_processor.rb in brakeman-1.0.0 vs lib/brakeman/processors/alias_processor.rb in brakeman-1.1.pre
- old
+ new
@@ -23,10 +23,13 @@
self.auto_shift_type = false
self.require_empty = false
self.default_method = :process_default
self.warn_on_default = false
@env = SexpProcessor::Environment.new
+ @inside_if = false
+ @ignore_ifs = false
+ @tracker = nil #set in subclass as necessary
set_env_defaults
end
#This method processes the given Sexp, but copies it first so
#the original argument will not be modified.
@@ -115,11 +118,25 @@
exp = joined
elsif string? target and string? args[1]
joined = join_strings target, args[1]
joined.line(exp.line)
exp = joined
+ elsif number? target and number? args[1]
+ exp = Sexp.new(:lit, target[1] + args[1][1])
end
+ when :-
+ if number? target and number? args[1]
+ exp = Sexp.new(:lit, target[1] - args[1][1])
+ end
+ when :*
+ if number? target and number? args[1]
+ exp = Sexp.new(:lit, target[1] * args[1][1])
+ end
+ when :/
+ if number? target and number? args[1]
+ exp = Sexp.new(:lit, target[1] / args[1][1])
+ end
when :[]
if array? target
temp_exp = process_array_access target, args[1..-1]
exp = temp_exp if temp_exp
elsif hash? target
@@ -134,10 +151,23 @@
end
when :merge
if hash? target and hash? args[1]
return process_hash_merge(target, args[1])
end
+ when :<<
+ if string? target and string? args[1]
+ target[1] << args[1][1]
+ env[target_var] = target
+ return target
+ elsif array? target
+ target << args[1]
+ env[target_var] = target
+ return target
+ else
+ target = find_push_target exp
+ env[target] = exp unless target.nil? #Happens in TemplateAliasProcessor
+ end
end
exp
end
@@ -181,12 +211,14 @@
# x = 1
def process_lasgn exp
exp[2] = process exp[2] if sexp? exp[2]
local = Sexp.new(:lvar, exp[1]).line(exp.line || -2)
- if @inside_if and env[local]
- env[local] = Sexp.new(:or, env[local], exp[2]).line(exp.line || -2)
+ if @inside_if and val = env[local]
+ if val != exp[2] #avoid setting to value it already is (e.g. "1 or 1")
+ env[local] = Sexp.new(:or, val, exp[2]).line(exp.line || -2)
+ end
else
env[local] = exp[2]
end
exp
@@ -196,12 +228,14 @@
# @x = 1
def process_iasgn exp
exp[2] = process exp[2]
ivar = Sexp.new(:ivar, exp[1]).line(exp.line)
- if @inside_if and env[ivar]
- env[ivar] = Sexp.new(:or, env[ivar], exp[2]).line(exp.line)
+ if @inside_if and val = env[ivar]
+ if val != exp[2]
+ env[ivar] = Sexp.new(:or, val, exp[2]).line(exp.line)
+ end
else
env[ivar] = exp[2]
end
exp
@@ -211,12 +245,14 @@
# $x = 1
def process_gasgn exp
match = Sexp.new(:gvar, exp[1])
value = exp[2] = process(exp[2])
- if @inside_if and env[match]
- env[match] = Sexp.new(:or, env[match], value)
+ if @inside_if and val = env[match]
+ if val != value
+ env[match] = Sexp.new(:or, env[match], value)
+ end
else
env[match] = value
end
exp
@@ -226,12 +262,14 @@
# @@x = 1
def process_cvdecl exp
match = Sexp.new(:cvar, exp[1])
value = exp[2] = process(exp[2])
- if @inside_if and env[match]
- env[match] = Sexp.new(:or, env[match], value)
+ if @inside_if and val = env[match]
+ if val != value
+ env[match] = Sexp.new(:or, env[match], value)
+ end
else
env[match] = value
end
exp
@@ -257,12 +295,14 @@
elsif method.to_s[-1,1] == "="
value = exp[3][1] = process(exp[3][1])
#This is what we'll replace with the value
match = Sexp.new(:call, target, method.to_s[0..-2].to_sym, Sexp.new(:arglist))
- if @inside_if and env[match]
- env[match] = Sexp.new(:or, env[match], value)
+ if @inside_if and val = env[match]
+ if val != value
+ env[match] = Sexp.new(:or, env[match], value)
+ end
else
env[match] = value
end
else
raise "Unrecognized assignment: #{exp}"
@@ -347,12 +387,11 @@
exp
end
#Sets @inside_if = true
def process_if exp
- was_inside = @inside_if
- @inside_if = true
+ @ignore_ifs ||= @tracker && @tracker.options[:ignore_ifs]
condition = process exp[1]
if true? condition
exps = [exp[2]]
@@ -360,10 +399,13 @@
exps = exp[3..-1]
else
exps = exp[2..-1]
end
+ was_inside = @inside_if
+ @inside_if = !@ignore_ifs
+
exps.each do |e|
process e if sexp? e
end
@inside_if = was_inside
@@ -433,7 +475,16 @@
set_line e, line_number
end
end
exp
+ end
+
+ #Finds the inner most call target which is not the target of a call to <<
+ def find_push_target exp
+ if call? exp and exp[2] == :<<
+ find_push_target exp[1]
+ else
+ exp
+ end
end
end