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.
|
# 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(/[\.@]/)
|
ignore << escaped(c).join if c.match(/[\.@]/)
|
||||||
patt = encoded(c)
|
patt = encoded(c)
|
||||||
patt.gsub(/%[\da-fA-F]{2}/) do |match|
|
patt.gsub(/%[\da-fA-F]{2}/) do |match|
|
||||||
|
|
|
@ -99,6 +99,50 @@ class RoutingTest < Minitest::Test
|
||||||
assert_body "foo/bar"
|
assert_body "foo/bar"
|
||||||
end
|
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
|
it "overrides the content-type in error handlers" do
|
||||||
mock_app {
|
mock_app {
|
||||||
before { content_type 'text/plain' }
|
before { content_type 'text/plain' }
|
||||||
|
|
Loading…
Reference in New Issue