brakeman 1.8.3 → 1.9.0.pre1

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.
Files changed (63) hide show
  1. data/README.md +3 -27
  2. data/lib/brakeman.rb +36 -38
  3. data/lib/brakeman/app_tree.rb +90 -0
  4. data/lib/brakeman/call_index.rb +5 -38
  5. data/lib/brakeman/checks.rb +11 -11
  6. data/lib/brakeman/checks/base_check.rb +53 -29
  7. data/lib/brakeman/checks/check_cross_site_scripting.rb +11 -9
  8. data/lib/brakeman/checks/check_evaluation.rb +1 -1
  9. data/lib/brakeman/checks/check_execute.rb +3 -3
  10. data/lib/brakeman/checks/check_link_to.rb +15 -13
  11. data/lib/brakeman/checks/check_link_to_href.rb +1 -1
  12. data/lib/brakeman/checks/check_mail_to.rb +1 -1
  13. data/lib/brakeman/checks/check_mass_assignment.rb +27 -13
  14. data/lib/brakeman/checks/check_redirect.rb +4 -4
  15. data/lib/brakeman/checks/check_select_tag.rb +1 -1
  16. data/lib/brakeman/checks/check_select_vulnerability.rb +1 -1
  17. data/lib/brakeman/checks/check_send.rb +2 -2
  18. data/lib/brakeman/checks/check_session_settings.rb +12 -5
  19. data/lib/brakeman/checks/check_single_quotes.rb +3 -3
  20. data/lib/brakeman/checks/check_skip_before_filter.rb +4 -3
  21. data/lib/brakeman/checks/check_sql.rb +30 -30
  22. data/lib/brakeman/checks/check_translate_bug.rb +11 -10
  23. data/lib/brakeman/checks/check_validation_regex.rb +36 -11
  24. data/lib/brakeman/checks/check_without_protection.rb +1 -1
  25. data/lib/brakeman/options.rb +6 -2
  26. data/lib/brakeman/processor.rb +6 -5
  27. data/lib/brakeman/processors/alias_processor.rb +153 -38
  28. data/lib/brakeman/processors/base_processor.rb +16 -21
  29. data/lib/brakeman/processors/controller_alias_processor.rb +24 -11
  30. data/lib/brakeman/processors/controller_processor.rb +25 -25
  31. data/lib/brakeman/processors/erb_template_processor.rb +6 -7
  32. data/lib/brakeman/processors/erubis_template_processor.rb +2 -3
  33. data/lib/brakeman/processors/gem_processor.rb +5 -4
  34. data/lib/brakeman/processors/haml_template_processor.rb +4 -6
  35. data/lib/brakeman/processors/lib/find_all_calls.rb +3 -3
  36. data/lib/brakeman/processors/lib/find_call.rb +2 -2
  37. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  38. data/lib/brakeman/processors/lib/processor_helper.rb +24 -2
  39. data/lib/brakeman/processors/lib/rails2_config_processor.rb +13 -14
  40. data/lib/brakeman/processors/lib/rails2_route_processor.rb +9 -4
  41. data/lib/brakeman/processors/lib/rails3_config_processor.rb +8 -8
  42. data/lib/brakeman/processors/lib/rails3_route_processor.rb +23 -21
  43. data/lib/brakeman/processors/lib/render_helper.rb +2 -2
  44. data/lib/brakeman/processors/library_processor.rb +2 -2
  45. data/lib/brakeman/processors/model_processor.rb +16 -12
  46. data/lib/brakeman/processors/output_processor.rb +2 -1
  47. data/lib/brakeman/processors/template_alias_processor.rb +12 -8
  48. data/lib/brakeman/report.rb +28 -14
  49. data/lib/brakeman/rescanner.rb +5 -5
  50. data/lib/brakeman/scanner.rb +56 -94
  51. data/lib/brakeman/templates/header.html.erb +7 -2
  52. data/lib/brakeman/tracker.rb +14 -4
  53. data/lib/brakeman/util.rb +38 -17
  54. data/lib/brakeman/version.rb +1 -1
  55. data/lib/brakeman/warning.rb +14 -6
  56. data/lib/ruby_parser/bm_sexp.rb +157 -57
  57. data/lib/ruby_parser/bm_sexp_processor.rb +1 -2
  58. metadata +26 -25
  59. data/lib/ruby_parser/ruby18_parser.rb +0 -5544
  60. data/lib/ruby_parser/ruby19_parser.rb +0 -5756
  61. data/lib/ruby_parser/ruby_lexer.rb +0 -1349
  62. data/lib/ruby_parser/ruby_parser.rb +0 -5
  63. data/lib/ruby_parser/ruby_parser_extras.rb +0 -1057
