Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Backported patch from [#4762]

URL fragments should not have safe characters escaped. Ref: Appendix A,
  http://tools.ietf.org/rfc/rfc3986.txt

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
commit f8f4872fccbc6ba2b4970e4e9eab9ce7f0d19986 1 parent fad166c
@jberkel jberkel authored josevalim committed
View
10 actionpack/lib/action_controller/url_rewriter.rb
@@ -92,6 +92,14 @@ module ActionController
# end
# end
module UrlWriter
+ RESERVED_PCHAR = ':@&=+$,;%'
+ SAFE_PCHAR = "#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}"
+ if RUBY_VERSION >= '1.9'
+ UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false).freeze
+ else
+ UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false, 'N').freeze
+ end
+
def self.included(base) #:nodoc:
ActionController::Routing::Routes.install_helpers(base)
base.mattr_accessor :default_url_options
@@ -142,7 +150,7 @@ def url_for(options)
end
trailing_slash = options.delete(:trailing_slash) if options.key?(:trailing_slash)
url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root]
- anchor = "##{CGI.escape options.delete(:anchor).to_param.to_s}" if options[:anchor]
+ anchor = "##{URI.escape(options.delete(:anchor).to_param.to_s, UNSAFE_PCHAR)}" if options[:anchor]
generated = Routing::Routes.generate(options, {})
url << (trailing_slash ? generated.sub(/\?|\z/) { "/" + $& } : generated)
url << anchor if anchor
View
12 actionpack/test/controller/url_rewriter_test.rb
@@ -134,9 +134,15 @@ def test_anchor_should_call_to_param
)
end
- def test_anchor_should_be_cgi_escaped
- assert_equal('/c/a#anc%2Fhor',
- W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anc/hor'))
+ def test_anchor_should_escape_unsafe_pchar
+ assert_equal('/c/a#%23anchor',
+ W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('#anchor'))
+ )
+ end
+
+ def test_anchor_should_not_escape_safe_pchar
+ assert_equal('/c/a#name=user&email=user@domain.com',
+ W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('name=user&email=user@domain.com'))
)
end

0 comments on commit f8f4872

Please sign in to comment.
Something went wrong with that request. Please try again.