Skip to content

Commit

Permalink
Set line numbers when joining array into a string
Browse files Browse the repository at this point in the history
Fixes #1579
  • Loading branch information
presidentbeef committed Apr 13, 2021
1 parent aef6253 commit d5cfa90
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
10 changes: 5 additions & 5 deletions lib/brakeman/processors/alias_processor.rb
Expand Up @@ -294,7 +294,7 @@ def process_call exp

# Painful conversion of Array#join into string interpolation
def process_array_join array, join_str
result = s()
result = s().line(array.line)

join_value = if string? join_str
join_str.value
Expand Down Expand Up @@ -332,11 +332,11 @@ def process_array_join array, join_str
result.unshift combined_first

# Have to fix up strings that follow interpolation
result.reduce(s(:dstr)) do |memo, e|
result.reduce(s(:dstr).line(array.line)) do |memo, e|
if string? e and node_type? memo.last, :evstr
e.value = "#{join_value}#{e.value}"
elsif join_value and node_type? memo.last, :evstr and node_type? e, :evstr
memo << s(:str, join_value)
memo << s(:str, join_value).line(e.line)
end

memo << e
Expand All @@ -347,9 +347,9 @@ def join_item item, join_value
if item.is_a? String
"#{item}#{join_value}"
elsif string? item or symbol? item or number? item
s(:str, "#{item.value}#{join_value}")
s(:str, "#{item.value}#{join_value}").line(item.line)
else
s(:evstr, item)
s(:evstr, item).line(item.line)
end
end

Expand Down
12 changes: 12 additions & 0 deletions test/tests/alias_processor.rb
Expand Up @@ -1151,6 +1151,18 @@ def test_array_join_lots_of_interp
INPUT
end

def test_array_join_line_numbers
# Test that line numbers are set for all parts of a joined string
original_sexp = RubyParser.new.parse "z = [x, 1].join(' ')"
processed_sexp = Brakeman::AliasProcessor.new.process_safely(original_sexp)

assert_equal s(:lasgn, :z, s(:dstr, "", s(:evstr, s(:call, nil, :x)), s(:str, " 1"))), processed_sexp
assert_equal 1, processed_sexp[2].line
assert_equal 1, processed_sexp[2][2].line
assert_equal 1, processed_sexp[2][2][1].line
assert_equal 1, processed_sexp[2][3].line
end

def test_ignore_freeze
assert_alias "blah", <<-INPUT
x = blah.freeze
Expand Down

0 comments on commit d5cfa90

Please sign in to comment.