diff options
author | Andrew White <andyw@pixeltrix.co.uk> | 2012-04-29 21:09:49 +0100 |
---|---|---|
committer | Andrew White <andyw@pixeltrix.co.uk> | 2012-04-29 21:12:03 +0100 |
commit | 958daaa664079ec32e542dc3dec52dfd504aecde (patch) | |
tree | c2b210db527a13bd13cb37b596ca39b48d697267 | |
parent | 978598b6da75aa5b1b4d0b95b08596e2c609a94e (diff) | |
download | rails-958daaa664079ec32e542dc3dec52dfd504aecde.tar.gz rails-958daaa664079ec32e542dc3dec52dfd504aecde.tar.bz2 rails-958daaa664079ec32e542dc3dec52dfd504aecde.zip |
Escape interpolated params when redirecting - fixes #5688
-rw-r--r-- | actionpack/lib/action_dispatch/routing/redirection.rb | 8 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing_test.rb | 29 |
2 files changed, 36 insertions, 1 deletions
diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index ae01781013..f4084d9f4f 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -1,4 +1,5 @@ require 'action_dispatch/http/request' +require 'rack/utils' module ActionDispatch module Routing @@ -96,13 +97,18 @@ module ActionDispatch path = args.shift block = lambda { |params, request| - (params.empty? || !path.match(/%\{\w*\}/)) ? path : (path % params) + (params.empty? || !path.match(/%\{\w*\}/)) ? path : (path % escape(params)) } if String === path block = path if path.respond_to? :call raise ArgumentError, "redirection argument not supported" unless block Redirect.new status, block end + + private + def escape(params) + Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }] + end end end end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 463dd6cb85..ce5cc16ace 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -2452,3 +2452,32 @@ class TestTildeAndMinusPaths < ActionDispatch::IntegrationTest end end + +class TestRedirectInterpolation < ActionDispatch::IntegrationTest + Routes = ActionDispatch::Routing::RouteSet.new.tap do |app| + app.draw do + ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] } + + get "/foo/:id" => redirect("/foo/bar/%{id}") + get "/foo/bar/:id" => ok + end + end + + def app; Routes end + + test "redirect escapes interpolated parameters" do + get "/foo/1%3E" + verify_redirect "http://www.example.com/foo/bar/1%3E" + end + +private + def verify_redirect(url, status=301) + assert_equal status, @response.status + assert_equal url, @response.headers['Location'] + assert_equal expected_redirect_body(url), @response.body + end + + def expected_redirect_body(url) + %(<html><body>You are being <a href="#{ERB::Util.h(url)}">redirected</a>.</body></html>) + end +end |