lib/brakeman/processors/alias_processor.rb in brakeman-2.6.3 vs lib/brakeman/processors/alias_processor.rb in brakeman-3.0.0
- old
+ new
@@ -349,10 +349,37 @@
raise "Unrecognized assignment: #{exp}"
end
exp
end
+ # Multiple/parallel assignment:
+ #
+ # x, y = z, w
+ def process_masgn exp
+ unless array? exp[1] and array? exp[2] and exp[1].length == exp[2].length
+ return process_default(exp)
+ end
+
+ vars = exp[1].dup
+ vals = exp[2].dup
+
+ vars.shift
+ vals.shift
+
+ # Call each assignment as if it is normal
+ vars.each_with_index do |var, i|
+ val = vals[i]
+ if val
+ assign = var.dup
+ assign.rhs = val
+ process assign
+ end
+ end
+
+ exp
+ end
+
#Merge values into hash when processing
#
# h.merge! :something => "value"
def process_hash_merge! hash, args
hash = hash.deep_clone
@@ -742,15 +769,41 @@
else
false
end
end
- #Return true if for x += blah or @x += blah
def self_assign? var, value
+ self_assign_var?(var, value) or self_assign_target?(var, value)
+ end
+
+ #Return true if for x += blah or @x += blah
+ def self_assign_var? var, value
call? value and
value.method == :+ and
node_type? value.target, :lvar, :ivar and
value.target.value == var
+ end
+
+ #Return true for x = x.blah
+ def self_assign_target? var, value
+ target = top_target(value)
+
+ if node_type? target, :lvar, :ivar
+ target = target.value
+ end
+
+ var == target
+ end
+
+ #Returns last non-nil target in a call chain
+ def top_target exp, last = nil
+ if call? exp
+ top_target exp.target, exp
+ elsif node_type? exp, :iter, :call_with_block
+ top_target exp.block_call, last
+ else
+ exp || last
+ end
end
def value_from_if exp
if block? exp.else_clause or block? exp.then_clause
#If either clause is more than a single expression, just use entire