brakeman-min 0.5.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/CHANGES +529 -0
  2. data/README.md +74 -28
  3. data/bin/brakeman +60 -266
  4. data/lib/brakeman.rb +422 -0
  5. data/lib/brakeman/app_tree.rb +101 -0
  6. data/lib/brakeman/brakeman.rake +10 -0
  7. data/lib/brakeman/call_index.rb +215 -0
  8. data/lib/brakeman/checks.rb +180 -0
  9. data/lib/brakeman/checks/base_check.rb +538 -0
  10. data/lib/brakeman/checks/check_basic_auth.rb +89 -0
  11. data/lib/brakeman/checks/check_content_tag.rb +162 -0
  12. data/lib/brakeman/checks/check_cross_site_scripting.rb +334 -0
  13. data/lib/{checks → brakeman/checks}/check_default_routes.rb +13 -6
  14. data/lib/brakeman/checks/check_deserialize.rb +57 -0
  15. data/lib/brakeman/checks/check_digest_dos.rb +38 -0
  16. data/lib/brakeman/checks/check_escape_function.rb +21 -0
  17. data/lib/brakeman/checks/check_evaluation.rb +33 -0
  18. data/lib/brakeman/checks/check_execute.rb +98 -0
  19. data/lib/brakeman/checks/check_file_access.rb +62 -0
  20. data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
  21. data/lib/brakeman/checks/check_forgery_setting.rb +54 -0
  22. data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
  23. data/lib/brakeman/checks/check_json_parsing.rb +102 -0
  24. data/lib/brakeman/checks/check_link_to.rb +132 -0
  25. data/lib/brakeman/checks/check_link_to_href.rb +92 -0
  26. data/lib/{checks → brakeman/checks}/check_mail_to.rb +14 -13
  27. data/lib/brakeman/checks/check_mass_assignment.rb +143 -0
  28. data/lib/brakeman/checks/check_model_attr_accessible.rb +48 -0
  29. data/lib/brakeman/checks/check_model_attributes.rb +118 -0
  30. data/lib/brakeman/checks/check_model_serialize.rb +66 -0
  31. data/lib/{checks → brakeman/checks}/check_nested_attributes.rb +10 -6
  32. data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
  33. data/lib/brakeman/checks/check_redirect.rb +177 -0
  34. data/lib/brakeman/checks/check_render.rb +62 -0
  35. data/lib/brakeman/checks/check_response_splitting.rb +21 -0
  36. data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
  37. data/lib/brakeman/checks/check_sanitize_methods.rb +54 -0
  38. data/lib/brakeman/checks/check_select_tag.rb +60 -0
  39. data/lib/brakeman/checks/check_select_vulnerability.rb +58 -0
  40. data/lib/brakeman/checks/check_send.rb +35 -0
  41. data/lib/brakeman/checks/check_send_file.rb +19 -0
  42. data/lib/brakeman/checks/check_session_settings.rb +145 -0
  43. data/lib/brakeman/checks/check_single_quotes.rb +101 -0
  44. data/lib/brakeman/checks/check_skip_before_filter.rb +62 -0
  45. data/lib/brakeman/checks/check_sql.rb +577 -0
  46. data/lib/brakeman/checks/check_strip_tags.rb +64 -0
  47. data/lib/brakeman/checks/check_symbol_dos.rb +67 -0
  48. data/lib/brakeman/checks/check_translate_bug.rb +45 -0
  49. data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
  50. data/lib/brakeman/checks/check_validation_regex.rb +88 -0
  51. data/lib/brakeman/checks/check_without_protection.rb +64 -0
  52. data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
  53. data/lib/brakeman/differ.rb +66 -0
  54. data/lib/{format → brakeman/format}/style.css +28 -0
  55. data/lib/brakeman/options.rb +256 -0
  56. data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
  57. data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
  58. data/lib/{scanner_erubis.rb → brakeman/parsers/rails3_erubis.rb} +8 -21
  59. data/lib/brakeman/processor.rb +102 -0
  60. data/lib/brakeman/processors/alias_processor.rb +780 -0
  61. data/lib/{processors → brakeman/processors}/base_processor.rb +90 -74
  62. data/lib/brakeman/processors/config_processor.rb +14 -0
  63. data/lib/brakeman/processors/controller_alias_processor.rb +334 -0
  64. data/lib/brakeman/processors/controller_processor.rb +265 -0
  65. data/lib/{processors → brakeman/processors}/erb_template_processor.rb +21 -19
  66. data/lib/brakeman/processors/erubis_template_processor.rb +96 -0
  67. data/lib/brakeman/processors/gem_processor.rb +59 -0
  68. data/lib/{processors → brakeman/processors}/haml_template_processor.rb +26 -21
  69. data/lib/brakeman/processors/lib/find_all_calls.rb +185 -0
  70. data/lib/{processors → brakeman/processors}/lib/find_call.rb +23 -28
  71. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  72. data/lib/brakeman/processors/lib/processor_helper.rb +82 -0
  73. data/lib/{processors/config_processor.rb → brakeman/processors/lib/rails2_config_processor.rb} +32 -35
  74. data/lib/{processors → brakeman/processors}/lib/rails2_route_processor.rb +60 -52
  75. data/lib/brakeman/processors/lib/rails3_config_processor.rb +129 -0
  76. data/lib/brakeman/processors/lib/rails3_route_processor.rb +282 -0
  77. data/lib/{processors → brakeman/processors}/lib/render_helper.rb +54 -20
  78. data/lib/brakeman/processors/lib/route_helper.rb +62 -0
  79. data/lib/{processors → brakeman/processors}/library_processor.rb +24 -17
  80. data/lib/{processors → brakeman/processors}/model_processor.rb +46 -22
  81. data/lib/{processors → brakeman/processors}/output_processor.rb +34 -40
  82. data/lib/brakeman/processors/route_processor.rb +17 -0
  83. data/lib/brakeman/processors/slim_template_processor.rb +113 -0
  84. data/lib/brakeman/processors/template_alias_processor.rb +120 -0
  85. data/lib/{processors → brakeman/processors}/template_processor.rb +10 -7
  86. data/lib/brakeman/report.rb +68 -0
  87. data/lib/brakeman/report/ignore/config.rb +130 -0
  88. data/lib/brakeman/report/ignore/interactive.rb +311 -0
  89. data/lib/brakeman/report/initializers/faster_csv.rb +7 -0
  90. data/lib/brakeman/report/initializers/multi_json.rb +29 -0
  91. data/lib/brakeman/report/renderer.rb +24 -0
  92. data/lib/brakeman/report/report_base.rb +279 -0
  93. data/lib/brakeman/report/report_csv.rb +56 -0
  94. data/lib/brakeman/report/report_hash.rb +22 -0
  95. data/lib/brakeman/report/report_html.rb +203 -0
  96. data/lib/brakeman/report/report_json.rb +46 -0
  97. data/lib/brakeman/report/report_table.rb +109 -0
  98. data/lib/brakeman/report/report_tabs.rb +17 -0
  99. data/lib/brakeman/report/templates/controller_overview.html.erb +18 -0
  100. data/lib/brakeman/report/templates/controller_warnings.html.erb +17 -0
  101. data/lib/brakeman/report/templates/error_overview.html.erb +25 -0
  102. data/lib/brakeman/report/templates/header.html.erb +44 -0
  103. data/lib/brakeman/report/templates/ignored_warnings.html.erb +21 -0
  104. data/lib/brakeman/report/templates/model_warnings.html.erb +17 -0
  105. data/lib/brakeman/report/templates/overview.html.erb +34 -0
  106. data/lib/brakeman/report/templates/security_warnings.html.erb +19 -0
  107. data/lib/brakeman/report/templates/template_overview.html.erb +17 -0
  108. data/lib/brakeman/report/templates/view_warnings.html.erb +30 -0
  109. data/lib/brakeman/report/templates/warning_overview.html.erb +13 -0
  110. data/lib/brakeman/rescanner.rb +446 -0
  111. data/lib/brakeman/scanner.rb +362 -0
  112. data/lib/brakeman/tracker.rb +296 -0
  113. data/lib/brakeman/util.rb +413 -0
  114. data/lib/brakeman/version.rb +3 -0
  115. data/lib/brakeman/warning.rb +217 -0
  116. data/lib/brakeman/warning_codes.rb +68 -0
  117. data/lib/ruby_parser/bm_sexp.rb +562 -0
  118. data/lib/ruby_parser/bm_sexp_processor.rb +230 -0
  119. metadata +152 -66
  120. data/lib/checks.rb +0 -71
  121. data/lib/checks/base_check.rb +0 -357
  122. data/lib/checks/check_cross_site_scripting.rb +0 -336
  123. data/lib/checks/check_evaluation.rb +0 -27
  124. data/lib/checks/check_execute.rb +0 -110
  125. data/lib/checks/check_file_access.rb +0 -46
  126. data/lib/checks/check_forgery_setting.rb +0 -42
  127. data/lib/checks/check_mass_assignment.rb +0 -74
  128. data/lib/checks/check_model_attributes.rb +0 -36
  129. data/lib/checks/check_redirect.rb +0 -98
  130. data/lib/checks/check_render.rb +0 -65
  131. data/lib/checks/check_send_file.rb +0 -15
  132. data/lib/checks/check_session_settings.rb +0 -79
  133. data/lib/checks/check_sql.rb +0 -146
  134. data/lib/checks/check_validation_regex.rb +0 -60
  135. data/lib/processor.rb +0 -86
  136. data/lib/processors/alias_processor.rb +0 -384
  137. data/lib/processors/controller_alias_processor.rb +0 -237
  138. data/lib/processors/controller_processor.rb +0 -202
  139. data/lib/processors/erubis_template_processor.rb +0 -85
  140. data/lib/processors/lib/find_model_call.rb +0 -39
  141. data/lib/processors/lib/processor_helper.rb +0 -36
  142. data/lib/processors/lib/rails3_route_processor.rb +0 -184
  143. data/lib/processors/lib/route_helper.rb +0 -34
  144. data/lib/processors/params_processor.rb +0 -77
  145. data/lib/processors/route_processor.rb +0 -11
  146. data/lib/processors/template_alias_processor.rb +0 -86
  147. data/lib/report.rb +0 -680
  148. data/lib/scanner.rb +0 -227
  149. data/lib/tracker.rb +0 -144
  150. data/lib/util.rb +0 -141
  151. data/lib/version.rb +0 -1
  152. data/lib/warning.rb +0 -99
