diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index a94b2ffd93de3..c3eb98c8f9838 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -112,6 +112,15 @@ def requirements @requirements ||= (@options[:constraints].is_a?(Hash) ? @options[:constraints] : {}).tap do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } + + requirements.each do |_, requirement| + if requirement.source =~ %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z} + raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}" + end + if requirement.multiline? + raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}" + end + end end end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 8e0ae70945342..222a45c943551 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -2178,6 +2178,46 @@ def test_controller_name_with_leading_slash_raise_error end end + def test_routing_constraints_with_anchors_raises_error + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { match 'page/:id' => 'pages#show', :id => /^\d+/ } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { match 'page/:id' => 'pages#show', :id => /\A\d+/ } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { match 'page/:id' => 'pages#show', :id => /\d+$/ } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { match 'page/:id' => 'pages#show', :id => /\d+\Z/ } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { match 'page/:id' => 'pages#show', :id => /^\d+\z/ } + end + end + end + + def test_multiline_routing_constraint_raises_error + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { match 'page/:id' => 'pages#show', :id => /\w+/m } + end + end + end + private def with_test_routes yield