Index: url/url_canon_relative.cc |
diff --git a/url/url_canon_relative.cc b/url/url_canon_relative.cc |
index 30956a633f7b3ee79ca3a74292ec77026c73a609..0abef40ff860b285b6a36d73b988e02db3e709b8 100644 |
--- a/url/url_canon_relative.cc |
+++ b/url/url_canon_relative.cc |
@@ -100,11 +100,19 @@ bool DoIsRelativeURL(const char* base, |
// BUT: Just because we have a scheme, doesn't make it absolute. |
// "http:foo.html" is a relative URL with path "foo.html". If the scheme is |
// empty, we treat it as relative (":foo") like IE does. |
- url_parse::Component scheme; |
- if (!url_parse::ExtractScheme(url, url_len, &scheme) || scheme.len == 0) { |
- // Don't allow relative URLs if the base scheme doesn't support it. |
- if (!is_base_hierarchical) |
+ url_parse::Parsed url_parsed; |
+ url_parse::ParsePathURL(url, url_len, &url_parsed); |
+ const url_parse::Component& scheme = url_parsed.scheme; |
+ const bool scheme_is_empty = !scheme.is_nonempty(); |
+ if (scheme_is_empty) { |
+ // |url| has no scheme. Check the other extreme: is it a bare fragment. |
+ bool url_is_ref_only = url_parsed.ref.is_valid() && |
+ url_parsed.CountCharactersBefore(url_parse::Parsed::REF, true) == |
+ url_parsed.CountCharactersBefore(url_parse::Parsed::SCHEME, false); |
+ if (!url_is_ref_only && !is_base_hierarchical) { |
+ // Don't allow relative URLs if the base scheme doesn't support it. |
return false; |
+ } |
*relative_component = url_parse::MakeRange(begin, url_len); |
*is_relative = true; |