mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Force encoding of US-ASCII to UTF-8 in unescape_uri.
Because URI paths may contain non US-ASCII characters we need to force the encoding of any unescaped URIs to UTF-8 if they are US-ASCII. This essentially replicates the functionality of the monkey patch to URI.parser.unescape in active_support/core_ext/uri.rb. Fixes #16104.
This commit is contained in:
parent
b9ffae8feb
commit
8a29713134
3 changed files with 21 additions and 5 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
* Because URI paths may contain non US-ASCII characters we need to force
|
||||||
|
the encoding of any unescaped URIs to UTF-8 if they are US-ASCII.
|
||||||
|
This essentially replicates the functionality of the monkey patch to
|
||||||
|
URI.parser.unescape in active_support/core_ext/uri.rb.
|
||||||
|
|
||||||
|
Fixes #16104.
|
||||||
|
|
||||||
|
*Karl Entwistle*
|
||||||
|
|
||||||
* Generate shallow paths for all children of shallow resources.
|
* Generate shallow paths for all children of shallow resources.
|
||||||
|
|
||||||
Fixes #15783.
|
Fixes #15783.
|
||||||
|
|
|
@ -25,9 +25,10 @@ module ActionDispatch
|
||||||
# http://tools.ietf.org/html/rfc3986
|
# http://tools.ietf.org/html/rfc3986
|
||||||
class UriEncoder # :nodoc:
|
class UriEncoder # :nodoc:
|
||||||
ENCODE = "%%%02X".freeze
|
ENCODE = "%%%02X".freeze
|
||||||
ENCODING = Encoding::US_ASCII
|
US_ASCII = Encoding::US_ASCII
|
||||||
EMPTY = "".force_encoding(ENCODING).freeze
|
UTF_8 = Encoding::UTF_8
|
||||||
DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(ENCODING) }
|
EMPTY = "".force_encoding(US_ASCII).freeze
|
||||||
|
DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(US_ASCII) }
|
||||||
|
|
||||||
ALPHA = "a-zA-Z".freeze
|
ALPHA = "a-zA-Z".freeze
|
||||||
DIGIT = "0-9".freeze
|
DIGIT = "0-9".freeze
|
||||||
|
@ -53,12 +54,13 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
def unescape_uri(uri)
|
def unescape_uri(uri)
|
||||||
uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(uri.encoding)
|
encoding = uri.encoding == US_ASCII ? UTF_8 : uri.encoding
|
||||||
|
uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(encoding)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def escape(component, pattern)
|
def escape(component, pattern)
|
||||||
component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(ENCODING)
|
component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(US_ASCII)
|
||||||
end
|
end
|
||||||
|
|
||||||
def percent_encode(unsafe)
|
def percent_encode(unsafe)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# coding: utf-8
|
||||||
require 'abstract_unit'
|
require 'abstract_unit'
|
||||||
|
|
||||||
module ActionDispatch
|
module ActionDispatch
|
||||||
|
@ -20,6 +21,10 @@ module ActionDispatch
|
||||||
assert_equal "a/b c+d", Utils.unescape_uri("a%2Fb%20c+d")
|
assert_equal "a/b c+d", Utils.unescape_uri("a%2Fb%20c+d")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_uri_unescape_with_utf8_string
|
||||||
|
assert_equal "Šašinková", Utils.unescape_uri("%C5%A0a%C5%A1inkov%C3%A1".force_encoding(Encoding::US_ASCII))
|
||||||
|
end
|
||||||
|
|
||||||
def test_normalize_path_not_greedy
|
def test_normalize_path_not_greedy
|
||||||
assert_equal "/foo%20bar%20baz", Utils.normalize_path("/foo%20bar%20baz")
|
assert_equal "/foo%20bar%20baz", Utils.normalize_path("/foo%20bar%20baz")
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue