From 572bbab2e63916b4bb5e835d403856767b7f4be5 Mon Sep 17 00:00:00 2001
From: brainopia <brainopia@evilmartians.com>
Date: Sat, 27 Dec 2014 13:42:42 +0300
Subject: Improve shorthand matching for routes

Shorthand route match is when controller and action are taken literally from path.
E.g.
get '/foo/bar' # => will use 'foo#bar' as endpoint
get '/foo/bar/baz' # => will use 'foo/bar#baz' as endpoint

Not any path with level two or more of nesting can be used as shortcut.
If path contains any characters outside of /[\w-]/ then it can't be
used as such.

This commit ensures that invalid shortcuts aren't used.

':controller/:action/postfix' - is an example of invalid shortcut
that was previosly matched and led to exception:
"ArgumentError - ':controller/:action' is not a supported controller name"
---
 actionpack/lib/action_dispatch/routing/mapper.rb | 2 +-
 actionpack/test/dispatch/routing_test.rb         | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

(limited to 'actionpack')

diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index f2c9e7b1a0..34b5b48f3a 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1504,7 +1504,7 @@ module ActionDispatch
         end
 
         def using_match_shorthand?(path, options)
-          path && (options[:to] || options[:action]).nil? && path =~ %r{/[\w/]+$}
+          path && (options[:to] || options[:action]).nil? && path =~ %r{^/?[-\w]+/[-\w/]+$}
         end
 
         def decomposed_match(path, options) # :nodoc:
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 3373705326..57cdecfb8a 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -1430,6 +1430,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
     assert_equal 'api/v3/products#list', @response.body
   end
 
+  def test_not_matching_shorthand_with_dynamic_parameters
+    draw do
+      get ':controller/:action/admin'
+    end
+
+    get '/finances/overview/admin'
+    assert_equal 'finances#overview', @response.body
+  end
+
   def test_controller_option_with_nesting_and_leading_slash
     draw do
       scope '/job', controller: 'job' do
-- 
cgit v1.2.3