Skip to content
This repository

Improve Rails 3 route processing #116

Merged
merged 11 commits into from over 1 year ago

2 participants

Justin Neil Matatall
Justin
Owner

This patch fixes some issues with Rails 3 route processing.

Improvements include:

  • Handling "controller" blocks
controller :whatever do
  get :something => :else
end
  • Handling routes that don't specify a controller
resource :book do
  get :reserve
end
  • Handling :to options in match
match 'path', :to => 'controller#action'
  • Handling :to options in blocks
resource :book do
  get 'reserve', :to => :checkout
end
Neil Matatall oreoshake commented on the diff July 24, 2012
lib/brakeman/processors/lib/rails3_route_processor.rb
((5 lines not shown))
184 223
     exp
185 224
   end
186 225
 
187 226
   def process_resources_block exp
188  
-    process_resources exp[1]
2
Neil Matatall Collaborator
oreoshake added a note July 24, 2012

alias :process_resources_block, :process_resource_block?

Justin Owner

They are slightly different...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Neil Matatall
Collaborator

code climate is making me overthink this, but yeah, :+1:

Justin presidentbeef merged commit 57c2672 into from July 24, 2012
Justin presidentbeef closed this July 24, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
116  lib/brakeman/processors/lib/rails3_route_processor.rb
@@ -14,6 +14,7 @@ def initialize tracker
14 14
     @prefix = [] #Controller name prefix (a module name, usually)
15 15
     @current_controller = nil
16 16
     @with_options = nil #For use inside map.with_options
  17
+    @controller_block = false
17 18
   end
18 19
 
19 20
   def process_routes exp
@@ -49,6 +50,8 @@ def process_iter exp
49 50
       process_resources_block exp
50 51
     when :scope
51 52
       process_scope_block exp
  53
+    when :controller
  54
+      process_controller_block exp
52 55
     else
53 56
       super
54 57
     end
@@ -71,10 +74,8 @@ def process_root exp
71 74
     args = exp[3][1..-1]
72 75
 
73 76
     if value = hash_access(args[0], :to)
74  
-      if string? value[1]
75  
-        controller, action = extract_action v[1]
76  
-
77  
-        add_route action, controller
  77
+      if string? value
  78
+        add_route_from_string value
78 79
       end
79 80
     end
80 81
 
@@ -96,18 +97,36 @@ def process_match exp
96 97
         return exp
97 98
       elsif matcher.include? ':action'
98 99
         action_variable = true
  100
+      elsif args[1].nil? and in_controller_block? and not matcher.include? ":"
  101
+        add_route matcher
99 102
       end
100 103
     end
101 104
 
102 105
     if hash? args[-1]
103 106
       hash_iterate args[-1] do |k, v|
104  
-        if string? k and string? v
105  
-          controller, action = extract_action v[1]
  107
+        if string? k
  108
+          if string? v
  109
+            add_route_from_string v[1]
  110
+          elsif in_controller_block? and symbol? v
  111
+            add_route v
  112
+          end
  113
+        elsif symbol? k
  114
+         case k[1]
  115
+         when :action
  116
+          if string? v
  117
+            add_route_from_string v
  118
+          else
  119
+            add_route v
  120
+          end
106 121
 
107  
-          add_route action if action
108  
-        elsif symbol? k and k[1] == :action
109  
-          add_route action
110 122
           action_variable = false
  123
+         when :to
  124
+           if string? v
  125
+             add_route_from_string v[1]
  126
+           elsif in_controller_block? and symbol? v
  127
+             add_route v
  128
+           end
  129
+         end
111 130
         end
112 131
       end
113 132
     end
@@ -116,9 +135,22 @@ def process_match exp
116 135
       @tracker.routes[@current_controller] = :allow_all_actions
117 136
     end
118 137
 
  138
+    @current_controller = nil unless in_controller_block?
119 139
     exp
120 140
   end
121 141
 
  142
+  def add_route_from_string value
  143
+    value = value[1] if string? value
  144
+
  145
+    controller, action = extract_action value
  146
+
  147
+    if action
  148
+      add_route action, controller
  149
+    elsif in_controller_block?
  150
+      add_route value
  151
+    end
  152
+  end
  153
+
122 154
   def process_verb exp
123 155
     args = exp[3][1..-1]
124 156
 
@@ -126,10 +158,12 @@ def process_verb exp
126 158
       add_route args[0]
127 159
     elsif hash? args[1]
128 160
       hash_iterate args[1] do |k, v|
