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]