brakeman-lib 3.3.1 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ddc7e6cb65aa8838c73a8052245d17b188059c2
4
- data.tar.gz: 9e5e114ead150d6d8ac25cbe4d55f71ee4655f50
3
+ metadata.gz: 247e1f6cbd985e4c43a49652500d38319984d212
4
+ data.tar.gz: bb49ccd6dce05cab284eca01935d2368a7c976e3
5
5
  SHA512:
6
- metadata.gz: d0555c9ee1835ccd8446cc81c4eb0f970cd2ce8966bf7ca3e0d71c81d74ff595aeb116f49b785f40acb4f57095d3a3dfc934d0b5418a8c42c59546ef8cad1dd1
7
- data.tar.gz: 4d24f5a2e330ea82dc914175bb54e1a2db32bc7a41131e2fa7ea0facf9e6c6edf37588868a0f7e0257ad7589382b23599348ede3bca8e05a0154683050f2530f
6
+ metadata.gz: f213baa263336bc6589ae552d87d10fb498abefc4b1921b6a3056abd80716910a61a1c5cedae8c2ec5317f1bcb8fb391cc9832cd6ffbfe014d3dcd4de3bb00c6
7
+ data.tar.gz: 9b8b4242889b5c03f59c0dec5a21e98bef3dcbdfe3a05cf8f5ac8ae1a9c826f60418cc1b5b9ab3c5c823be3c616da9922fa4511a64a4b48bf149c1917114a418
data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ # 3.3.2
2
+
3
+ * Fix serious performance regression with global constant tracking
4
+
1
5
  # 3.3.1
2
6
 
3
7
  * Delay loading vendored gems and modifying load path
@@ -13,7 +13,7 @@ class Brakeman::CheckSecrets < Brakeman::BaseCheck
13
13
  @warned = Set.new
14
14
 
15
15
  @tracker.constants.each do |constant|
16
- name = constant.name.last
16
+ name = constant.name_array.last
17
17
  value = constant.value
18
18
 
19
19
  if string? value and not value.value.empty? and looks_like_secret? name
@@ -76,6 +76,7 @@ module Brakeman::Options
76
76
  opts.on "--faster", "Faster, but less accurate scan" do
77
77
  options[:ignore_ifs] = true
78
78
  options[:skip_libs] = true
79
+ options[:disable_constant_tracking] = true
79
80
  end
80
81
 
81
82
  opts.on "--ignore-model-output", "Consider model attributes XSS-safe" do
@@ -186,11 +186,11 @@ class Brakeman::Tracker
186
186
  end
187
187
 
188
188
  def add_constant name, value, context = nil
189
- @constants.add name, value, context
189
+ @constants.add name, value, context unless @options[:disable_constant_tracking]
190
190
  end
191
191
 
192
192
  def constant_lookup name
193
- @constants.get_literal name
193
+ @constants.get_literal name unless @options[:disable_constant_tracking]
194
194
  end
195
195
 
196
196
  def index_call_sites
@@ -2,11 +2,11 @@ require 'brakeman/processors/output_processor'
2
2
 
3
3
  module Brakeman
4
4
  class Constant
5
- attr_reader :name, :file
5
+ attr_reader :name, :name_array, :file, :value
6
6
 
7
7
  def initialize name, value = nil, context = nil
8
8
  set_name name, context
9
- @values = [ value ]
9
+ @value = value
10
10
  @context = context
11
11
 
12
12
  if @context
@@ -15,28 +15,28 @@ module Brakeman
15
15
  end
16
16
 
17
17
  def line
18
- if @values.first.is_a? Sexp
19
- @values.first.line
18
+ if @value.is_a? Sexp
19
+ @value.line
20
20
  end
21
21
  end
22
22
 
23
23
  def set_name name, context
24
- @name = Constants.constant_as_array(name)
24
+ @name = name
25
+ @name_array = Constants.constant_as_array(name)
25
26
  end
26
27
 
27
28
  def match? name