129  
-        if symbol? k and k[1] == :to and string? v
130  
-          controller, action = extract_action v[1]
131  
-
132  
-          add_route action, controller
  161
+        if symbol? k and k[1] == :to
  162
+          if string? v
  163
+            add_route_from_string v[1]
  164
+          elsif in_controller_block? and symbol? v
  165
+            add_route v
  166
+          end
133 167
         end
134 168
       end
135 169
     elsif string? args[0]
@@ -138,19 +172,22 @@ def process_verb exp
138 172
         add_route route[0]
139 173
       else
140 174
         add_route route[1], route[0]
141  
-        @current_controller = nil
142 175
       end
  176
+    elsif in_controller_block? and symbol? args[0]
  177
+      add_route args[0]
143 178
     else hash? args[0]
144 179
       hash_iterate args[0] do |k, v|
145  
-        if string? v
146  
-          controller, action = extract_action v[1]
147  
-
148  
-          add_route action, controller
149  
-          break
  180
+        if string? k
  181
+          if string? v
  182
+            add_route_from_string v
  183
+          elsif in_controller_block?
  184
+            add_route v
  185
+          end
150 186
         end
151 187
       end
152 188
     end
153 189
 
  190
+    @current_controller = nil unless in_controller_block?
154 191
     exp
155 192
   end
156 193
 
@@ -166,6 +203,7 @@ def process_resources exp
166 203
       end
167 204
     end
168 205
 
  206
+    @current_controller = nil unless in_controller_block?
169 207
     exp
170 208
   end
171 209
 
@@ -181,18 +219,27 @@ def process_resource exp
181 219
       end
182 220
     end
183 221
 
  222
+    @current_controller = nil unless in_controller_block?
184 223
     exp
185 224
   end
186 225
 
187 226
   def process_resources_block exp
188  
-    process_resources exp[1]
189  
-    process exp[3]
  227
+    in_controller_block do
  228
+      process_resources exp[1]
  229
+      process exp[3]
  230
+    end
  231
+
  232
+    @current_controller = nil
190 233
     exp
191 234
   end
192 235
 
193 236
   def process_resource_block exp
194  
-    process_resource exp[1]
195  
-    process exp[3]
  237
+    in_controller_block do
  238
+      process_resource exp[1]
  239
+      process exp[3]
  240
+    end
  241
+
  242
+    @current_controller = nil
196 243
     exp
197 244
   end
198 245
 
@@ -202,7 +249,30 @@ def process_scope_block exp
202 249
     exp
203 250
   end
204 251
 
  252
+  def process_controller_block exp
  253
+    args = exp[1][3]
  254
+    self.current_controller = args[1][1]
  255
+
  256
+    in_controller_block do
  257
+      process exp[-1] if exp[-1]
  258
+    end
  259
+
  260
+    @current_controller = nil
  261
+    exp
  262
+  end
  263
+
205 264
   def extract_action str
206 265
     str.split "#"
207 266
   end
  267
+
  268
+  def in_controller_block?
  269
+    @controller_block
  270
+  end
  271
+
  272
+  def in_controller_block
  273
+    prev_block = @controller_block
  274
+    @controller_block = true
  275
+    yield
  276
+    @controller_block = prev_block
  277
+  end
208 278
 end
6  lib/brakeman/processors/lib/route_helper.rb
@@ -35,7 +35,11 @@ def add_route route, controller = nil
35 35
       self.current_controller = controller
36 36
     end
37 37
 
38  
-    @tracker.routes[@current_controller] << route
  38
+    routes = @tracker.routes[@current_controller]
  39
+    
  40
+    if routes and routes != :allow_all_actions
  41
+      routes << route
  42
+    end
39 43
   end
40 44
 
41 45
   #Add default routes
29  test/apps/rails3.1/app/controllers/other_controller.rb
... ...
@@ -0,0 +1,29 @@
  1
+class OtherController < ApplicationController
  2
+  def a
  3
+    @a = params[:bad]
  4
+  end
  5
+
  6
+  def b
  7
+    @b = params[:bad]
  8
+  end
  9
+
  10
+  def c
  11
+    @c = params[:bad]
  12
+  end
  13
+
  14
+  def d
  15
+    @d = params[:bad]
  16
+  end
  17
+
  18
+  def e
  19
+    @e = params[:bad]
  20
+  end
  21
+
  22
+  def f
  23
+    @f = params[:bad]
  24
+  end
  25
+
  26
+  def g
  27
+    @g = params[:bad]
  28