@@ -26,13 +26,18 @@
26
26
  <tr>
27
27
  <th>Application Path</th>
28
28
  <th>Rails Version</th>
29
- <th>Report Generation Time</th>
29
+ <th>Brakeman Version</th>
30
+ <th>Report Time</th>
30
31
  <th>Checks Performed</th>
31
32
  </tr>
32
33
  <tr>
33
34
  <td><%= File.expand_path tracker.options[:app_path] %></td>
34
35
  <td><%= rails_version %></td>
35
- <td><%= Time.now %></td>
36
+ <td><%= Brakeman::Version %>
37
+ <td>
38
+ <%= tracker.start_time %><br><br>
39
+ <%= tracker.duration %> seconds
40
+ </td>
36
41
  <td><%= checks.checks_run.sort.join(", ") %></td>
37
42
  </tr>
38
43
  </table>
@@ -9,7 +9,8 @@ require 'brakeman/processors/lib/find_all_calls'
9
9
  class Brakeman::Tracker
10
10
  attr_accessor :controllers, :templates, :models, :errors,
11
11
  :checks, :initializers, :config, :routes, :processor, :libs,
12
- :template_cache, :options, :filter_cache
12
+ :template_cache, :options, :filter_cache, :start_time, :end_time,
13
+ :duration
13
14
 
14
15
  #Place holder when there should be a model, but it is not
15
16
  #clear what model it will be.
@@ -19,9 +20,11 @@ class Brakeman::Tracker
19
20
  #
20
21
  #The Processor argument is only used by other Processors
21
22
  #that might need to access it.
22
- def initialize processor = nil, options = {}
23
+ def initialize(app_tree, processor = nil, options = {})
24
+ @app_tree = app_tree
23
25
  @processor = processor
24
26
  @options = options
27
+
25
28
  @config = {}
26
29
  @templates = {}
27
30
  @controllers = {}
@@ -44,6 +47,9 @@ class Brakeman::Tracker
44
47
  @template_cache = Set.new
45
48
  @filter_cache = {}
46
49
  @call_index = nil
50
+ @start_time = Time.now
51
+ @end_time = nil
52
+ @duration = nil
47
53
  end
48
54
 
49
55
  #Add an error to the list. If no backtrace is given,
@@ -63,7 +69,11 @@ class Brakeman::Tracker
63
69
  #Run a set of checks on the current information. Results will be stored
64
70
  #in Tracker#checks.
65
71
  def run_checks
66
- @checks = Brakeman::Checks.run_checks(self)
72
+ @checks = Brakeman::Checks.run_checks(@app_tree, self)
73
+
74
+ @end_time = Time.now
75
+ @duration = @end_time - @start_time
76
+ @checks
67
77
  end
68
78
 
69
79
  #Iterate over all methods in controllers and models.
@@ -139,7 +149,7 @@ class Brakeman::Tracker
139
149
 
140
150
  #Returns a Report with this Tracker's information
141
151
  def report
142
- Brakeman::Report.new(self)
152
+ Brakeman::Report.new(@app_tree, self)
143
153
  end
144
154
 
145
155
  def index_call_sites
data/lib/brakeman/util.rb CHANGED
@@ -4,21 +4,21 @@ require 'active_support/inflector'
4
4
  #This is a mixin containing utility methods.
5
5
  module Brakeman::Util
6
6
 
7
- QUERY_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :query_parameters, Sexp.new(:arglist))
7
+ QUERY_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request), :query_parameters)
8
8
 
9
- PATH_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :path_parameters, Sexp.new(:arglist))
9
+ PATH_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request), :path_parameters)
10
10
 
11
- REQUEST_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :request_parameters, Sexp.new(:arglist))
11
+ REQUEST_PARAMETERS = Sexp.new(:call, Sexp.new(:call, nil, :request), :request_parameters)
12
12
 
