Bug 1555302 - Ensure that nsStandardURL::Resolve() doesn't parse URLs with a different scheme as relative r=mayhemer

Normally, this method will return the entire in string if it has a scheme.
However, mParser->ParseURL may fail, leading to the scheme to be cleared,
and the result will be the same HTTP URL with the input appended to the
path. This triggers the assertion in NS_NewURI that the scheme should not
change.

As a fix, we bail out of nsStandardURL::Resolve() if the parsed scheme of
the input is different than the base URIs current scheme. This condition
is necessary, because we still need to support a deprecated form of relative
URLs like http:file or http:/path/file

Differential Revision: https://phabricator.services.mozilla.com/D33003

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Valentin Gosu 2019-06-04 13:42:37 +00:00
Родитель 34522cf0c8
Коммит 7d213246fb
3 изменённых файлов: 23 добавлений и 3 удалений

Просмотреть файл

@ -426,7 +426,7 @@
is(url.href, "ftp://tmp/test");
url = new URL("scheme://tmp\\test", base);
is(url.href, "scheme://tmp/test");
is(url.href, "scheme://tmp\\test");
</script>
<script>

Просмотреть файл

@ -2313,6 +2313,20 @@ nsStandardURL::Resolve(const nsACString& in, nsACString& out) {
uint32_t offset = 0;
netCoalesceFlags coalesceFlag = NET_COALESCE_NORMAL;
nsAutoCString baseProtocol(Scheme());
nsAutoCString protocol;
rv = net_ExtractURLScheme(buf, protocol);
// Normally, if we parse a scheme, then it's an absolute URI. But because
// we still support a deprecated form of relative URIs such as: http:file or
// http:/path/file we can't do that for all protocols.
// So we just make sure that if there a protocol, it's the same as the
// current one, otherwise we treat it as an absolute URI.
if (NS_SUCCEEDED(rv) && protocol != baseProtocol) {
out = buf;
return NS_OK;
}
// relative urls should never contain a host, so we always want to use
// the noauth url parser.
// use it to extract a possible scheme
@ -2323,8 +2337,7 @@ nsStandardURL::Resolve(const nsACString& in, nsACString& out) {
// reset the scheme and assume a relative url
if (NS_FAILED(rv)) scheme.Reset();
nsAutoCString protocol(Segment(scheme));
nsAutoCString baseProtocol(Scheme());
protocol.Assign(Segment(scheme));
// We need to do backslash replacement for the following cases:
// 1. The input is an absolute path with a http/https/ftp scheme

Просмотреть файл

@ -633,6 +633,12 @@ function check_mozextension_query() {
Assert.equal(uri.query, "u=https%3A%2F%2Fnews.ycombinator.com%2F");
}
function check_resolve() {
let base = gIoService.newURI("http://example.com");
let uri = gIoService.newURI("tel::+371 27028456", "utf-8", base);
Assert.equal(uri.spec, "tel::+371 27028456");
}
// TEST MAIN FUNCTION
// ------------------
function run_test()
@ -641,6 +647,7 @@ function run_test()
check_space_escaping();
check_schemeIsNull();
check_mozextension_query();
check_resolve();
// UTF-8 check - From bug 622981
// ASCII