@@ -0,0 +1,134 @@
1
+ require 'brakeman/processors/alias_processor'
2
+
3
+ #Attempts to determine the return value of a method.
4
+ #
5
+ #Preferred usage:
6
+ #
7
+ # Brakeman::FindReturnValue.return_value exp
8
+ class Brakeman::FindReturnValue
9
+ include Brakeman::Util
10
+
11
+ #Returns a guess at the return value of a given method or other block of code.
12
+ #
13
+ #If multiple return values are possible, returns all values in an :or Sexp.
14
+ def self.return_value exp, env = nil
15
+ self.new.get_return_value exp, env
16
+ end
17
+
18
+ def initialize
19
+ @uses_ivars = false
20
+ @return_values = []
21
+ end
22
+
23
+ def uses_ivars?
24
+ @uses_ivars
25
+ end
26
+
27
+ #Find return value of Sexp. Takes an optional starting environment.
28
+ def get_return_value exp, env = nil
29
+ process_method exp, env
30
+ value = make_return_value
31
+ value.original_line = exp.line
32
+ value
33
+ end
34
+
35
+ #Process method (or, actually, any Sexp) for return value.
36
+ def process_method exp, env = nil
37
+ exp = Brakeman::AliasProcessor.new.process_safely exp, env
38
+
39
+ find_explicit_return_values exp
40
+
41
+ if node_type? exp, :methdef, :selfdef, :defn, :defs
42
+ body = exp.body
43
+
44
+ unless body.empty?
45
+ @return_values << last_value(body)
46
+ else
47
+ Brakeman.debug "FindReturnValue: Empty method? #{exp.inspect}"
48
+ end
49
+ elsif exp
50
+ @return_values << last_value(exp)
51
+ else
52
+ Brakeman.debug "FindReturnValue: Given something strange? #{exp.inspect}"
53
+ end
54
+
55
+ exp
56
+ end
57
+
58
+ #Searches expression for return statements.
59
+ def find_explicit_return_values exp
60
+ todo = [exp]
61
+
62
+ until todo.empty?
63
+ current = todo.shift
64
+
65
+ @uses_ivars = true if node_type? current, :ivar
66
+
67
+ if node_type? current, :return
68
+ @return_values << current.value unless current.value.nil?
69
+ elsif sexp? current
70
+ todo = current[1..-1].concat todo
71
+ end
72
+ end
73
+ end
74
+
75
+ #Determines the "last value" of an expression.
76
+ def last_value exp
77
+ case exp.node_type
78
+ when :rlist, :block, :scope, Sexp
79
+ last_value exp.last
80
+ when :if
81
+ then_clause = exp.then_clause
82
+ else_clause = exp.else_clause
83
+
84
+ if then_clause.nil?
85
+ last_value else_clause
86
+ elsif else_clause.nil?
87
+ last_value then_clause
88
+ else
89
+ true_branch = last_value then_clause
90
+ false_branch = last_value else_clause
91
+
92
+ if true_branch and false_branch
93
+ value = make_or(true_branch, false_branch)
94
+ value.original_line = value.rhs.line
95
+ value
96
+ else #Unlikely?
97
+ true_branch or false_branch
98
+ end
99
+ end
100
+ when :lasgn, :iasgn
101
+ exp.rhs
102
+ when :return
103
+ exp.value
104
+ else
105
+ exp.original_line = exp.line unless exp.original_line
106
+ exp
107
+ end
108
+ end
109
+
110
+ def make_or lhs, rhs
111
+ #Better checks in future
112
+ if lhs == rhs
113
+ lhs
114
+ else
115
+ Sexp.new(:or, lhs, rhs)
116
+ end
117
+ end
118
+
119
+ #Turns the array of return values into an :or Sexp
120
+ def make_return_value
121
+ @return_values.compact!
122
+ @return_values.uniq!
123
+
124
+ if @return_values.empty?
125
+ Sexp.new(:nil)
126
+ elsif @return_values.length == 1
127
+ @return_values.first
128
+ else
129
+ @return_values.reduce do |value, sexp|
130
+ make_or value, sexp
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,82 @@
1
+ #Contains a couple shared methods for Processors.
2
+ module Brakeman::ProcessorHelper
3
+ def process_all exp
4
+ exp.each_sexp do |e|
5
+ process e
6
+ end
7
+ exp
8
+ end
9
+
10
+ def process_all! exp
11
+ exp.map! do |e|
12
+ if sexp? e
13
+ process e
14
+ else
15
+ e
16
+ end
17
+ end
18
+
19
+ exp
20
+ end
21
+
22
+ #Process the arguments of a method call. Does not store results.
23
+ #
24
+ #This method is used because Sexp#args and Sexp#arglist create new objects.
25
+ def process_call_args exp
26
+ exp.each_arg do |a|
27
+ process a if sexp? a
28
+ end
29
+
30
+ exp
31
+ end
32
+ #Sets the current module.
33
+ def process_module exp
34
+ module_name = class_name(exp.class_name).to_s
35
+ prev_module = @current_module
36
+
37
+ if prev_module
38
+ @current_module = "#{prev_module}::#{module_name}"
39
+ else
40
+ @current_module = module_name
41
+ end
42
+
43
+ if block_given?
44
+ yield
45
+ else
46
+ process_all exp.body
47
+ end
48
+
49
+ @current_module = prev_module
50
+
51
+ exp
52
+ end
53
+
54
+ #Returns a class name as a Symbol.
55
+ def class_name exp
56
+ case exp
57
+ when Sexp
58
+ case exp.node_type
59
+ when :const
60
+ exp.value
61
+ when :lvar
62
+ exp.value.to_sym
63
+ when :colon2
64
+ "#{class_name(exp.lhs)}::#{exp.rhs}".to_sym
65
+ when :colon3
66
+ "::#{exp.value}".to_sym
67
+ when :call
68
+ process exp
69
+ when :self
70
+ @current_class || @current_module || nil
71
+ else
72
+ raise "Error: Cannot get class name from #{exp}"
73
+ end
74
+ when Symbol
75
+ exp
76
+ when nil
77
+ nil
78
+ else
79
+ raise "Error: Cannot get class name from #{exp}"
80
+ end
81
+ end
82
+ end
@@ -1,13 +1,3 @@
1
- require 'processors/base_processor'
2
- require 'processors/alias_processor'
3
-
4
- #Replace block variable in
5
- #
6
- # Rails::Initializer.run |config|
7
- #
8
- #with this value so we can keep track of it.
9
- RAILS_CONFIG = Sexp.new(:const, :"!BRAKEMAN_RAILS_CONFIG")
10
-
11
1
  #Processes configuration. Results are put in tracker.config.