13
- REQUEST_PARAMS = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :parameters, Sexp.new(:arglist))
13
+ REQUEST_PARAMS = Sexp.new(:call, Sexp.new(:call, nil, :request), :parameters)
14
14
 
15
- REQUEST_ENV = Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :env, Sexp.new(:arglist))
15
+ REQUEST_ENV = Sexp.new(:call, Sexp.new(:call, nil, :request), :env)
16
16
 
17
- PARAMETERS = Sexp.new(:call, nil, :params, Sexp.new(:arglist))
17
+ PARAMETERS = Sexp.new(:call, nil, :params)
18
18
 
19
- COOKIES = Sexp.new(:call, nil, :cookies, Sexp.new(:arglist))
19
+ COOKIES = Sexp.new(:call, nil, :cookies)
20
20
 
21
- SESSION = Sexp.new(:call, nil, :session, Sexp.new(:arglist))
21
+ SESSION = Sexp.new(:call, nil, :session)
22
22
 
23
23
  ALL_PARAMETERS = Set[PARAMETERS, QUERY_PARAMETERS, PATH_PARAMETERS, REQUEST_PARAMETERS, REQUEST_PARAMS]
24
24
 
@@ -75,7 +75,7 @@ module Brakeman::Util
75
75
  end
76
76
  index += 2
77
77
  end
78
-
78
+
79
79
  hash << key << value
80
80
 
81
81
  hash
@@ -96,19 +96,24 @@ module Brakeman::Util
96
96
  nil
97
97
  end
98
98
 
99
+ #These are never modified
100
+ PARAMS_SEXP = Sexp.new(:params)
101
+ SESSION_SEXP = Sexp.new(:session)
102
+ COOKIES_SEXP = Sexp.new(:cookies)
103
+
99
104
  #Adds params, session, and cookies to environment
100
105
  #so they can be replaced by their respective Sexps.
101
106
  def set_env_defaults
102
- @env[PARAMETERS] = Sexp.new(:params)
103
- @env[SESSION] = Sexp.new(:session)
104
- @env[COOKIES] = Sexp.new(:cookies)
107
+ @env[PARAMETERS] = PARAMS_SEXP
108
+ @env[SESSION] = SESSION_SEXP
109
+ @env[COOKIES] = COOKIES_SEXP
105
110
  end
106
111
 
107
112
  #Check if _exp_ represents a hash: s(:hash, {...})
108
113
  #This also includes pseudo hashes params, session, and cookies.
109
114
  def hash? exp
110
- exp.is_a? Sexp and (exp.node_type == :hash or
111
- exp.node_type == :params or
115
+ exp.is_a? Sexp and (exp.node_type == :hash or
116
+ exp.node_type == :params or
112
117
  exp.node_type == :session or
113
118
  exp.node_type == :cookies)
114
119
  end
@@ -239,6 +244,22 @@ module Brakeman::Util
239
244
  false
240
245
  end
241
246
 
247
+ def make_call target, method, *args
248
+ call = Sexp.new(:call, target, method)
249
+
250
+ if args.empty? or args.first.empty?
251
+ #nothing to do
252
+ elsif node_type? args.first, :arglist
253
+ call.concat args.first[1..-1]
254
+ elsif args.first.node_type.is_a? Sexp #just a list of args
255
+ call.concat args.first
256
+ else
257
+ call.concat args
258
+ end
259
+
260
+ call
261
+ end
262
+
242
263
  #Return file name related to given warning. Uses +warning.file+ if it exists
243
264
  def file_for warning, tracker = nil
244
265
  if tracker.nil?
@@ -315,10 +336,10 @@ module Brakeman::Util
315
336
 
316
337
  #Return array of lines surrounding the warning location from the original
317
338
  #file.
318
- def context_for warning, tracker = nil
339
+ def context_for app_tree, warning, tracker = nil
319
340
  file = file_for warning, tracker
320
341
  context = []
321
- return context unless warning.line and file and File.exist? file
342
+ return context unless warning.line and file and @app_tree.path_exists? file
322
343
 
323
344
  current_line = 0
324
345
  start_line = warning.line - 5
@@ -369,5 +390,5 @@ module Brakeman::Util
369
390
  output << CSV.generate_line(row.cells.map{|cell| cell.to_s.strip})
370
391
  end
371
392
  output
372
- end
393
+ end
373
394
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "1.8.3"
2
+ Version = "1.9.0.pre1"
3
3
  end
@@ -76,14 +76,14 @@ class Brakeman::Warning
76
76
 
77
77
  #Return String of the code output from the OutputProcessor and
78
78
  #stripped of newlines and tabs.
79
- def format_code
80
- Brakeman::OutputProcessor.new.format(self.code).gsub(/(\t|\r|\n)+/, " ")
79
+ def format_code strip = true
80
+ format_ruby self.code, strip
81
81
  end
82
82
 
83
83
  #Return String of the user input formatted and
84
84
  #stripped of newlines and tabs.
85
- def format_user_input
86
- Brakeman::OutputProcessor.new.format(self.user_input).gsub(/(\t|\r|\n)+/, " ")
85
+ def format_user_input strip = true
86
+ format_ruby self.user_input, strip
87
87
  end
88
88
 
89
89
  #Return formatted warning message
@@ -171,9 +171,9 @@ class Brakeman::Warning
171
171
  :file => self.file,
172
172
  :line => self.line,
173
173
  :link => self.link,
174
- :code => (@code && self.format_code),
174
+ :code => (@code && self.format_code(false)),
175
175
  :location => location,
176
- :user_input => (@user_input && self.format_user_input),
176
+ :user_input => (@user_input && self.format_user_input(false)),
177
177
  :confidence => TEXT_CONFIDENCE[self.confidence]
178
178
  }
