Skip to content

Commit

Permalink
Merge pull request #1734 from presidentbeef/case_splat_safe
Browse files Browse the repository at this point in the history
Handle multiple values in case/when ...
  • Loading branch information
presidentbeef authored Oct 9, 2022
2 parents 25fb055 + 3e255d6 commit 61b7946
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
33 changes: 28 additions & 5 deletions lib/brakeman/processors/alias_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -970,11 +970,27 @@ def equality_check? exp
exp.method == :==
end

# Not a list of values
# when :example
def simple_when? exp
node_type? exp[1], :array and
not node_type? exp[1][1], :splat, :array and
(exp[1].length == 2 or
exp[1].all? { |e| e.is_a? Symbol or node_type? e, :lit, :str })
exp[1].length == 2 and # only one element in the array
not node_type? exp[1][1], :splat, :array
end

# A list of literal values
#
# when 1,2,3
#
# or
#
# when *[:a, :b]
def all_literals_when? exp
if array? exp[1] # pretty sure this is always true
all_literals? exp[1] or # simple list, not actually array
(splat_array? exp[1][1] and
all_literals? exp[1][1][1])
end
end

def process_case exp
Expand Down Expand Up @@ -1002,9 +1018,16 @@ def process_case exp
scope do
@branch_env = env.current

# Process the when value for matching
process_default e[1]

# set value of case var if possible
if case_value and simple_when? e
@branch_env[case_value] = e[1][1]
if case_value
if simple_when? e
@branch_env[case_value] = e[1][1]
elsif all_literals_when? e
@branch_env[case_value] = safe_literal(e.line + 1)
end
end

# when blocks aren't blocks, they are lists of expressions
Expand Down
32 changes: 32 additions & 0 deletions test/tests/alias_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,38 @@ def test_case_value_params
OUTPUT
end

def test_case_list
assert_output <<-INPUT, <<-OUTPUT
case y
when :a, :b, :c
something(y)
end
INPUT
case y
when :a, :b, :c
something(:BRAKEMAN_SAFE_LITERAL)
end
OUTPUT
end

def test_case_splat
assert_output <<-INPUT, <<-OUTPUT
x = [1, 2, 3]
case y
when *x
something(y)
end
INPUT
x = [1, 2, 3]
case y
when *[1, 2, 3]
something(:BRAKEMAN_SAFE_LITERAL)
end
OUTPUT
end

def test_less_copying_of_arrays_and_hashes
assert_output <<-'INPUT', <<-'OUTPUT'
x = {}
Expand Down

0 comments on commit 61b7946

Please # to comment.