12
2
  #
13
3
  #Configuration of Rails via Rails::Initializer are stored in tracker.config[:rails].
@@ -22,7 +12,14 @@ RAILS_CONFIG = Sexp.new(:const, :"!BRAKEMAN_RAILS_CONFIG")
22
12
  # tracker.config[:rails][:action_controller][:session_store]
23
13
  #
24
14
  #Values for tracker.config[:rails] will still be Sexps.
25
- class ConfigProcessor < BaseProcessor
15
+ class Brakeman::Rails2ConfigProcessor < Brakeman::BaseProcessor
16
+ #Replace block variable in
17
+ #
18
+ # Rails::Initializer.run |config|
19
+ #
20
+ #with this value so we can keep track of it.
21
+ RAILS_CONFIG = Sexp.new(:const, :"!BRAKEMAN_RAILS_CONFIG")
22
+
26
23
  def initialize *args
27
24
  super
28
25
  @tracker.config[:rails] ||= {}
@@ -30,17 +27,17 @@ class ConfigProcessor < BaseProcessor
30
27
 
31
28
  #Use this method to process configuration file
32
29
  def process_config src
33
- res = ConfigAliasProcessor.new.process_safely(src)
30
+ res = Brakeman::ConfigAliasProcessor.new.process_safely(src)
34
31
  process res