179
179
  end
@@ -181,4 +181,12 @@ class Brakeman::Warning
181
181
  def to_json
182
182
  MultiJson.dump self.to_hash
183
183
  end
184
+
185
+ private
186
+
187
+ def format_ruby code, strip
188
+ formatted = Brakeman::OutputProcessor.new.format(code)
189
+ formatted.gsub!(/(\t|\r|\n)+/, " ") if strip
190
+ formatted
191
+ end
184
192
  end
@@ -3,7 +3,7 @@
3
3
  #of a Sexp.
4
4
  class Sexp
5
5
  attr_reader :paren
6
- ASSIGNMENT_BOOL = [:gasgn, :iasgn, :lasgn, :cvdecl, :cdecl, :or, :and]
6
+ ASSIGNMENT_BOOL = [:gasgn, :iasgn, :lasgn, :cvdecl, :cdecl, :or, :and, :colon2]
7
7
 
8
8
  def method_missing name, *args
9
9
  #Brakeman does not use this functionality,
@@ -23,6 +23,12 @@ class Sexp
23
23
  last
24
24
  end
25
25
 
26
+ def value= exp
27
+ raise WrongSexpError, "Sexp#value= called on multi-item Sexp", caller[1..-1] if size > 2
28
+ @my_hash_value = nil
29
+ self[1] = exp
30
+ end
31
+
26
32
  def second
27
33
  self[1]
28
34
  end
@@ -35,26 +41,6 @@ class Sexp
35
41
  self[0] = type
36
42
  end
37
43
 
38
- #Don't use this, please.
39
- #:nodoc:
40
- def resbody delete = false
41
- #RubyParser and Ruby2Ruby rely on method_missing for this, but since we
42
- #don't want to use method_missing, here's a real method.
43
- find_node :resbody, delete
44
- end
45
-
46
- #Don't use this, please.
47
- #:nodoc:
48
- def lasgn delete = false
49
- find_node :lasgn, delete
50
- end
51
-
52
- #Don't use this, please.
53
- #:nodoc:
54
- def iasgn delete = false
55
- find_node :iasgn, delete
56
- end
57
-
58
44
  alias :node_type :sexp_type
59
45
  alias :values :sexp_body # TODO: retire
60
46
 
@@ -161,21 +147,34 @@ class Sexp
161
147
  #s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1)))
162
148
  # ^- method
163
149
  def method
164
- expect :call, :attrasgn, :super, :zsuper
150
+ expect :call, :attrasgn, :super, :zsuper, :result
165
151
 
166
152
  case self.node_type
167
153
  when :call, :attrasgn
168
154
  self[2]
169
155
  when :super, :zsuper
170
156
  :super
157
+ when :result
158
+ self.last
171
159
  end
172
160
  end
