Correctly handle encoded colons in routes (Fixes #776)
This uses a negative lookahead assertion to ensure the colon is not followed by a character that will make it a key. In that case, it should be treated as a literal colon, and handled similar to other literal special characters.
This commit is contained in:
parent
6ca8c84517
commit
f763e62819
|
@ -1631,7 +1631,7 @@ module Sinatra
|
|||
|
||||
# Special character handling.
|
||||
#
|
||||
pattern = segment.to_str.gsub(/[^\?\%\\\/\:\*\w]/) do |c|
|
||||
pattern = segment.to_str.gsub(/[^\?\%\\\/\:\*\w]|:(?!\w)/) do |c|
|
||||
ignore << escaped(c).join if c.match(/[\.@]/)
|
||||
patt = encoded(c)
|
||||
patt.gsub(/%[\da-fA-F]{2}/) do |match|
|
||||
|
|
|
@ -99,6 +99,50 @@ class RoutingTest < Minitest::Test
|
|||
assert_body "foo/bar"
|
||||
end
|
||||
|
||||
it "it handles encoded colons correctly" do
|
||||
mock_app {
|
||||
get("/:") { 'a' }
|
||||
get("/a/:") { 'b' }
|
||||
get("/a/:/b") { 'c' }
|
||||
get("/a/b:") { 'd' }
|
||||
get("/a/b: ") { 'e' }
|
||||
}
|
||||
get '/:'
|
||||
assert_equal 200, status
|
||||
assert_body "a"
|
||||
get '/%3a'
|
||||
assert_equal 200, status
|
||||
assert_body "a"
|
||||
|
||||
get '/a/:'
|
||||
assert_equal 200, status
|
||||
assert_body "b"
|
||||
get '/a/%3a'
|
||||
assert_equal 200, status
|
||||
assert_body "b"
|
||||
|
||||
get '/a/:/b'
|
||||
assert_equal 200, status
|
||||
assert_body "c"
|
||||
get '/a/%3A/b'
|
||||
assert_equal 200, status
|
||||
assert_body "c"
|
||||
|
||||
get '/a/b:'
|
||||
assert_equal 200, status
|
||||
assert_body "d"
|
||||
get '/a/b%3a'
|
||||
assert_equal 200, status
|
||||
assert_body "d"
|
||||
|
||||
get '/a/b%3a%20'
|
||||
assert_equal 200, status
|
||||
assert_body "e"
|
||||
get '/a/b%3a+'
|
||||
assert_equal 200, status
|
||||
assert_body "e"
|
||||
end
|
||||
|
||||
it "overrides the content-type in error handlers" do
|
||||
mock_app {
|
||||
before { content_type 'text/plain' }
|
||||
|
|
Loading…
Reference in New Issue