35
32
  end
36
33
 
37
34
  #Check if config is set to use Erubis
38
35
  def process_call exp
39
- target = exp[1]
36
+ target = exp.target
40
37
  target = process target if sexp? target
41
38
 
42
- if exp[2] == :gem and exp[3][1][1] == "erubis"
43
- warn "[Notice] Using Erubis for ERB templates"
39
+ if exp.method == :gem and exp.first_arg.value == "erubis"
40
+ Brakeman.notify "[Notice] Using Erubis for ERB templates"
44
41
  @tracker.config[:erubis] = true
45
42
  end
46
43
 
@@ -49,14 +46,14 @@ class ConfigProcessor < BaseProcessor
49
46
 
50
47
  #Look for configuration settings
51
48
  def process_attrasgn exp
52
- if exp[1] == RAILS_CONFIG
49
+ if exp.target == RAILS_CONFIG
53
50
  #Get rid of '=' at end
54
- attribute = exp[2].to_s[0..-2].to_sym
55
- if exp[3].length > 2
51
+ attribute = exp.method.to_s[0..-2].to_sym
52
+ if exp.args.length > 1
56
53
  #Multiple arguments?...not sure if this will ever happen
57
- @tracker.config[:rails][exp[2]] = exp[3][1..-1]
54
+ @tracker.config[:rails][attribute] = exp.args
58
55
  else
