diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 4bcc860e096005cef7c03e281ed3e07120958a81..3f738c32bc300ddcd6cabb88efdab04d032f2571 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,7 +1,10 @@ *SVN* +* Make Routing noisy when an anchor regexp is assigned to a segment. #5674 [francois.beausoleil@gmail.com] + * Added months and years to the resolution of DateHelper#distance_of_time_in_words, such that "60 days ago" becomes "2 months ago" #5611 [pjhyett@gmail.com] +>>>>>>> .r4676 * Short documentation to mention use of Mime::Type.register. #5710 [choonkeat@gmail.com] * Make controller_path available as an instance method. #5724 [jmckible@gmail.com] diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb index 7ca773469cefd37706b85041622dcfe85d628128..2911789892859a2eee97949891efcfac5c2bf2af 100644 --- a/actionpack/lib/action_controller/routing.rb +++ b/actionpack/lib/action_controller/routing.rb @@ -679,7 +679,7 @@ def divide_route_options(segments, options) [defaults, requirements, conditions] end - + # Takes a hash of defaults and a hash of requirements, and assigns them to # the segments. Any unused requirements (which do not correspond to a segment) # are returned as a hash. @@ -694,6 +694,9 @@ def assign_route_options(segments, defaults, requirements) segment = segment_named[key] if segment raise TypeError, "#{key}: requirements on a path segment must be regular expressions" unless requirement.is_a?(Regexp) + if requirement.source =~ %r{\\A|\\Z|\\z|\^|\$} + raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}" + end segment.regexp = requirement else route_requirements[key] = requirement diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 56070fe6f3b10b7fc046c81a6ffe7a6e7f6cbfc8..8def5556b2d1666eb1b17290c08fc39223d00d2a 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -150,7 +150,7 @@ def test_named_route_without_hash def test_named_route_with_regexps rs.draw do |map| map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show', - :year => /^\d+$/, :month => /^\d+$/, :day => /^\d+$/ + :year => /\d+/, :month => /\d+/, :day => /\d+/ map.connect ':controller/:action/:id' end x = setup_for_named_route.new @@ -1216,47 +1216,96 @@ def test_namd_route_url_method_with_ordered_parameters assert_equal "http://named.route.test/people/go/7/hello/joe/5", controller.send(:multi_url, 7, "hello", 5) end - + def test_draw_default_route ActionController::Routing.with_controllers(['users']) do set.draw do |map| map.connect '/:controller/:action/:id' end - + assert_equal 1, set.routes.size route = set.routes.first - + assert route.segments.last.optional? - + assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10) assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10) - + assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10')) assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/')) end end - + def test_route_with_parameter_shell ActionController::Routing.with_controllers(['users', 'pages']) do set.draw do |map| map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/ map.connect '/:controller/:action/:id' end - + assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages')) assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index')) assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list')) - + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10')) assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) end end + def test_route_requirements_with_anchor_chars_are_invalid + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/ + end + end + assert_nothing_raised do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/ + end + assert_raises ActionController::RoutingError do + set.generate :controller => 'pages', :action => 'show', :id => 10 + end + end + end + + def test_non_path_route_requirements_match_all + set.draw do |map| + map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/ + end + assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis') + assert_raises ActionController::RoutingError do + set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis') + end + assert_raises ActionController::RoutingError do + set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david') + end + end + def test_recognize_with_encoded_id_and_regex set.draw do |map| map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9 ]+/ end - + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) assert_equal({:controller => 'pages', :action => 'show', :id => 'hello world'}, set.recognize_path('/page/hello+world')) end