aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG.md7
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb7
-rw-r--r--actionpack/test/dispatch/routing_test.rb15
3 files changed, 29 insertions, 0 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 05495179c3..ae9f2416f6 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Added verification of route constraints given as a Proc or an object responding
+ to `:matches?`. Previously, when given an non-complying object, it would just
+ silently fail to enforce the constraint. It will now raise an ArgumentError
+ when setting up the routes.
+
+ *Xavier Defrang*
+
* Fix `Mime::Type.parse` when bad accepts header is looked up. Previously it
was setting `request.formats` with an array containing a `nil` value, which
raised an error when setting the controller formats.
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 288ce3e867..ff33d87901 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -156,6 +156,8 @@ module ActionDispatch
next unless URL_OPTIONS.include?(key) && (String === default || Fixnum === default)
@defaults[key] ||= default
end
+ elsif options[:constraints]
+ verify_callable_constraint(options[:constraints])
end
if Regexp === options[:format]
@@ -165,6 +167,11 @@ module ActionDispatch
end
end
+ def verify_callable_constraint(callable_constraint)
+ return if callable_constraint.respond_to?(:call) || callable_constraint.respond_to?(:matches?)
+ raise ArgumentError, "Invalid constraint: #{callable_constraint.inspect} must respond to :call or :matches?"
+ end
+
def normalize_conditions!
@conditions.merge!(:path_info => path)
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 8e4339aa0c..e1ce3648e8 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -3593,6 +3593,21 @@ class TestFormatConstraints < ActionDispatch::IntegrationTest
end
end
+class TestCallableConstraintValidation < ActionDispatch::IntegrationTest
+
+ def test_constraint_with_object_not_callable
+ assert_raise(ArgumentError) do
+ ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+ get '/test', to: ok, constraints: Object.new
+ end
+ end
+ end
+ end
+
+end
+
class TestRouteDefaults < ActionDispatch::IntegrationTest
stub_controllers do |routes|
Routes = routes