59
- @tracker.config[:rails][exp[2]] = exp[3][1]
56
+ @tracker.config[:rails][attribute] = exp.first_arg
60
57
  end
61
58
  elsif include_rails_config? exp
62
59
  options = get_rails_config exp
@@ -66,7 +63,7 @@ class ConfigProcessor < BaseProcessor
66
63
  level = level[o]
67
64
  end
68
65
 
69
- level[options.last] = exp[3][1]
66
+ level[options.last] = exp.first_arg
70
67
  end
71
68
 
72
69
  exp
@@ -75,8 +72,8 @@ class ConfigProcessor < BaseProcessor
75
72
  #Check for Rails version
76
73
  def process_cdecl exp
77
74
  #Set Rails version required
78
- if exp[1] == :RAILS_GEM_VERSION
79
- @tracker.config[:rails_version] = exp[2][1]
75
+ if exp.lhs == :RAILS_GEM_VERSION
76
+ @tracker.config[:rails_version] = exp.rhs.value
80
77
  end
81
78
 
82
79
  exp
@@ -84,9 +81,9 @@ class ConfigProcessor < BaseProcessor
84
81
 
85
82
  #Check if an expression includes a call to set Rails config
86
83
  def include_rails_config? exp
87
- target = exp[1]
84
+ target = exp.target
88
85
  if call? target