28
- @name.reverse.zip(name.reverse).reduce(true) { |m, a| a[1] ? a[0] == a[1] && m : m }
29
- end
30
-
31
- def value
32
- @values.reverse.reduce do |m, v|
33
- Sexp.new(:or, v, m)
34
- end
35
- end
36
-
37
- def add_value exp
38
- unless @values.include? exp
39
- @values << exp
29
+ if name == @name
30
+ return true
31
+ elsif name.is_a? Sexp and name.node_type == :const and name.value == @name
32
+ return true
33
+ elsif name.is_a? Symbol and name.value == @name
34
+ return true
35
+ elsif name.class == Array
36
+ name == @name_array or
37
+ @name_array.reverse.zip(name.reverse).reduce(true) { |m, a| a[1] ? a[0] == a[1] && m : m }
38
+ else
39
+ false
40
40
  end
41
41
  end
42
42
  end
@@ -45,7 +45,11 @@ module Brakeman
45
45
  include Brakeman::Util
46
46
 
47
47
  def initialize
48
- @constants = []
48
+ @constants = Hash.new { |h, k| h[k] = [] }
49
+ end
50
+
51
+ def size
52
+ @constants.length
49
53
  end
50
54
 
51
55
  def [] exp
@@ -60,41 +64,98 @@ module Brakeman
60
64
  end
61
65
 
62
66
  def find_constant exp
63
- name = Constants.constant_as_array(exp)
64
- @constants.find do |c|
65
- c.match? name
67
+ base_name = Constants.get_constant_base_name(exp)
68
+
69
+ if @constants.key? base_name
70
+ @constants[base_name].find do |c|
71
+ if c.match? exp
72
+ return c
73
+ end
74
+ end
75
+
76
+ name_array = Constants.constant_as_array(exp)
77
+
78
+ # Avoid losing info about dynamic constant values
79
+ return unless name_array.all? { |n| constant? n or n.is_a? Symbol }
80
+
81
+ @constants[base_name].find do |c|
82
+ if c.match? name_array
83
+ return c
84
+ end
85
+ end
66
86
  end
87
+
88
+ nil
67
89
  end
68
90
 
69
91
  def add name, value, context = nil
70
- if existing = self.find_constant(name)
71
- existing.add_value value
72
- else
73
- @constants << Constant.new(name, value, context)
92
+ if call? value and value.method == :freeze
93
+ value = value.target
74
94
  end
95
+
96
+ base_name = Constants.get_constant_base_name(name)
97
+ @constants[base_name] << Constant.new(name, value, context)
98
+ end
99
+
100
+ LITERALS = [:lit, :false, :str, :true, :array, :hash]
101
+ def literal? exp
102
+ exp.is_a? Sexp and LITERALS.include? exp.node_type
75
103
  end
76
104
 
77
105
  def get_literal name
78
- if x = self[name] and [:lit, :false, :str, :true, :array, :hash].include? x.node_type
106
+ if x = self[name] and literal? x
79
107
  x
80
108
  else
81
109
  nil
82
110
  end
83
111
  end
84
112
 
85
- def each &block
86
- @constants.each &block
113
+ def each
114
+ @constants.each do |name, values|
115
+ values.each do |constant|
116
+ yield constant
117
+ end
118
+ end
87
119
  end
88
120
 
89
121
  def self.constant_as_array exp
90
- get_constant_name(exp).split('::')
122
+ res = []
123
+ while exp
124
+ if exp.is_a? Sexp
125
+ case exp.node_type
126
+ when :const
127
+ res << exp.value
128
+ exp = nil
129
+ when :colon3
130
+ res << exp.value << :""
131
+ exp = nil
132
+ when :colon2
133
+ res << exp.last
134
+ exp = exp[1]
135
+ else
136
+ res << exp
137
+ exp = nil
138
+ end
139
+ else
140
+ res << exp
141
+ exp = nil
142
+ end
143
+ end
144
+
145
+ res.reverse!
146
+ res
91
147
  end
92
148
 
93
- def self.get_constant_name exp
94
- if exp.is_a? Sexp
95
- Brakeman::OutputProcessor.new.format(exp)
149
+ def self.get_constant_base_name exp
150
+ return exp unless exp.is_a? Sexp
151
+
152
+ case exp.node_type
153
+ when :const, :colon3
154
+ exp.value
155
+ when :colon2
156
+ exp.last
96
157
  else
97
- exp.to_s
158
+ exp
98
159
  end
99
160
  end
100
161
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "3.3.1"
2
+ Version = "3.3.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.1
4
+ version: 3.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Collins
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - brakeman-public_cert.pem
12
- date: 2016-06-02 00:00:00.000000000 Z
12
+ date: 2016-06-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-unit