173
161
 
174
162
  #Sets the arglist in a method call.
175
163
  def arglist= exp
176
164
  expect :call, :attrasgn
177
- self[3] = exp
178
- #RP 3 TODO
165
+ start_index = 3
166
+
167
+ if exp.is_a? Sexp and exp.node_type == :arglist
168
+ exp = exp[1..-1]
169
+ end
170
+
171
+ exp.each_with_index do |e, i|
172
+ self[start_index + i] = e
173
+ end
174
+ end
175
+
176
+ def set_args *exp
177
+ self.arglist = exp
179
178
  end
180
179
 
181
180
  #Returns arglist for method call. This differs from Sexp#args, as Sexp#args
@@ -189,17 +188,14 @@ class Sexp
189
188
 
190
189
  case self.node_type
191
190
  when :call, :attrasgn
192
- self[3]
191
+ self[3..-1].unshift :arglist
193
192
  when :super, :zsuper
194
193
  if self[1]
195
- Sexp.new(:arglist).concat self[1..-1]
194
+ self[1..-1].unshift :arglist
196
195
  else
197
196
  Sexp.new(:arglist)
198
197
  end
199
198
  end
200
-
201
- #For new ruby_parser
202
- #Sexp.new(:arglist, *self[3..-1])
203
199
  end
204
200
 
205
201
  #Returns arguments of a method call. This will be an 'untyped' Sexp.
@@ -208,59 +204,93 @@ class Sexp
208
204
  # ^--------args--------^
209
205
  def args
210
206
  expect :call, :attrasgn, :super, :zsuper
211
- #For new ruby_parser
212
- #if self[3]
213
- # self[3..-1]
214
- #else
215
- # []
216
- #end
217
207
 
218
208
  case self.node_type
219
209
  when :call, :attrasgn
220
- #For old ruby_parser
221
210
  if self[3]
222
- self[3][1..-1]
211
+ self[3..-1]
223
212
  else
224
- []
213
+ Sexp.new
225
214
  end
226
215
  when :super, :zsuper
227
216
  if self[1]
228
217
  self[1..-1]
229
218
  else
230
- []
219
+ Sexp.new
220
+ end
221
+ end
222
+ end
223
+
224
+ def each_arg replace = false
225
+ expect :call, :attrasgn, :super, :zsuper
226
+ range = nil
227
+
228
+ case self.node_type
229
+ when :call, :attrasgn
230
+ if self[3]
231
+ range = (3...self.length)
232
+ end
233
+ when :super, :zsuper
234
+ if self[1]
235
+ range = (1...self.length)
236
+ end
237
+ end
238
+
239
+ if range
240
+ range.each do |i|
241
+ res = yield self[i]
242
+ self[i] = res if replace
231
243
  end
232
244
  end
245
+
246
+ self
247
+ end
248
+
249
+ def each_arg! &block
250
+ self.each_arg true, &block
233
251
  end
234
252
 
235
253
  #Returns first argument of a method call.
236
254
  def first_arg
237
255
  expect :call, :attrasgn
238
- if self[3]
239
- self[3][1]
240
- end
256
+ self[3]
241
257
  end
242
258
 
243
259
  #Sets first argument of a method call.
244
260
  def first_arg= exp
245
261
  expect :call, :attrasgn
246
- if self[3]
247
- self[3][1] = exp
248
- end
262
+ self[3] = exp
249
263
  end
250
264
 
251
265
  #Returns second argument of a method call.
252
266
  def second_arg
253
267
  expect :call, :attrasgn
254
- if self[3]
255
- self[3][2]
256
- end
268
+ self[4]
257
269
  end
258
270
 
259
271
  #Sets second argument of a method call.
260
272
  def second_arg= exp
261
273
  expect :call, :attrasgn
274
+ self[4] = exp
275
+ end
276
+
277
+ def third_arg
278
+ expect :call, :attrasgn
279
+ self[5]
280
+ end
281
+
282
+ def third_arg= exp
283
+ expect :call, :attrasgn
284
+ self[5] = exp
285
+ end
286
+
287
+ def last_arg
288
+ expect :call, :attrasgn
289
+
262
290
  if self[3]
263
- self[3][2] = exp
291
+ self[-1]
292
+ else
293
+ nil
264
294
  end