89
- if target[1] == RAILS_CONFIG
86
+ if target.target == RAILS_CONFIG
90
87
  true
91
88
  else
92
89
  include_rails_config? target
@@ -106,14 +103,14 @@ class ConfigProcessor < BaseProcessor
106
103
  #
107
104
  # [:action_controller, :session_store]
108
105
  def get_rails_config exp
109
- if sexp? exp and exp.node_type == :attrasgn
110
- attribute = exp[2].to_s[0..-2].to_sym
111
- get_rails_config(exp[1]) << attribute
106
+ if node_type? exp, :attrasgn
107
+ attribute = exp.method.to_s[0..-2].to_sym
108
+ get_rails_config(exp.target) << attribute
112
109
  elsif call? exp
113
- if exp[1] == RAILS_CONFIG
114
- [exp[2]]
110
+ if exp.target == RAILS_CONFIG
111
+ [exp.method]
115
112
  else
116
- get_rails_config(exp[1]) << exp[2]
113
+ get_rails_config(exp.target) << exp.method
117
114
  end
118
115
  else
119
116
  raise "WHAT"
@@ -122,7 +119,7 @@ class ConfigProcessor < BaseProcessor
122
119
  end
123
120
 
124
121
  #This is necessary to replace block variable so we can track config settings
125
- class ConfigAliasProcessor < AliasProcessor
122
+ class Brakeman::ConfigAliasProcessor < Brakeman::AliasProcessor
126
123
 
127
124
  RAILS_INIT = Sexp.new(:colon2, Sexp.new(:const, :Rails), :Initializer)
128
125
 
@@ -134,11 +131,11 @@ class ConfigAliasProcessor < AliasProcessor
134
131
  #
135
132
  #and replace config with RAILS_CONFIG
136
133
  def process_iter exp
137
- target = exp[1][1]
138
- method = exp[1][2]
134
+ target = exp.block_call.target
135
+ method = exp.block_call.method
139
136
 
140
137
  if sexp? target and target == RAILS_INIT and method == :run
141
- exp[2][2] = RAILS_CONFIG
138
+ env[Sexp.new(:lvar, exp.block_args.value)] = Brakeman::Rails2ConfigProcessor::RAILS_CONFIG
142
139
  end
143
140
 
144
141
  process_default exp
@@ -1,10 +1,11 @@
1
- require 'processors/base_processor'
1
+ require 'brakeman/processors/base_processor'
2
+
2
3
  #Processes the Sexp from routes.rb. Stores results in tracker.routes.
3
4
  #
4
5
  #Note that it is only interested in determining what methods on which
5
6
  #controllers are used as routes, not the generated URLs for routes.
6
- class RoutesProcessor < BaseProcessor
7
- include RouteHelper
7
+ class Brakeman::Rails2RoutesProcessor < Brakeman::BaseProcessor
8
+ include Brakeman::RouteHelper
8
9
 
9
10
  attr_reader :map, :nested, :current_controller
10
11
 
@@ -22,16 +23,15 @@ class RoutesProcessor < BaseProcessor
22
23
  #This method first calls RouteAliasProcessor#process_safely on the +exp+,
23
24
  #so it does not modify the +exp+.
24
25
  def process_routes exp
25
- process RouteAliasProcessor.new.process_safely(exp)
26
+ process Brakeman::RouteAliasProcessor.new.process_safely(exp)
26
27
  end
27
28
 
28
29
  #Looking for mapping of routes
29
30
  def process_call exp
30
- target = exp[1]
31
+ target = exp.target
31
32
 
32
- if target == map or target == nested
33
+ if target == map or (not target.nil? and target == nested)
33
34
  process_map exp
34
-
35
35
  else
36
36
  process_default exp
37
37
  end
@@ -42,9 +42,9 @@ class RoutesProcessor < BaseProcessor
42
42
  #Process a map.something call
43
43
  #based on the method used
44
44
  def process_map exp
45
- args = exp[3][1..-1]
45
+ args = exp.args
46
46
 
47
- case exp[2]
47
+ case exp.method
48
48
  when :resource
49
49
  process_resource args
50
50
  when :resources
@@ -61,14 +61,16 @@ class RoutesProcessor < BaseProcessor
61
61
  #Look for map calls that take a block.
