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:
Jeremy Evans 2014-07-03 13:47:52 -07:00 committed by Zachary Scott
parent 6ca8c84517
commit f763e62819
2 changed files with 45 additions and 1 deletions

View File

@ -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|

View File

@ -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' }