+  end
  29
+end
1  test/apps/rails3.1/app/views/other/a.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @a %>
1  test/apps/rails3.1/app/views/other/b.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @b %>
1  test/apps/rails3.1/app/views/other/c.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @c %>
1  test/apps/rails3.1/app/views/other/d.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @d %>
1  test/apps/rails3.1/app/views/other/e.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @e %>
1  test/apps/rails3.1/app/views/other/f.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @f %>
1  test/apps/rails3.1/app/views/other/g.html.erb
... ...
@@ -0,0 +1 @@
  1
+<%= raw @g %>
17  test/apps/rails3.1/config/routes.rb
@@ -4,6 +4,23 @@
4 4
     get 'mixin_default'
5 5
   end
6 6
 
  7
+  resources :other do
  8
+    get :a
  9
+    delete 'f'
  10
+  end
  11
+
  12
+  controller :other do
  13
+    get 'b'
  14
+    post 'something' => 'c'
  15
+    put 'dee', :to => :d
  16
+  end
  17
+
  18
+  match 'e', :to => 'other#e', :as => 'eeeee'
  19
+
  20
+  get 'g' => 'other#g'
  21
+
  22
+  match 'blah/:id', :action => 'blarg' 
  23
+
7 24
   # The priority is based upon order of creation:
8 25
   # first created -> highest priority.
9 26
 
64  test/tests/test_rails31.rb
@@ -13,7 +13,7 @@ def report
13 13
   def expected
14 14
     @expected ||= {
15 15
       :model => 0,
16  
-      :template => 4,
  16
+      :template => 11,
17 17
       :controller => 1,
18 18
       :warning => 44 }
19 19
   end
@@ -455,6 +455,68 @@ def test_controller_mixin_default_render
455 455
       :file => /users\/mixin_default\.html\.erb/
456 456
   end
457 457
 
  458
+  def test_get_in_resources_block
  459
+    assert_warning :type => :template,
  460
+      :warning_type => "Cross Site Scripting",
  461
+      :line => 1,
  462
+      :message => /^Unescaped\ parameter\ value/,
  463
+      :confidence => 0,
  464
+      :file => /\/a\.html\.erb/
  465
+  end
  466
+
  467
+  def test_get_in_controller_block
  468
+    assert_warning :type => :template,
  469
+      :warning_type => "Cross Site Scripting",
  470
+      :line => 1,
  471
+      :message => /^Unescaped\ parameter\ value/,
  472
+      :confidence => 0,
  473
+      :file => /\/b\.html\.erb/
  474
+  end
  475
+
  476
+  def test_post_with_just_hash_in_controller_block
  477
+    assert_warning :type => :template,
  478
+      :warning_type => "Cross Site Scripting",
  479
+      :line => 1,
  480
+      :message => /^Unescaped\ parameter\ value/,
  481
+      :confidence => 0,
  482
+      :file => /\/c\.html\.erb/
  483
+  end
  484
+
  485
+  def test_put_to_in_controller_block
  486
+    assert_warning :type => :template,
  487
+      :warning_type => "Cross Site Scripting",
  488
+      :line => 1,
  489
+      :message => /^Unescaped\ parameter\ value/,
  490
+      :confidence => 0,
  491
+      :file => /\/d\.html\.erb/
  492
+  end
  493
+
  494
+  def test_match_to_route
  495
+    assert_warning :type => :template,
  496
+      :warning_type => "Cross Site Scripting",
  497
+      :line => 1,
  498
+      :message => /^Unescaped\ parameter\ value/,
  499
+      :confidence => 0,
  500
+      :file => /\/e\.html\.erb/
  501
+  end
  502
+
  503
+  def test_delete_in_resources_block
  504
+    assert_warning :type => :template,
  505
+      :warning_type => "Cross Site Scripting",
  506
+      :line => 1,
  507
+      :message => /^Unescaped\ parameter\ value/,
  508
+      :confidence => 0,
  509
+      :file => /\/f\.html\.erb/
  510
+  end
  511
+
  512
+  def test_route_hash_shorthand
  513
+    assert_warning :type => :template,
  514
+      :warning_type => "Cross Site Scripting",
  515
+      :line => 1,
  516
+      :message => /^Unescaped\ parameter\ value/,
  517
+      :confidence => 0,
  518
+      :file => /\/g\.html\.erb/
  519
+  end
458 520
 
459 521
   def test_file_access_indirect_user_input
460 522
     assert_warning :type => :warning,
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.