Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test runs only with pattern: os != 'android'
- Manifest: browser/components/urlbar/tests/unit/xpcshell.toml
/* Any copyright is dedicated to the Public Domain.
// Tests which icon URLs UrlbarUtils.getRemoteIconUrl hands on as they are and
// which it wraps in `moz-remote-image:` so the image decodes outside the
"use strict";
const SIZE = 16;
// The icon of a rich suggestion, as the search provider sends it.
const DATA_URL =
"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
// A controller whose view renders in a content process, which decodes what it
// displays itself.
const CONTENT_CONTROLLER = { rendersInContentProcess: true };
/**
* Asserts that an icon URL came back wrapped in `moz-remote-image:`.
*
* @param {string} iconUrl
* The URL passed to `getRemoteIconUrl`.
* @param {?string} result
* What `getRemoteIconUrl` returned.
*/
function assertWrapped(iconUrl, result) {
let url = URL.parse(result);
Assert.equal(url?.protocol, "moz-remote-image:", `${iconUrl} is wrapped`);
Assert.equal(
url.searchParams.get("url"),
iconUrl,
"The wrapper carries the original URL"
);
}
add_task(function trustedSchemesPassThrough() {
// These are the browser's own images, so there is nothing to re-encode.
for (let iconUrl of [
"chrome://global/skin/icons/search-glass.svg",
"about:logo",
]) {
Assert.equal(
UrlbarUtils.getRemoteIconUrl(iconUrl, SIZE),
iconUrl,
`${iconUrl} is used as it is`
);
}
});
add_task(function untrustedSchemesAreWrapped() {
for (let iconUrl of [
DATA_URL,
]) {
assertWrapped(iconUrl, UrlbarUtils.getRemoteIconUrl(iconUrl, SIZE));
}
});
add_task(function unexpectedSchemesAreWrapped() {
// A provider can send anything. None of these reach an <img> unwrapped, and
// `moz-remote-image:` produces no image for them.
for (let iconUrl of [
"javascript:alert(1)",
]) {
assertWrapped(iconUrl, UrlbarUtils.getRemoteIconUrl(iconUrl, SIZE));
}
});
add_task(function nonUrlsYieldNull() {
for (let iconUrl of [
"",
"not a url",
"example.com/favicon.ico",
"//host/x",
]) {
Assert.equal(
UrlbarUtils.getRemoteIconUrl(iconUrl, SIZE),
null,
`${iconUrl} is not a URL`
);
}
});
add_task(function contentProcessViewTakesTheIconAsItIs() {
for (let iconUrl of [
DATA_URL,
"chrome://global/skin/icons/search-glass.svg",
]) {
Assert.equal(
UrlbarUtils.getRemoteIconUrl(iconUrl, SIZE, CONTENT_CONTROLLER),
iconUrl,
`${iconUrl} is used as it is`
);
}
// The scheme check the wrapper would apply doesn't apply here, but the page
// still can't load these -- http because its CSP allows only https:, data:,
// blob: and chrome: -- so the row falls back to a broken-image icon.
for (let iconUrl of [
"javascript:alert(1)",
]) {
Assert.equal(
UrlbarUtils.getRemoteIconUrl(iconUrl, SIZE, CONTENT_CONTROLLER),
iconUrl,
`${iconUrl} is used as it is`
);
}
Assert.equal(
UrlbarUtils.getRemoteIconUrl("not a url", SIZE, CONTENT_CONTROLLER),
null,
"A string that isn't a URL is still rejected"
);
});