62
62
  #Otherwise, just do the default processing.
63
63
  def process_iter exp
64
- if exp[1][1] == map or exp[1][1] == nested
65
- method = exp[1][2]
64
+ target = exp.block_call.target
65
+
66
+ if target == map or target == nested
67
+ method = exp.block_call.method
66
68
  case method
67
69
  when :namespace
68
70
  process_namespace exp
69
71
  when :resources, :resource
70
- process_resources exp[1][3][1..-1]
71
- process_default exp[3]
72
+ process_resources exp.block_call.args
73
+ process_default exp.block if exp.block
72
74
  when :with_options
73
75
  process_with_options exp
74
76
  end
@@ -88,10 +90,10 @@ class RoutesProcessor < BaseProcessor
88
90
  process_resource_options exp[-1]
89
91
  else
90
92
  exp.each do |argument|
91
- if sexp? argument and argument.node_type == :lit
92
- self.current_controller = exp[0][1]
93
+ if node_type? argument, :lit
94
+ self.current_controller = exp.first.value
93
95
  add_resources_routes
94
- process_resource_options exp[-1]
96
+ process_resource_options exp.last
95
97
  end
96
98
  end
97
99
  end
@@ -110,7 +112,8 @@ class RoutesProcessor < BaseProcessor
110
112
  hash_iterate(exp) do |option, value|
111
113
  case option[1]
112
114
  when :controller, :requirements, :singular, :path_prefix, :as,
113
- :path_names, :shallow, :name_prefix
115
+ :path_names, :shallow, :name_prefix, :member_path, :nested_member_path,
116
+ :belongs_to, :conditions, :active_scaffold
114
117
  #should be able to skip
115
118
  when :collection, :member, :new
116
119
  process_collection value
@@ -127,7 +130,7 @@ class RoutesProcessor < BaseProcessor
127
130
  when :except
128
131
  process_option_except value
129
132
  else
130
- raise "Unhandled resource option: #{option}"
133
+ Brakeman.notify "[Notice] Unhandled resource option, please report: #{option}"
131
134
  end
132
135
  end
133
136
  end
@@ -141,7 +144,7 @@ class RoutesProcessor < BaseProcessor
141
144
 
142
145
  if exp.node_type == :array
143
146
  exp[1..-1].each do |e|
144
- routes << e[1]
147
+ routes << e.value
145
148
  end
146
149
  end
147
150
  end
@@ -152,7 +155,7 @@ class RoutesProcessor < BaseProcessor
152
155
  routes = @tracker.routes[@current_controller]
153
156
 
154
157
  exp[1..-1].each do |e|
155
- routes.delete e[1]
158
+ routes.delete e.value
156
159
  end
157
160
  end
158
161
 
@@ -161,13 +164,13 @@ class RoutesProcessor < BaseProcessor
161
164
  controller = check_for_controller_name exp
162
165
  if controller
163
166
  self.current_controller = controller
164
- process_resource_options exp[-1]
167
+ process_resource_options exp.last
165
168
  else
166
169
  exp.each do |argument|
167
- if sexp? argument and argument.node_type == :lit
168
- self.current_controller = pluralize(exp[0][1].to_s)
170
+ if node_type? argument, :lit
171
+ self.current_controller = pluralize(exp.first.value.to_s)
169
172
  add_resource_routes
170
- process_resource_options exp[-1]
173
+ process_resource_options exp.last
171
174
  end
172
175
  end
173
176
  end
@@ -176,26 +179,33 @@ class RoutesProcessor < BaseProcessor
176
179
  #Process
177
180
  # map.connect '/something', :controller => 'blah', :action => 'whatever'
178
181
  def process_connect exp
182
+ return if exp.empty?
183
+
179
184
  controller = check_for_controller_name exp
180
185
  self.current_controller = controller if controller
181
186
 
182
187
  #Check for default route
183
- if string? exp[0]
184
- if exp[0][1] == ":controller/:action/:id"
185
- @tracker.routes[:allow_all_actions] = exp[0]
186
- elsif exp[0][1].include? ":action"
187
- @tracker.routes[@current_controller] = :allow_all_actions
188
+ if string? exp.first
189
+ if exp.first.value == ":controller/:action/:id"
190
+ @tracker.routes[:allow_all_actions] = exp.first
191
+ elsif exp.first.value.include? ":action"
192
+ @tracker.routes[@current_controller] = [:allow_all_actions, exp.line]
188
193
  return
