Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set line numbers when joining array into a string #1581

Merged
merged 2 commits into from Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 10 additions & 10 deletions lib/brakeman/processors/alias_processor.rb
Expand Up @@ -201,11 +201,11 @@ def process_call exp
res = process_or_simple_operation(exp)
return res if res
elsif target == ARRAY_CONST and method == :new
return Sexp.new(:array, *exp.args)
return Sexp.new(:array, *exp.args).line(exp.line)
elsif target == HASH_CONST and method == :new and first_arg.nil? and !node_type?(@exp_context.last, :iter)
return Sexp.new(:hash)
return Sexp.new(:hash).line(exp.line)
elsif exp == RAILS_TEST or exp == RAILS_DEV
return Sexp.new(:false)
return Sexp.new(:false).line(exp.line)
end

#See if it is possible to simplify some basic cases
Expand Down Expand Up @@ -243,7 +243,7 @@ def process_call exp
env[target_var] = target
return target
elsif string? target and string_interp? first_arg
exp = Sexp.new(:dstr, target.value + first_arg[1]).concat(first_arg.sexp_body(2))
exp = Sexp.new(:dstr, target.value + first_arg[1]).concat(first_arg.sexp_body(2)).line(exp.line)
env[target_var] = exp
elsif string? first_arg and string_interp? target
if string? target.last
Expand Down 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 Expand Up @@ -690,7 +690,7 @@ def process_op_asgn1 exp
end
end
else
new_value = process s(:call, s(:call, target_var, :[], index), exp[3], value)
new_value = process s(:call, s(:call, target_var, :[], index), exp[3], value).line(exp.line)

env[match] = new_value
end
Expand Down
8 changes: 4 additions & 4 deletions lib/brakeman/processors/base_processor.rb
Expand Up @@ -8,7 +8,7 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
include Brakeman::SafeCallHelper
include Brakeman::Util

IGNORE = Sexp.new :ignore
IGNORE = Sexp.new(:ignore).line(0)

#Return a new Processor.
def initialize tracker
Expand Down Expand Up @@ -216,7 +216,7 @@ def make_render exp, in_view = false
#
#And also :layout for inside templates
def find_render_type call, in_view = false
rest = Sexp.new(:hash)
rest = Sexp.new(:hash).line(call.line)
type = nil
value = nil
first_arg = call.first_arg
Expand All @@ -236,7 +236,7 @@ def find_render_type call, in_view = false
end
elsif first_arg.is_a? Symbol or first_arg.is_a? String
type = :action
value = Sexp.new(:lit, first_arg.to_sym)
value = Sexp.new(:lit, first_arg.to_sym).line(call.line)
elsif first_arg.nil?
type = :default
elsif not hash? first_arg
Expand Down Expand Up @@ -293,6 +293,6 @@ def make_inline_render value, options
@tracker.processor.process_template(template_name, ast, type, nil, @current_file)
@tracker.processor.process_template_alias(@tracker.templates[template_name])

return s(:lit, template_name), options
return s(:lit, template_name).line(value.line), options
end
end
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