# # # patch "NEWS" # from [7c6a6cfd1ef4869eea14ff78dfeff6c0356ca671] # to [88c36d5402452b9ffd6ecb8a02151351497b809b] # # patch "unit-tests/uri.cc" # from [6a59bc8b989d98385aee5ca69195d02bcfae7d7d] # to [2d261643efa47504bb083f0763b71709e0d61f28] # # patch "uri.cc" # from [9f56830b5aaecba242f81dc362fd336eb7fa24cc] # to [7ffeabb888ecd9ab5cf0c15ce659fd750a76e520] # ============================================================ --- NEWS 7c6a6cfd1ef4869eea14ff78dfeff6c0356ca671 +++ NEWS 88c36d5402452b9ffd6ecb8a02151351497b809b @@ -301,6 +301,15 @@ Xxx Xxx 99 99:99:99 UTC 2010 - 'mtn conflicts store' now gives a proper error message when run outside a workspace (fixes monotone bug #30473) + - monotone did not properly parse URIs with paths which missed a + scheme and / or contained a port specification. This has been + fixed. Additionally, if a scheme is specified now, we require + that the scheme is followed by two slashes per RFC 1738, i.e. + "file:path/to/db.mtn" is no longer considered valid, but must be + given as "file://path/to/db.mtn". + (fixes monotone issue 94) + + Sun Jun 13 22:13:53 UTC 2010 0.48 release. ============================================================ --- uri.cc 9f56830b5aaecba242f81dc362fd336eb7fa24cc +++ uri.cc 7ffeabb888ecd9ab5cf0c15ce659fd750a76e520 @@ -112,31 +112,25 @@ parse_uri(string const & in, uri_t & uri // This is a simplified URI grammar. It does the basics. // First there may be a scheme: one or more characters which are not - // ":/?#", followed by a colon. + // ":/?#", followed by a colon and two slashes. stringpos scheme_end = in.find_first_of(":/?#", p); - if (scheme_end != 0 && scheme_end < in.size() && in.at(scheme_end) == ':') + if (scheme_end != 0 && scheme_end + 2 < in.size() + && in.substr(scheme_end, 3) == "://") { uri.scheme.assign(in, p, scheme_end - p); - p = scheme_end + 1; + p = scheme_end + 3; L(FL("matched URI scheme: '%s'") % uri.scheme); } - // Next, there may be an authority: "//" followed by zero or more - // characters which are not "/?#". - - if (p + 1 < in.size() && in.at(p) == '/' && in.at(p+1) == '/') + stringpos authority_end = in.find_first_of("/?#", p); + if (authority_end != p) { - p += 2; - stringpos authority_end = in.find_first_of("/?#", p); - if (authority_end != p) - { - parse_authority(string(in, p, authority_end - p), uri, made_from); - p = authority_end; - } - if (p >= in.size()) - return; + parse_authority(string(in, p, authority_end - p), uri, made_from); + p = authority_end; } + if (p >= in.size()) + return; // Next, a path: zero or more characters which are not "?#". { ============================================================ --- unit-tests/uri.cc 6a59bc8b989d98385aee5ca69195d02bcfae7d7d +++ unit-tests/uri.cc 2d261643efa47504bb083f0763b71709e0d61f28 @@ -25,8 +25,10 @@ test_one_uri(string scheme, { string built; + // we follow the common internet scheme syntax here (sec 3.1 RFC1738) + // i.e. all our URI schemes must start with '//' if given if (!scheme.empty()) - built += scheme + ':'; + built += scheme + "://"; string host; @@ -43,8 +45,6 @@ test_one_uri(string scheme, && host.empty() && port.empty())) { - built += "//"; - if (! user.empty()) built += (user + '@'); @@ -107,6 +107,8 @@ UNIT_TEST(bizarre) UNIT_TEST(bizarre) { + test_one_uri("", "", "", "venge.net", "", "", "", ""); + test_one_uri("", "", "", "venge.net", "4692", "", "", ""); test_one_uri("", "graydon", "", "venge.net", "22", "/tmp/foo.mtn", "", ""); test_one_uri("", "", "", "", "", "/address@hidden:22/tmp/foo.mtn", "", ""); test_one_uri("ssh", "graydon", "", "venge.net", "22", "/tmp/foo.mtn", "", "");