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