265
295
  end
266
296
 
@@ -317,7 +347,11 @@ class Sexp
317
347
  # s(:lasgn, :y),
318
348
  # s(:block, s(:lvar, :y), s(:call, nil, :z, s(:arglist))))
319
349
  # ^-------------------- block --------------------------^
320
- def block
350
+ def block delete = nil
351
+ unless delete.nil? #this is from RubyParser
352
+ return find_node :block, delete
353
+ end
354
+
321
355
  expect :iter, :call_with_block, :scope, :resbody
322
356
 
323
357
  case self.node_type
@@ -342,6 +376,11 @@ class Sexp
342
376
  self[2]
343
377
  end
344
378
 
379
+ def first_param
380
+ expect :args
381
+ self[1]
382
+ end
383
+
345
384
  #Returns the left hand side of assignment or boolean:
346
385
  #
347
386
  # s(:lasgn, :x, s(:lit, 1))
@@ -384,34 +423,61 @@ class Sexp
384
423
  end
385
424
  end
386
425
 
387
- #Sets body
426
+ def formal_args
427
+ expect :defn, :defs, :methdef, :selfdef
428
+
429
+ case self.node_type
430
+ when :defn, :methdef
431
+ self[2]
432
+ when :defs, :selfdef
433
+ self[3]
434
+ end
435
+ end
436
+
437
+ #Sets body, which is now a complicated process because the body is no longer
438
+ #a separate Sexp, but just a list of Sexps.
388
439
  def body= exp
389
440
  expect :defn, :defs, :methdef, :selfdef, :class, :module
390
441
 
391
442
  case self.node_type
392
443
  when :defn, :methdef, :class
393
- self[3] = exp
444
+ index = 3
394
445
  when :defs, :selfdef
395
- self[4] = exp
446
+ index = 4
396
447
  when :module
397
- self[2] = exp
448
+ index = 2
449
+ end
450
+
451
+ self.slice!(index..-1) #Remove old body
452
+
453
+ #Insert new body
454
+ exp.each do |e|
455
+ self[index] = e
456
+ index += 1
398
457
  end
399
458
  end
400
459
 
401
460
  #Returns body of a method definition, class, or module.
461
+ #This will be an untyped Sexp containing a list of Sexps from the body.
402
462
  def body
403
463
  expect :defn, :defs, :methdef, :selfdef, :class, :module
404
464
 
405
465
  case self.node_type
406
466
  when :defn, :methdef, :class
407
- self[3]
467
+ self[3..-1]
408
468
  when :defs, :selfdef
409
- self[4]
469
+ self[4..-1]
410
470
  when :module
411
- self[2]
471
+ self[2..-1]
412
472
  end
413
473
  end
414
474
 
475
+ #Like Sexp#body, except the returned Sexp is of type :rlist
476
+ #instead of untyped.
477
+ def body_list
478
+ self.body.unshift :rlist
479
+ end
480
+
415
481
  def render_type
416
482
  expect :render
417
483
  self[1]
@@ -428,6 +494,27 @@ class Sexp
428
494
  expect :class
429
495
  self[2]
430
496
  end
497
+
498
+ #Returns the call Sexp in a result returned from FindCall
499
+ def call
500
+ expect :result
501
+
502
+ self.last
503
+ end
504
+
505
+ #Returns the module the call is inside
506
+ def module
507
+ expect :result
508
+
509
+ self[1]
510
+ end
511
+
512
+ #Return the class the call is inside
513
+ def result_class
514
+ expect :result
515
+
516
+ self[2]
517
+ end
431
518
  end
432
519
 
433
520
  #Invalidate hash cache if the Sexp changes
@@ -445,4 +532,17 @@ end
445
532
  RUBY
446
533
  end
447
534
 
535
+ #Methods used by RubyParser which would normally go through method_missing but
536
+ #we don't want that to happen because it hides Brakeman errors
537
+ [:resbody, :lasgn, :iasgn, :splat].each do |method|
538
+ Sexp.class_eval <<-RUBY
539
+ def #{method} delete = false
540
+ if delete
541
+ @my_hash_value = false
542
+ end
543
+ find_node :#{method}, delete
544
+ end
545
+ RUBY
546
+ end
547
+
448
548
  class WrongSexpError < RuntimeError; end