From d43ef2e78e6b6a78b6ccbae48efa44af5648bbf3 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Sat, 2 Dec 2017 18:27:04 +0900 Subject: [PATCH] Allow empty path components in a URI [Bug #8352] * generic.rb (URI::Generic#merge, URI::Generic#route_to): Fix a bug where a sequence of slashes in the path part gets collapsed to a single slash. According to the relevant RFCs and WHATWG URL Standard, empty path components are simply valid and there is no special treatment defined for them, so we just keep them as they are. --- lib/uri/generic.rb | 6 +++--- test/uri/test_generic.rb | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/uri/generic.rb b/lib/uri/generic.rb index 044d408f50..ce71b47858 100644 --- a/lib/uri/generic.rb +++ b/lib/uri/generic.rb @@ -979,7 +979,7 @@ def relative? # returns an Array of the path split on '/' # def split_path(path) - path.split(%r{/+}, -1) + path.split(%r{/}, -1) end private :split_path @@ -1154,8 +1154,8 @@ def route_from_path(src, dst) return dst.dup end - src_path = src.scan(%r{(?:\A|[^/]+)/}) - dst_path = dst.scan(%r{(?:\A|[^/]+)/?}) + src_path = src.scan(%r{[^/]*/}) + dst_path = dst.scan(%r{[^/]*/?}) # discard same parts while !dst_path.empty? && dst_path.first == src_path.first diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb index b77717f949..7e428aa849 100644 --- a/test/uri/test_generic.rb +++ b/test/uri/test_generic.rb @@ -208,6 +208,9 @@ def test_merge assert(nil != u.merge!("../baz")) assert_equal('http://foo/baz', u.to_s) + url = URI.parse('http://a/b//c') + 'd//e' + assert_equal('http://a/b//d//e', url.to_s) + u0 = URI.parse('mailto:foo@example.com') u1 = URI.parse('mailto:foo@example.com#bar') assert_equal(uri_to_ary(u0 + '#bar'), uri_to_ary(u1), "[ruby-dev:23628]") @@ -265,6 +268,9 @@ def test_route url = URI.parse('http://hoge/b').route_to('http://hoge/b:c') assert_equal('./b:c', url.to_s) + url = URI.parse('http://hoge/b//c').route_to('http://hoge/b/c') + assert_equal('../c', url.to_s) + url = URI.parse('file:///a/b/').route_to('file:///a/b/') assert_equal('', url.to_s) url = URI.parse('file:///a/b/').route_to('file:///a/b') -- 2.15.0