diff options
-rw-r--r-- | src/Uri.cpp | 6 | ||||
-rw-r--r-- | test/src/UriTests.cpp | 17 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/Uri.cpp b/src/Uri.cpp index 1a82ee8..e218ecd 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -330,7 +330,11 @@ namespace Uri { bool Uri::ParseFromString(const std::string& uriString) { // First parse the scheme. - const auto schemeEnd = uriString.find(':'); + auto authorityDelimiter = uriString.find("//"); + if (authorityDelimiter == std::string::npos) { + authorityDelimiter = uriString.length(); + } + const auto schemeEnd = uriString.substr(0, authorityDelimiter).find(':'); std::string rest; if (schemeEnd == std::string::npos) { impl_->scheme.clear(); diff --git a/test/src/UriTests.cpp b/test/src/UriTests.cpp index d246a4d..1724b89 100644 --- a/test/src/UriTests.cpp +++ b/test/src/UriTests.cpp @@ -310,3 +310,20 @@ TEST(UriTests, ParseFromStringUserInfoBarelyLegal) { ++index; } } + +TEST(UriTests, ParseFromStringDontMisinterpretColonInAuthorityAsSchemeDelimiter) { + const std::vector< std::string > testVectors{ + {"//foo:bar@www.example.com/"}, + {"//www.example.com/a:b"}, + {"//www.example.com/foo?a:b"}, + {"//www.example.com/foo#a:b"}, + {"//[v7.:]/"}, + }; + size_t index = 0; + for (const auto& testVector : testVectors) { + Uri::Uri uri; + ASSERT_TRUE(uri.ParseFromString(testVector)) << index; + ASSERT_TRUE(uri.GetScheme().empty()); + ++index; + } +} |