189
194
  end
190
195
  end
191
196
 
192
197
  #This -seems- redundant, but people might connect actions
193
198
  #to a controller which already allows them all
194
- return if @tracker.routes[@current_controller] == :allow_all_actions
199
+ return if @tracker.routes[@current_controller].is_a? Array and @tracker.routes[@current_controller][0] == :allow_all_actions
200
+
201
+ exp.last.each_with_index do |e,i|
202
+ if symbol? e and e.value == :action
203
+ action = exp.last[i + 1]
204
+
205
+ if node_type? action, :lit
206
+ @tracker.routes[@current_controller] << action.value.to_sym
207
+ end
195
208
 
196
- exp[-1].each_with_index do |e,i|
197
- if symbol? e and e[1] == :action
198
- @tracker.routes[@current_controller] << exp[-1][i + 1][1].to_sym
199
209
  return
200
210
  end
201
211
  end
@@ -205,13 +215,13 @@ class RoutesProcessor < BaseProcessor
205
215
  # something.resources :blah
206
216
  # end
207
217
  def process_with_options exp
208
- @with_options = exp[1][3][-1]
209
- @nested = Sexp.new(:lvar, exp[2][1])
218
+ @with_options = exp.block_call.last_arg
219
+ @nested = Sexp.new(:lvar, exp.block_args.value)
210
220
 
211
- self.current_controller = check_for_controller_name exp[1][3]
221
+ self.current_controller = check_for_controller_name exp.block_call.args
212
222
 
213
223
  #process block
214
- process exp[3]
224
+ process exp.block
215
225
 
216
226
  @with_options = nil
217
227
  @nested = nil
@@ -221,13 +231,15 @@ class RoutesProcessor < BaseProcessor
221
231
  # something.resources :blah
222
232
  # end
223
233
  def process_namespace exp
224
- call = exp[1]
225
- formal_args = exp[2]
226
- block = exp[3]
234
+ call = exp.block_call
235
+ formal_args = exp.block_args
236
+ block = exp.block
227
237
 
228
- @prefix << camelize(call[3][1][1])
238
+ @prefix << camelize(call.first_arg.value)
229
239
 
230
- @nested = Sexp.new(:lvar, formal_args[1])
240
+ if formal_args
241
+ @nested = Sexp.new(:lvar, formal_args.value)
242
+ end
231
243
 
232
244
  process block
233
245
 
@@ -246,7 +258,7 @@ class RoutesProcessor < BaseProcessor
246
258
  routes = @tracker.routes[@current_controller]
247
259
 
248
260
  hash_iterate(exp) do |action, type|
249
- routes << action[1]
261
+ routes << action.value
250
262
  end
251
263
  end
252
264
 
@@ -258,12 +270,8 @@ class RoutesProcessor < BaseProcessor
258
270
  #Otherwise, returns nil.
259
271
  def check_for_controller_name args
260
272
  args.each do |a|
261
- if hash? a
262
- hash_iterate(a) do |k, v|
263
- if k[1] == :controller
264
- return v[1]
265
- end
266
- end
273
+ if hash? a and value = hash_access(a, :controller)
274
+ return value.value if string? value or symbol? value
267
275
  end
268
276
  end
269
277
 
@@ -273,7 +281,7 @@ end
273
281
 
274
282
  #This is for a really specific case where a hash is used as arguments
275
283
  #to one of the map methods.
276
- class RouteAliasProcessor < AliasProcessor
284
+ class Brakeman::RouteAliasProcessor < Brakeman::AliasProcessor
277
285
 
278
286
  #This replaces
279
287
  # { :some => :hash }.keys
@@ -282,8 +290,8 @@ class RouteAliasProcessor < AliasProcessor
282
290
  def process_call exp
283
291
  process_default exp
284
292
 
285
- if hash? exp[1] and exp[2] == :keys
286
- keys = get_keys exp[1]
293
+ if hash? exp.target and exp.method == :keys
294
+ keys = get_keys exp.target
287
295
  exp.clear
288
296
  keys.each_with_index do |e,i|
289
297
  exp[i] = e