lib/brakeman/processors/alias_processor.rb in brakeman-5.4.0 vs lib/brakeman/processors/alias_processor.rb in brakeman-5.4.1

- old
+ new

@@ -298,18 +298,14 @@ end when :first if array? target and first_arg.nil? and sexp? target[1] exp = target[1] end - when :freeze + when :freeze, :dup, :presence unless target.nil? exp = target end - when :dup - unless target.nil? - exp = target - end when :join if array? target and (string? first_arg or first_arg.nil?) exp = process_array_join(target, first_arg) end when :! @@ -330,10 +326,21 @@ # are present in the hash. unless res.any?(&:nil?) exp = res end end + when :presence_in + arg = exp.first_arg + + if node_type? arg, :array + # 1.presence_in [1,2,3] + if arg.include? target + exp = target + elsif all_literals? arg + exp = safe_literal(exp.line) + end + end end exp end @@ -860,10 +867,21 @@ [:detect, :find].include? exp.method and exp.first_arg.nil? and (all_literals? exp.target or dir_glob? exp.target) end + # Check if exp is a call to Array#include? on an array literal + # that contains all literal values. For example: + # + # x.in? [1, 2, "a"] + # + def in_array_all_literals? exp + call? exp and + exp.method == :in? and + all_literals? exp.first_arg + end + # Check if exp is a call to Hash#include? on a hash literal # that contains all literal values. For example: # # {x: 1}.include? x def hash_include_all_literals? exp @@ -913,32 +931,34 @@ branch_scopes = [] exps.each_with_index do |branch, i| scope do @branch_env = env.current branch_index = 2 + i # s(:if, condition, then_branch, else_branch) - if i == 0 and hash_or_array_include_all_literals? condition + exp[branch_index] = if i == 0 and hash_or_array_include_all_literals? condition # If the condition is ["a", "b"].include? x - # set x to "a" inside the true branch + # set x to safe_literal inside the true branch var = condition.first_arg - previous_value = env.current[var] - env.current[var] = safe_literal(var.line) - exp[branch_index] = process_if_branch branch - env.current[var] = previous_value + value = safe_literal(var.line) + process_branch_with_value(var, value, branch, i) + elsif i == 0 and in_array_all_literals? condition + # If the condition is x.in? ["a", "b"] + # set x to safe_literal inside the true branch + var = condition.target + value = safe_literal(var.line) + process_branch_with_value(var, value, branch, i) elsif i == 0 and equality_check? condition # For conditions like a == b, # set a to b inside the true branch var = condition.target - previous_value = env.current[var] - env.current[var] = condition.first_arg - exp[branch_index] = process_if_branch branch - env.current[var] = previous_value + value = condition.first_arg + process_branch_with_value(var, value, branch, i) elsif i == 1 and hash_or_array_include_all_literals? condition and early_return? branch var = condition.first_arg env.current[var] = safe_literal(var.line) - exp[branch_index] = process_if_branch branch + process_if_branch branch else - exp[branch_index] = process_if_branch branch + process_if_branch branch end branch_scopes << env.current @branch_env = nil end end @@ -951,10 +971,18 @@ end exp end + def process_branch_with_value var, value, branch, branch_index + previous_value = env.current[var] + env.current[var] = value + result = process_if_branch branch + env.current[var] = previous_value + result + end + def early_return? exp return true if node_type? exp, :return return true if call? exp and [:fail, :raise].include? exp.method if node_type? exp, :block, :rlist @@ -1014,13 +1042,16 @@ end exp.each_sexp do |e| if node_type? e, :when scope do - @branch_env = env.current - # Process the when value for matching process_default e[1] + + # Moved here to avoid @branch_env being cleared out + # in process_default + # Maybe in the future don't set it to nil? + @branch_env = env.current # set value of case var if possible if case_value if simple_when? e @branch_env[case_value] = e[1][1]