Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2017-01-16 16:44:15 +01:00
commit 0c21611303
102 changed files with 15045 additions and 14903 deletions

View File

@ -96,6 +96,7 @@ add_task(function* () {
let store = stores.find(store => store.id === tab.cookieStoreId);
browser.test.assertTrue(!!store, "We have a store for this tab.");
browser.test.assertTrue(store.tabIds.includes(tab.id), "tabIds includes this tab.");
await browser.tabs.remove(tab.id);

View File

@ -1668,6 +1668,9 @@ class PPAPIInstance {
case 'setFullscreen':
this.mm.sendAsyncMessage("ppapi.js:setFullscreen", message.fullscreen);
break;
case 'save':
this.mm.sendAsyncMessage("ppapipdf.js:save");
break;
case 'viewport':
case 'rotateClockwise':
case 'rotateCounterclockwise':

View File

@ -194,6 +194,10 @@ class Toolbar {
case 'zoomOut':
this._zoomOut();
break;
case 'download':
case 'secondaryDownload':
this._viewport.save();
break;
case 'pageRotateCw':
this._viewport.rotateClockwise();
break;

View File

@ -419,6 +419,12 @@ class Viewport {
});
}
save() {
this._doAction({
type: 'save'
});
}
// A handler for delivering messages to runtime.
registerActionHandler(handler) {
if (typeof handler === 'function') {

View File

@ -9,7 +9,14 @@
* loaded the plugin lives. It communicates with the process where the PPAPI
* implementation lives.
*/
const { utils: Cu } = Components;
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
let mm = pluginElement.frameLoader.messageManager;
let containerWindow = pluginElement.ownerDocument.defaultView;
@ -92,4 +99,77 @@ mm.addMessageListener("ppapi.js:setFullscreen", ({ data }) => {
}
});
mm.addMessageListener("ppapipdf.js:save", () => {
let url = containerWindow.document.location;
let filename = "document.pdf";
let regex = /[^\/#\?]+\.pdf$/i;
let result = regex.exec(url.hash) ||
regex.exec(url.search) ||
regex.exec(url.pathname);
if (result) {
filename = result[0];
}
let originalUri = NetUtil.newURI(url.href);
let extHelperAppSvc =
Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
getService(Ci.nsIExternalHelperAppService);
let docIsPrivate =
PrivateBrowsingUtils.isContentWindowPrivate(containerWindow);
let netChannel = NetUtil.newChannel({
uri: originalUri,
loadUsingSystemPrincipal: true,
});
if ("nsIPrivateBrowsingChannel" in Ci &&
netChannel instanceof Ci.nsIPrivateBrowsingChannel) {
netChannel.setPrivate(docIsPrivate);
}
NetUtil.asyncFetch(netChannel, function(aInputStream, aResult) {
if (!Components.isSuccessCode(aResult)) {
return;
}
// Create a nsIInputStreamChannel so we can set the url on the channel
// so the filename will be correct.
let channel = Cc["@mozilla.org/network/input-stream-channel;1"].
createInstance(Ci.nsIInputStreamChannel);
channel.QueryInterface(Ci.nsIChannel);
channel.contentDisposition = Ci.nsIChannel.DISPOSITION_ATTACHMENT;
channel.contentDispositionFilename = filename;
channel.setURI(originalUri);
channel.loadInfo = netChannel.loadInfo;
channel.contentStream = aInputStream;
if ("nsIPrivateBrowsingChannel" in Ci &&
channel instanceof Ci.nsIPrivateBrowsingChannel) {
channel.setPrivate(docIsPrivate);
}
let listener = {
extListener: null,
onStartRequest(aRequest, aContext) {
var loadContext = containerWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
this.extListener = extHelperAppSvc.doContent(
"application/pdf", aRequest, loadContext, false);
this.extListener.onStartRequest(aRequest, aContext);
},
onStopRequest(aRequest, aContext, aStatusCode) {
if (this.extListener) {
this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
}
},
onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount) {
this.extListener
.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
}
};
channel.asyncOpen2(listener);
});
});
mm.loadFrameScript("resource://ppapi.js/ppapi-instance.js", true);

View File

@ -9,6 +9,7 @@ support-files =
storage-idb-delete-blocked.html
storage-indexeddb-duplicate-names.html
storage-listings.html
storage-listings-with-fragment.html
storage-localstorage.html
storage-overflow.html
storage-search.html
@ -20,6 +21,7 @@ support-files =
!/devtools/client/framework/test/shared-head.js
[browser_storage_basic.js]
[browser_storage_basic_with_fragment.js]
[browser_storage_cache_delete.js]
[browser_storage_cache_error.js]
[browser_storage_cookies_delete_all.js]

View File

@ -24,7 +24,7 @@
const testCases = [
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("cs2", ".example.org", "/"),
@ -33,7 +33,7 @@ const testCases = [
]
],
[
["cookies", "sectest1.example.org"],
["cookies", "https://sectest1.example.org"],
[
getCookieId("uc1", ".example.org", "/"),
getCookieId("cs2", ".example.org", "/"),
@ -86,8 +86,8 @@ const testCases = [
*/
function testTree() {
let doc = gPanelWindow.document;
for (let item of testCases) {
ok(doc.querySelector("[data-id='" + JSON.stringify(item[0]) + "']"),
for (let [item] of testCases) {
ok(doc.querySelector("[data-id='" + JSON.stringify(item) + "']"),
"Tree item " + item[0] + " should be present in the storage tree");
}
}
@ -107,16 +107,16 @@ function* testTables() {
}
// Click rest of the tree items and wait for the table to be updated
for (let item of testCases.slice(1)) {
yield selectTreeItem(item[0]);
for (let [treeItem, items] of testCases.slice(1)) {
yield selectTreeItem(treeItem);
// Check whether correct number of items are present in the table
is(doc.querySelectorAll(
".table-widget-wrapper:first-of-type .table-widget-cell"
).length, item[1].length, "Number of items in table is correct");
).length, items.length, "Number of items in table is correct");
// Check if all the desired items are present in the table
for (let id of item[1]) {
for (let id of items) {
ok(doc.querySelector(".table-widget-cell[data-id='" + id + "']"),
"Table item " + id + " should be present");
}

View File

@ -0,0 +1,139 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* import-globals-from head.js */
// A second basic test to assert that the storage tree and table corresponding
// to each item in the storage tree is correctly displayed.
// This test differs from browser_storage_basic.js because the URLs we load
// include fragments e.g. http://example.com/test.js#abcdefg
// ^^^^^^^^
// fragment
// Entries that should be present in the tree for this test
// Format for each entry in the array :
// [
// ["path", "to", "tree", "item"], - The path to the tree item to click formed
// by id of each item
// ["key_value1", "key_value2", ...] - The value of the first (unique) column
// for each row in the table corresponding
// to the tree item selected.
// ]
// These entries are formed by the cookies, local storage, session storage and
// indexedDB entries created in storage-listings.html,
// storage-secured-iframe.html and storage-unsecured-iframe.html
"use strict";
const testCases = [
[
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("cs2", ".example.org", "/"),
getCookieId("c3", "test1.example.org", "/"),
getCookieId("uc1", ".example.org", "/")
]
],
[
["cookies", "https://sectest1.example.org"],
[
getCookieId("uc1", ".example.org", "/"),
getCookieId("cs2", ".example.org", "/"),
getCookieId("sc1", "sectest1.example.org", "/browser/devtools/client/storage/test/")
]
],
[["localStorage", "http://test1.example.org"],
["ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
["iframe-s-ls1"]],
[["sessionStorage", "http://test1.example.org"],
["ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org"],
["idb1 (default)", "idb2 (default)"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)"],
["obj1", "obj2"]],
[["indexedDB", "http://test1.example.org", "idb2 (default)"],
["obj3"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
[1, 2, 3]],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj2"],
[1]],
[["indexedDB", "http://test1.example.org", "idb2 (default)", "obj3"],
[]],
[["indexedDB", "http://sectest1.example.org"],
[]],
[["indexedDB", "https://sectest1.example.org"],
["idb-s1 (default)", "idb-s2 (default)"]],
[["indexedDB", "https://sectest1.example.org", "idb-s1 (default)"],
["obj-s1"]],
[["indexedDB", "https://sectest1.example.org", "idb-s2 (default)"],
["obj-s2"]],
[["indexedDB", "https://sectest1.example.org", "idb-s1 (default)", "obj-s1"],
[6, 7]],
[["indexedDB", "https://sectest1.example.org", "idb-s2 (default)", "obj-s2"],
[16]],
[["Cache", "http://test1.example.org", "plop"],
[MAIN_DOMAIN + "404_cached_file.js",
MAIN_DOMAIN + "browser_storage_basic.js"]],
];
/**
* Test that the desired number of tree items are present
*/
function testTree() {
let doc = gPanelWindow.document;
for (let [item] of testCases) {
ok(doc.querySelector("[data-id='" + JSON.stringify(item) + "']"),
"Tree item " + item[0] + " should be present in the storage tree");
}
}
/**
* Test that correct table entries are shown for each of the tree item
*/
function* testTables() {
let doc = gPanelWindow.document;
// Expand all nodes so that the synthesized click event actually works
gUI.tree.expandAll();
// First tree item is already selected so no clicking and waiting for update
for (let id of testCases[0][1]) {
ok(doc.querySelector(".table-widget-cell[data-id='" + id + "']"),
"Table item " + id + " should be present");
}
// Click rest of the tree items and wait for the table to be updated
for (let [treeItem, items] of testCases.slice(1)) {
yield selectTreeItem(treeItem);
// Check whether correct number of items are present in the table
is(doc.querySelectorAll(
".table-widget-wrapper:first-of-type .table-widget-cell"
).length, items.length, "Number of items in table is correct");
// Check if all the desired items are present in the table
for (let id of items) {
ok(doc.querySelector(".table-widget-cell[data-id='" + id + "']"),
"Table item " + id + " should be present");
}
}
}
add_task(function* () {
yield openTabAndSetupStorage(
MAIN_DOMAIN + "storage-listings-with-fragment.html#abc");
testTree();
yield testTables();
yield finishTests();
});

View File

@ -44,7 +44,7 @@ add_task(function* () {
info("test state before delete");
yield checkState([
[
["cookies", "test1.example.org"], [
["cookies", "http://test1.example.org"], [
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("c3", "test1.example.org", "/"),
getCookieId("cs2", ".example.org", "/"),
@ -52,7 +52,7 @@ add_task(function* () {
]
],
[
["cookies", "sectest1.example.org"], [
["cookies", "https://sectest1.example.org"], [
getCookieId("cs2", ".example.org", "/"),
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/client/storage/test/"),
@ -64,20 +64,20 @@ add_task(function* () {
info("delete all from domain");
// delete only cookies that match the host exactly
let id = getCookieId("c1", "test1.example.org", "/browser");
yield performDelete(["cookies", "test1.example.org"], id, false);
yield performDelete(["cookies", "http://test1.example.org"], id, false);
info("test state after delete all from domain");
yield checkState([
// Domain cookies (.example.org) must not be deleted.
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("cs2", ".example.org", "/"),
getCookieId("uc1", ".example.org", "/")
]
],
[
["cookies", "sectest1.example.org"],
["cookies", "https://sectest1.example.org"],
[
getCookieId("cs2", ".example.org", "/"),
getCookieId("uc1", ".example.org", "/"),
@ -90,14 +90,14 @@ add_task(function* () {
info("delete all");
// delete all cookies for host, including domain cookies
id = getCookieId("uc1", ".example.org", "/");
yield performDelete(["cookies", "sectest1.example.org"], id, true);
yield performDelete(["cookies", "http://sectest1.example.org"], id, true);
info("test state after delete all");
yield checkState([
// Domain cookies (.example.org) are deleted too, so deleting in sectest1
// also removes stuff from test1.
[["cookies", "test1.example.org"], []],
[["cookies", "sectest1.example.org"], []],
[["cookies", "http://test1.example.org"], []],
[["cookies", "https://sectest1.example.org"], []],
]);
yield finishTests();

View File

@ -14,7 +14,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("test1", ".test1.example.org", "/browser"),
getCookieId("test2", "test1.example.org", "/browser"),

View File

@ -14,7 +14,7 @@ const TEST_CASES = [
[["sessionStorage", "http://test1.example.org"],
"ss1", "name"],
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
getCookieId("c1", "test1.example.org", "/browser"), "name"
],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],

View File

@ -18,7 +18,7 @@ add_task(function* () {
info("test state before delete");
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("cs2", ".example.org", "/"),
@ -35,7 +35,7 @@ add_task(function* () {
info("do the delete");
const deleteHosts = [
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
["localStorage", "http://test1.example.org"],
["sessionStorage", "http://test1.example.org"],
["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
@ -64,7 +64,7 @@ add_task(function* () {
info("test state after delete");
yield checkState([
[["cookies", "test1.example.org"], []],
[["cookies", "http://test1.example.org"], []],
[["localStorage", "http://test1.example.org"], []],
[["sessionStorage", "http://test1.example.org"], []],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], []],

View File

@ -43,7 +43,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("c2", "test1.example.org", "/browser")
@ -60,7 +60,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("c2", "test1.example.org", "/browser")
@ -78,7 +78,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("c2", "test1.example.org", "/browser"),
@ -100,7 +100,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("c2", "test1.example.org", "/browser"),
@ -122,7 +122,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c2", "test1.example.org", "/browser"),
getCookieId("c3", "test1.example.org",
@ -145,7 +145,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c2", "test1.example.org", "/browser"),
getCookieId("c4", "test1.example.org",
@ -163,7 +163,7 @@ add_task(function* () {
yield checkState([
[
["cookies", "test1.example.org"],
["cookies", "http://test1.example.org"],
[
getCookieId("c4", "test1.example.org",
"/browser/devtools/client/storage/test/")
@ -179,7 +179,7 @@ add_task(function* () {
yield gUI.once("store-objects-updated");
yield checkState([
[["cookies", "test1.example.org"], [ ]],
[["cookies", "http://test1.example.org"], [ ]],
]);
ok(gUI.sidebar.hidden, "Sidebar is hidden when no rows");

View File

@ -16,7 +16,7 @@
const testCases = [
{
location: ["cookies", "sectest1.example.org"],
location: ["cookies", "https://sectest1.example.org"],
sidebarHidden: true
},
{

View File

@ -0,0 +1,134 @@
<!DOCTYPE HTML>
<html>
<!--
This test differs from browser_storage_listings.html only because the URLs we load
include fragments e.g. http://example.com/test.js#abcdefg
^^^^^^^^
fragment
-->
<head>
<meta charset="utf-8">
<title>Storage inspector test for listing hosts and storages with URL fragments</title>
</head>
<body>
<iframe src="http://sectest1.example.org/browser/devtools/client/storage/test/storage-unsecured-iframe.html#def"></iframe>
<iframe src="https://sectest1.example.org:443/browser/devtools/client/storage/test/storage-secured-iframe.html#ghi"></iframe>
<script type="application/javascript;version=1.7">
"use strict";
let partialHostname = location.hostname.match(/^[^.]+(\..*)$/)[1];
let cookieExpiresTime1 = 2000000000000;
let cookieExpiresTime2 = 2000000001000;
// Setting up some cookies to eat.
document.cookie = "c1=foobar; expires=" +
new Date(cookieExpiresTime1).toGMTString() + "; path=/browser";
document.cookie = "cs2=sessionCookie; path=/; domain=" + partialHostname;
document.cookie = "c3=foobar-2; expires=" +
new Date(cookieExpiresTime2).toGMTString() + "; path=/";
// ... and some local storage items ..
localStorage.setItem("ls1", "foobar");
localStorage.setItem("ls2", "foobar-2");
// ... and finally some session storage items too
sessionStorage.setItem("ss1", "foobar-3");
dump("added cookies and storage from main page\n");
let idbGenerator = async function() {
let request = indexedDB.open("idb1", 1);
request.onerror = function() {
throw new Error("error opening db connection");
};
let db = await new Promise(done => {
request.onupgradeneeded = event => {
let db = event.target.result;
let store1 = db.createObjectStore("obj1", { keyPath: "id" });
store1.createIndex("name", "name", { unique: false });
store1.createIndex("email", "email", { unique: true });
let store2 = db.createObjectStore("obj2", { keyPath: "id2" });
store1.transaction.oncomplete = () => {
done(db);
};
};
});
// Prevents AbortError
await new Promise(done => {
request.onsuccess = done;
});
let transaction = db.transaction(["obj1", "obj2"], "readwrite");
let store1 = transaction.objectStore("obj1");
let store2 = transaction.objectStore("obj2");
store1.add({id: 1, name: "foo", email: "foo@bar.com"});
store1.add({id: 2, name: "foo2", email: "foo2@bar.com"});
store1.add({id: 3, name: "foo2", email: "foo3@bar.com"});
store2.add({
id2: 1,
name: "foo",
email: "foo@bar.com",
extra: "baz"
});
// Prevents AbortError during close()
await new Promise(success => {
transaction.oncomplete = success;
});
db.close();
request = indexedDB.open("idb2", 1);
let db2 = await new Promise(done => {
request.onupgradeneeded = event => {
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = () => {
done(db2);
}
};
});
// Prevents AbortError during close()
await new Promise(done => {
request.onsuccess = done;
});
db2.close();
dump("added indexedDB from main page\n");
};
function deleteDB(dbName) {
return new Promise(resolve => {
dump("removing database " + dbName + " from " + document.location + "\n");
indexedDB.deleteDatabase(dbName).onsuccess = resolve;
});
}
async function fetchPut(cache, url) {
let response = await fetch(url);
await cache.put(url, response);
}
let cacheGenerator = async function() {
let cache = await caches.open("plop");
await fetchPut(cache, "404_cached_file.js");
await fetchPut(cache, "browser_storage_basic.js");
};
window.setup = function*() {
yield idbGenerator();
if (window.caches) {
yield cacheGenerator();
}
};
window.clear = function*() {
yield deleteDB("idb1");
yield deleteDB("idb2");
if (window.caches) {
yield caches.delete("plop");
}
dump("removed indexedDB and cache data from " + document.location + "\n");
};
</script>
</body>
</html>

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<!--
Bug 970517 - Storage inspector front end - tests
Storage inspector front end - tests
-->
<head>
<meta charset="utf-8">

View File

@ -126,7 +126,11 @@ StorageActors.defaults = function (typeName, observationTopics) {
get hosts() {
let hosts = new Set();
for (let {location} of this.storageActor.windows) {
hosts.add(this.getHostName(location));
let host = this.getHostName(location);
if (host) {
hosts.add(host);
}
}
return hosts;
},
@ -140,13 +144,35 @@ StorageActors.defaults = function (typeName, observationTopics) {
},
/**
* Converts the window.location object into host.
* Converts the window.location object into a URL (e.g. http://domain.com).
*/
getHostName(location) {
if (location.protocol === "chrome:") {
return location.href;
if (!location) {
// Debugging a legacy Firefox extension... no hostname available and no
// storage possible.
return null;
}
switch (location.protocol) {
case "data:":
// data: URLs do not support storage of any type.
return null;
case "about:":
// Fallthrough.
case "chrome:":
// Fallthrough.
case "file:":
return location.protocol + location.pathname;
case "resource:":
return location.origin + location.pathname;
case "moz-extension:":
return location.origin;
case "javascript:":
return location.href;
default:
// http: or unknown protocol.
return `${location.protocol}//${location.host}`;
}
return location.hostname || location.href;
},
initialize(storageActor) {
@ -206,7 +232,7 @@ StorageActors.defaults = function (typeName, observationTopics) {
*/
onWindowReady: Task.async(function* (window) {
let host = this.getHostName(window.location);
if (!this.hostVsStores.has(host)) {
if (host && !this.hostVsStores.has(host)) {
yield this.populateStoresForHost(host, window);
let data = {};
data[host] = this.getNamesForHost(host);
@ -227,7 +253,7 @@ StorageActors.defaults = function (typeName, observationTopics) {
return;
}
let host = this.getHostName(window.location);
if (!this.hosts.has(host)) {
if (host && !this.hosts.has(host)) {
this.hostVsStores.delete(host);
let data = {};
data[host] = [];
@ -467,12 +493,16 @@ StorageActors.createActor({
if (cookie.host == null) {
return host == null;
}
host = trimHttpHttps(host);
if (cookie.host.startsWith(".")) {
return ("." + host).endsWith(cookie.host);
}
if (cookie.host === "") {
return host.startsWith("file://" + cookie.path);
}
return cookie.host == host;
},
@ -714,6 +744,8 @@ var cookieHelpers = {
host = "";
}
host = trimHttpHttps(host);
let cookies = Services.cookies.getCookiesFromHost(host, originAttributes);
let store = [];
@ -848,6 +880,8 @@ var cookieHelpers = {
opts.path = split[2];
}
host = trimHttpHttps(host);
function hostMatches(cookieHost, matchHost) {
if (cookieHost == null) {
return matchHost == null;
@ -1054,16 +1088,6 @@ function getObjectForLocalOrSessionStorage(type) {
}));
},
getHostName(location) {
if (!location.host) {
return location.href;
}
if (location.protocol === "chrome:") {
return location.href;
}
return location.protocol + "//" + location.host;
},
populateStoresForHost(host, window) {
try {
this.hostVsStores.set(host, window[type]);
@ -1075,7 +1099,10 @@ function getObjectForLocalOrSessionStorage(type) {
populateStoresForHosts() {
this.hostVsStores = new Map();
for (let window of this.windows) {
this.populateStoresForHost(this.getHostName(window.location), window);
let host = this.getHostName(window.location);
if (host) {
this.populateStoresForHost(host, window);
}
}
},
@ -1274,16 +1301,6 @@ StorageActors.createActor({
];
}),
getHostName(location) {
if (!location.host) {
return location.href;
}
if (location.protocol === "chrome:") {
return location.href;
}
return location.protocol + "//" + location.host;
},
populateStoresForHost: Task.async(function* (host) {
let storeMap = new Map();
let caches = yield this.getCachesForHost(host);
@ -1559,16 +1576,6 @@ StorageActors.createActor({
this.removeDBRecord(host, principal, db, store, id);
}),
getHostName(location) {
if (!location.host) {
return location.href;
}
if (location.protocol === "chrome:") {
return location.href;
}
return location.protocol + "//" + location.host;
},
/**
* This method is overriden and left blank as for indexedDB, this operation
* cannot be performed synchronously. Thus, the preListStores method exists to
@ -2409,6 +2416,19 @@ exports.setupParentProcessForIndexedDB = function ({ mm, prefix }) {
};
};
/**
* General helpers
*/
function trimHttpHttps(url) {
if (url.startsWith("http://")) {
return url.substr(7);
}
if (url.startsWith("https://")) {
return url.substr(8);
}
return url;
}
/**
* The main Storage Actor.
*/

View File

@ -11,7 +11,7 @@ const {StorageFront} = require("devtools/shared/fronts/storage");
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/server/tests/browser/storage-helpers.js", this);
const TESTDATA = {
"test1.example.org": [
"http://test1.example.org": [
{
name: "name",
value: "value1",

View File

@ -9,8 +9,8 @@ Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtool
const beforeReload = {
cookies: {
"test1.example.org": ["c1", "cs2", "c3", "uc1"],
"sectest1.example.org": ["uc1", "cs2"]
"http://test1.example.org": ["c1", "cs2", "c3", "uc1"],
"http://sectest1.example.org": ["uc1", "cs2"]
},
localStorage: {
"http://test1.example.org": ["ls1", "ls2"],
@ -99,7 +99,12 @@ function testAddIframe(front) {
"https://sectest1.example.org": ["iframe-s-ss1"]
},
cookies: {
"sectest1.example.org": [
"https://sectest1.example.org": [
getCookieId("cs2", ".example.org", "/"),
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/server/tests/browser/")
],
"http://sectest1.example.org": [
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/server/tests/browser/")
]

View File

@ -9,7 +9,7 @@ Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtool
const storeMap = {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
{
name: "c1",
value: "foobar",
@ -38,7 +38,29 @@ const storeMap = {
isSecure: true,
}
],
"sectest1.example.org": [
"http://sectest1.example.org": [
{
name: "cs2",
value: "sessionCookie",
path: "/",
host: ".example.org",
expires: 0,
isDomain: true,
isSecure: false,
},
{
name: "sc1",
value: "foobar",
path: "/browser/devtools/server/tests/browser/",
host: "sectest1.example.org",
expires: 0,
isDomain: false,
isSecure: false,
}
],
"https://sectest1.example.org": [
{
name: "uc1",
value: "foobar",
@ -328,7 +350,7 @@ function* testStores(data) {
}
function testCookies(cookiesActor) {
is(Object.keys(cookiesActor.hosts).length, 2,
is(Object.keys(cookiesActor.hosts).length, 3,
"Correct number of host entries for cookies");
return testCookiesObjects(0, cookiesActor.hosts, cookiesActor);
}

View File

@ -6,7 +6,7 @@
const {StorageFront} = require("devtools/shared/fronts/storage");
const beforeReload = {
cookies: ["test1.example.org", "sectest1.example.org"],
cookies: ["http://test1.example.org", "https://sectest1.example.org"],
localStorage: ["http://test1.example.org", "http://sectest1.example.org"],
sessionStorage: ["http://test1.example.org", "http://sectest1.example.org"],
};
@ -27,7 +27,7 @@ const TESTS = [
expected: {
added: {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
getCookieId("c1", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
getCookieId("c2", "test1.example.org",
@ -53,7 +53,7 @@ const TESTS = [
expected: {
changed: {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
getCookieId("c1", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
@ -82,7 +82,7 @@ const TESTS = [
expected: {
deleted: {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
getCookieId("c2", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
@ -123,7 +123,7 @@ const TESTS = [
expected: {
added: {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
getCookieId("c3", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
@ -139,7 +139,7 @@ const TESTS = [
},
deleted: {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
getCookieId("c1", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]
@ -175,7 +175,7 @@ const TESTS = [
expected: {
deleted: {
cookies: {
"test1.example.org": [
"http://test1.example.org": [
getCookieId("c3", "test1.example.org",
"/browser/devtools/server/tests/browser/"),
]

View File

@ -910,8 +910,8 @@ EffectCompositor::GetBaseStyle(nsCSSPropertyID aProperty,
RefPtr<nsStyleContext> styleContextWithoutAnimation =
aStyleContext->PresContext()->StyleSet()->AsGecko()->
ResolveStyleWithoutAnimation(&aElement, aStyleContext,
eRestyle_AllHintsWithAnimations);
ResolveStyleByRemovingAnimation(&aElement, aStyleContext,
eRestyle_AllHintsWithAnimations);
DebugOnly<bool> success =
StyleAnimationValue::ExtractComputedValue(aProperty,

View File

@ -277,6 +277,8 @@ KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
// Skip updating properties when we are composing style.
// FIXME: Bug 1324966. Drop this check once we have a function to get
// nsStyleContext without resolving animating style.
MOZ_DIAGNOSTIC_ASSERT(!mIsComposingStyle,
"Should not be called while processing ComposeStyle()");
if (mIsComposingStyle) {
return;
}
@ -363,7 +365,8 @@ KeyframeEffectReadOnly::GetUnderlyingStyle(
// If we are composing with composite operation that is not 'replace'
// and we have not composed style for the property yet, we have to get
// the base style for the property.
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
RefPtr<nsStyleContext> styleContext =
GetTargetStyleContextWithoutAnimation();
result = EffectCompositor::GetBaseStyle(aProperty,
styleContext,
*mTarget->mElement,
@ -443,7 +446,7 @@ KeyframeEffectReadOnly::EnsureBaseStylesForCompositor(
}
if (!styleContext) {
styleContext = GetTargetStyleContext();
styleContext = GetTargetStyleContextWithoutAnimation();
}
MOZ_RELEASE_ASSERT(styleContext);
@ -464,6 +467,8 @@ KeyframeEffectReadOnly::ComposeStyle(
RefPtr<AnimValuesStyleRule>& aStyleRule,
const nsCSSPropertyIDSet& aPropertiesToSkip)
{
MOZ_DIAGNOSTIC_ASSERT(!mIsComposingStyle,
"Should not be called recursively");
if (mIsComposingStyle) {
return;
}
@ -900,8 +905,9 @@ KeyframeEffectReadOnly::RequestRestyle(
}
}
template<KeyframeEffectReadOnly::AnimationStyle aAnimationStyle>
already_AddRefed<nsStyleContext>
KeyframeEffectReadOnly::GetTargetStyleContext()
KeyframeEffectReadOnly::DoGetTargetStyleContext()
{
nsIPresShell* shell = GetPresShell();
if (!shell) {
@ -914,8 +920,27 @@ KeyframeEffectReadOnly::GetTargetStyleContext()
nsIAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count
? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
: nullptr;
return nsComputedDOMStyle::GetStyleContextForElement(mTarget->mElement,
pseudo, shell);
if (aAnimationStyle == AnimationStyle::Include) {
return nsComputedDOMStyle::GetStyleContextForElement(mTarget->mElement,
pseudo,
shell);
}
return nsComputedDOMStyle::GetStyleContextForElementWithoutAnimation(
mTarget->mElement, pseudo, shell);
}
already_AddRefed<nsStyleContext>
KeyframeEffectReadOnly::GetTargetStyleContext()
{
return DoGetTargetStyleContext<AnimationStyle::Include>();
}
already_AddRefed<nsStyleContext>
KeyframeEffectReadOnly::GetTargetStyleContextWithoutAnimation()
{
return DoGetTargetStyleContext<AnimationStyle::Skip>();
}
#ifdef DEBUG

View File

@ -409,8 +409,19 @@ protected:
// context. That's because calling GetStyleContextForElement when we are in
// the process of building a style context may trigger various forms of
// infinite recursion.
already_AddRefed<nsStyleContext> GetTargetStyleContext();
// Similar to the above but ignoring animation rules. We use this to get base
// styles (which don't include animation rules).
already_AddRefed<nsStyleContext>
GetTargetStyleContext();
GetTargetStyleContextWithoutAnimation();
enum AnimationStyle {
Skip,
Include
};
template<AnimationStyle aAnimationStyle>
already_AddRefed<nsStyleContext> DoGetTargetStyleContext();
// A wrapper for marking cascade update according to the current
// target and its effectSet.

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html class="reftest-wait">
<span id=a />
<script>
addEventListener("DOMContentLoaded", function(){
a.animate([{"left": "38%"}], 100);
a.appendChild(document.createElement("div"));
document.documentElement.classList.remove("reftest-wait");
});
</script>
</html>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<style>
@keyframes anim {
}
#o_0:before {
animation: anim 10s;
}
</style>
<meta charset="UTF-8">
<script>
function boom(){
function getPseudoElement() {
var anim = document.getAnimations()[0];
anim.cancel();
return anim.effect.target;
}
var target = getPseudoElement();
target.animate([{"perspective": "262ex"}, {}], {duration: 1070, iterationStart: 68, iterationComposite: "accumulate"});
target.animate([{"color": "white", "flex": "inherit"}, {"color": "red", "flex": "66% "}], 3439);
target.animate([{"font": "icon"}], 1849);
setTimeout(function() {
document.documentElement.classList.remove("reftest-wait");
}, 500);
}
document.addEventListener("DOMContentLoaded", boom);
</script>
</head>
<body>
<div id=o_0></div>
</body>
</html>

View File

@ -17,5 +17,7 @@ skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1322291-1.html #
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1322291-2.html # bug 1311257
asserts-if(stylo,0-5) pref(dom.animations-api.core.enabled,true) load 1323114-1.html # bug 1324690
asserts-if(stylo,0-5) pref(dom.animations-api.core.enabled,true) load 1323114-2.html # bug 1324690
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330513-1.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1325193-1.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330190-1.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330190-2.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330513-1.html # bug 1311257

View File

@ -368,8 +368,11 @@ ScreenOrientation::LockDeviceOrientation(ScreenOrientationInternal aOrientation,
}
// We are fullscreen and lock has been accepted.
if (aIsFullScreen && !mFullScreenListener) {
mFullScreenListener = new FullScreenEventListener();
if (aIsFullScreen) {
if (!mFullScreenListener) {
mFullScreenListener = new FullScreenEventListener();
}
aRv = target->AddSystemEventListener(NS_LITERAL_STRING("fullscreenchange"),
mFullScreenListener, /* useCapture = */ true);
if (NS_WARN_IF(aRv.Failed())) {

View File

@ -126,6 +126,7 @@ private:
DECL_MEDIA_PREF("media.decoder-doctor.wmf-disabled-is-failure", DecoderDoctorWMFDisabledIsFailure, bool, false);
DECL_MEDIA_PREF("media.wmf.vp9.enabled", PDMWMFVP9DecoderEnabled, bool, true);
DECL_MEDIA_PREF("media.wmf.decoder.thread-count", PDMWMFThreadCount, int32_t, -1);
DECL_MEDIA_PREF("media.wmf.allow-unsupported-resolutions", PDMWMFAllowUnsupportedResolutions, bool, false);
#endif
DECL_MEDIA_PREF("media.decoder.fuzzing.enabled", PDMFuzzingEnabled, bool, false);
DECL_MEDIA_PREF("media.decoder.fuzzing.video-output-minimum-interval-ms", PDMFuzzingInterval, uint32_t, 0);

View File

@ -129,7 +129,7 @@ VP8TrackEncoder::Init(int32_t aWidth, int32_t aHeight, int32_t aDisplayWidth,
// rate control settings
config.rc_dropframe_thresh = 0;
config.rc_end_usage = VPX_CBR;
config.rc_end_usage = VPX_VBR;
config.g_pass = VPX_RC_ONE_PASS;
// ffmpeg doesn't currently support streams that use resize.
// Therefore, for safety, we should turn it off until it does.

View File

@ -20,6 +20,7 @@
#endif
#include "nsAutoPtr.h"
#include "SourceBufferResource.h"
#include <algorithm>
extern mozilla::LogModule* GetMediaSourceSamplesLog();
@ -348,6 +349,9 @@ public:
// Each MP4 atom has a chunk size and chunk type. The root chunk in an MP4
// file is the 'ftyp' atom followed by a file type. We just check for a
// vaguely valid 'ftyp' atom.
if (aData->Length() < 8) {
return NS_ERROR_NOT_AVAILABLE;
}
AtomParser parser(mType, aData);
if (!parser.IsValid()) {
return MediaResult(
@ -359,6 +363,9 @@ public:
MediaResult IsMediaSegmentPresent(MediaByteBuffer* aData) override
{
if (aData->Length() < 8) {
return NS_ERROR_NOT_AVAILABLE;
}
AtomParser parser(mType, aData);
if (!parser.IsValid()) {
return MediaResult(
@ -396,20 +403,15 @@ private:
MSE_DEBUGV(AtomParser ,"Checking atom:'%c%c%c%c' @ %u",
typec[0], typec[1], typec[2], typec[3],
(uint32_t)reader.Offset() - 8);
for (const auto& boxType : validBoxes) {
if (type == boxType) {
mValid = true;
break;
}
}
if (!mValid) {
// No point continuing.
if (std::find(std::begin(validBoxes), std::end(validBoxes), type)
== std::end(validBoxes)) {
// No valid box found, no point continuing.
mLastInvalidBox[0] = typec[0];
mLastInvalidBox[1] = typec[1];
mLastInvalidBox[2] = typec[2];
mLastInvalidBox[3] = typec[3];
mLastInvalidBox[4] = '\0';
mValid = false;
break;
}
if (mInitOffset.isNothing() &&
@ -458,7 +460,7 @@ private:
private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
bool mValid = false;
bool mValid = true;
char mLastInvalidBox[5];
};

View File

@ -210,7 +210,9 @@ WMFDecoderModule::Supports(const TrackInfo& aTrackInfo,
WMFDecoderModule::HasAAC()) {
return true;
}
if (MP4Decoder::IsH264(aTrackInfo.mMimeType) && WMFDecoderModule::HasH264()) {
if (MP4Decoder::IsH264(aTrackInfo.mMimeType) &&
WMFDecoderModule::HasH264() &&
!MediaPrefs::PDMWMFAllowUnsupportedResolutions()) {
const VideoInfo* videoInfo = aTrackInfo.GetAsVideoInfo();
MOZ_ASSERT(videoInfo);
// Check Windows format constraints, based on:

View File

@ -270,6 +270,10 @@ Compositor::DrawGeometry(const gfx::Rect& aRect,
const gfx::Rect& aVisibleRect,
const Maybe<gfx::Polygon>& aGeometry)
{
if (aRect.IsEmpty()) {
return;
}
if (!aGeometry || !SupportsLayerGeometry()) {
DrawQuad(aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect);
@ -283,7 +287,37 @@ Compositor::DrawGeometry(const gfx::Rect& aRect,
const gfx::Polygon clipped = aGeometry->ClipPolygon(aRect);
for (gfx::Triangle& triangle : clipped.ToTriangles()) {
DrawPolygon(clipped, aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect);
}
void
Compositor::DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
for (const gfx::TexturedTriangle& triangle : aTriangles) {
DrawTriangle(triangle, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect);
}
}
void
Compositor::DrawPolygon(const gfx::Polygon& aPolygon,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
nsTArray<gfx::TexturedTriangle> texturedTriangles;
for (gfx::Triangle& triangle : aPolygon.ToTriangles()) {
const gfx::Rect intersection = aRect.Intersect(triangle.BoundingBox());
// Cull invisible triangles.
@ -311,9 +345,11 @@ Compositor::DrawGeometry(const gfx::Rect& aRect,
texturedEffect->mTextureCoords);
}
DrawTriangle(texturedTriangle, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect);
texturedTriangles.AppendElement(Move(texturedTriangle));
}
DrawTriangles(texturedTriangles, aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect);
}
void

View File

@ -621,6 +621,21 @@ protected:
gfx::Matrix4x4* aOutTransform,
gfx::Rect* aOutLayerQuad = nullptr);
virtual void DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect);
virtual void DrawPolygon(const gfx::Polygon& aPolygon,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect);
/**
* An array of locks that will need to be unlocked after the next composition.

View File

@ -356,15 +356,100 @@ BasicCompositor::SupportsEffect(EffectTypes aEffect)
return aEffect != EffectTypes::YCBCR && aEffect != EffectTypes::COMPONENT_ALPHA;
}
bool
BasicCompositor::SupportsLayerGeometry() const
{
return gfxPrefs::BasicLayerGeometry();
}
static RefPtr<gfx::Path>
BuildPathFromPolygon(const RefPtr<DrawTarget>& aDT,
const gfx::Polygon& aPolygon)
{
RefPtr<PathBuilder> pathBuilder = aDT->CreatePathBuilder();
const nsTArray<Point4D>& points = aPolygon.GetPoints();
pathBuilder->MoveTo(points[0].As2DPoint());
for (size_t i = 1; i < points.Length(); ++i) {
pathBuilder->LineTo(points[i].As2DPoint());
}
pathBuilder->Close();
return pathBuilder->Finish();
}
static void
DrawSurfaceWithTextureCoords(DrawTarget *aDest,
DrawSurface(gfx::DrawTarget* aDest,
const gfx::Rect& aDestRect,
const gfx::Rect& /* aClipRect */,
const gfx::Color& aColor,
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform)
{
FillRectWithMask(aDest, aDestRect, aColor,
aOptions, aMask, aMaskTransform);
}
static void
DrawSurface(gfx::DrawTarget* aDest,
const gfx::Polygon& aPolygon,
const gfx::Rect& aClipRect,
const gfx::Color& aColor,
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform)
{
RefPtr<Path> path = BuildPathFromPolygon(aDest, aPolygon);
FillPathWithMask(aDest, path, aClipRect, aColor,
aOptions, aMask, aMaskTransform);
}
static void
DrawTextureSurface(gfx::DrawTarget* aDest,
const gfx::Rect& aDestRect,
const gfx::Rect& /* aClipRect */,
gfx::SourceSurface* aSource,
gfx::SamplingFilter aSamplingFilter,
const gfx::DrawOptions& aOptions,
ExtendMode aExtendMode,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform,
const Matrix* aSurfaceTransform)
{
FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
aExtendMode, aMask, aMaskTransform, aSurfaceTransform);
}
static void
DrawTextureSurface(gfx::DrawTarget* aDest,
const gfx::Polygon& aPolygon,
const gfx::Rect& aClipRect,
gfx::SourceSurface* aSource,
gfx::SamplingFilter aSamplingFilter,
const gfx::DrawOptions& aOptions,
ExtendMode aExtendMode,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform,
const Matrix* aSurfaceTransform)
{
RefPtr<Path> path = BuildPathFromPolygon(aDest, aPolygon);
FillPathWithMask(aDest, path, aClipRect, aSource, aSamplingFilter, aOptions,
aExtendMode, aMask, aMaskTransform, aSurfaceTransform);
}
template<typename Geometry>
static void
DrawSurfaceWithTextureCoords(gfx::DrawTarget* aDest,
const Geometry& aGeometry,
const gfx::Rect& aDestRect,
SourceSurface *aSource,
gfx::SourceSurface* aSource,
const gfx::Rect& aTextureCoords,
gfx::SamplingFilter aSamplingFilter,
const DrawOptions& aOptions,
SourceSurface *aMask,
const Matrix* aMaskTransform)
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform)
{
if (!aSource) {
gfxWarning() << "DrawSurfaceWithTextureCoords problem " << gfx::hexa(aSource) << " and " << gfx::hexa(aMask);
@ -392,8 +477,8 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest,
gfx::Rect unitRect(0, 0, 1, 1);
ExtendMode mode = unitRect.Contains(aTextureCoords) ? ExtendMode::CLAMP : ExtendMode::REPEAT;
FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
mode, aMask, aMaskTransform, &matrix);
DrawTextureSurface(aDest, aGeometry, aDestRect, aSource, aSamplingFilter,
aOptions, mode, aMask, aMaskTransform, &matrix);
}
static void
@ -552,6 +637,35 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
DrawGeometry(aRect, aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect, true);
}
void
BasicCompositor::DrawPolygon(const gfx::Polygon& aPolygon,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
DrawGeometry(aPolygon, aRect, aClipRect, aEffectChain,
aOpacity, aTransform, aVisibleRect, false);
}
template<typename Geometry>
void
BasicCompositor::DrawGeometry(const Geometry& aGeometry,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect,
const bool aEnableAA)
{
RefPtr<DrawTarget> buffer = mRenderTarget->mDrawTarget;
@ -613,6 +727,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode;
}
const AntialiasMode aaMode =
aEnableAA ? AntialiasMode::DEFAULT : AntialiasMode::NONE;
DrawOptions drawOptions(aOpacity, blendMode, aaMode);
switch (aEffectChain.mPrimaryEffect->mType) {
case EffectTypes::SOLID_COLOR: {
EffectSolidColor* effectSolidColor =
@ -623,8 +742,8 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
dest->PushClipRect(aRect);
}
FillRectWithMask(dest, aRect, effectSolidColor->mColor,
DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform);
DrawSurface(dest, aGeometry, aRect, effectSolidColor->mColor,
drawOptions, sourceMask, &maskTransform);
if (unboundedOp) {
dest->PopClip();
@ -654,11 +773,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
dest, buffer)) {
// we succeeded in scaling
} else {
DrawSurfaceWithTextureCoords(dest, aRect,
DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
source->GetSurface(dest),
texturedEffect->mTextureCoords,
texturedEffect->mSamplingFilter,
DrawOptions(aOpacity, blendMode),
drawOptions,
sourceMask, &maskTransform);
}
} else if (source) {
@ -670,11 +789,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
// This might be better with a cache, eventually.
RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData);
DrawSurfaceWithTextureCoords(dest, aRect,
DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
premultData,
texturedEffect->mTextureCoords,
texturedEffect->mSamplingFilter,
DrawOptions(aOpacity, blendMode),
drawOptions,
sourceMask, &maskTransform);
}
} else {
@ -694,11 +813,11 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
= static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get());
RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot();
DrawSurfaceWithTextureCoords(dest, aRect,
DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
sourceSurf,
effectRenderTarget->mTextureCoords,
effectRenderTarget->mSamplingFilter,
DrawOptions(aOpacity, blendMode),
drawOptions,
sourceMask, &maskTransform);
break;
}

View File

@ -9,6 +9,8 @@
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Triangle.h"
#include "mozilla/gfx/Polygon.h"
namespace mozilla {
namespace layers {
@ -80,6 +82,8 @@ public:
virtual bool SupportsEffect(EffectTypes aEffect) override;
bool SupportsLayerGeometry() const override;
virtual void SetRenderTarget(CompositingRenderTarget *aSource) override
{
mRenderTarget = static_cast<BasicCompositingRenderTarget*>(aSource);
@ -111,7 +115,7 @@ public:
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override { return true; }
virtual int32_t GetMaxTextureSize() const override;
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override { }
virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) override {
}
@ -136,6 +140,24 @@ public:
private:
template<typename Geometry>
void DrawGeometry(const Geometry& aGeometry,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect,
const bool aEnableAA);
virtual void DrawPolygon(const gfx::Polygon& aPolygon,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) override;
void TryToEndRemoteDrawing(bool aForceToEnd = false);
bool NeedsToDeferEndRemoteDrawing();

View File

@ -206,6 +206,68 @@ FillRectWithMask(DrawTarget* aDT,
ExtendMode::CLAMP);
}
void
FillPathWithMask(DrawTarget* aDT,
const Path* aPath,
const Rect& aClipRect,
const Color& aColor,
const DrawOptions& aOptions,
SourceSurface* aMaskSource,
const Matrix* aMaskTransform)
{
if (aMaskSource && aMaskTransform) {
aDT->PushClipRect(aClipRect);
Matrix oldTransform = aDT->GetTransform();
aDT->SetTransform(*aMaskTransform);
aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
aDT->SetTransform(oldTransform);
aDT->PopClip();
return;
}
aDT->Fill(aPath, ColorPattern(aColor), aOptions);
}
void
FillPathWithMask(DrawTarget* aDT,
const Path* aPath,
const Rect& aClipRect,
SourceSurface* aSurface,
SamplingFilter aSamplingFilter,
const DrawOptions& aOptions,
ExtendMode aExtendMode,
SourceSurface* aMaskSource,
const Matrix* aMaskTransform,
const Matrix* aSurfaceTransform)
{
if (aMaskSource && aMaskTransform) {
aDT->PushClipRect(aClipRect);
Matrix oldTransform = aDT->GetTransform();
Matrix inverseMask = *aMaskTransform;
inverseMask.Invert();
Matrix transform = oldTransform * inverseMask;
if (aSurfaceTransform) {
transform = (*aSurfaceTransform) * transform;
}
SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);
aDT->SetTransform(*aMaskTransform);
aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
aDT->SetTransform(oldTransform);
aDT->PopClip();
return;
}
aDT->Fill(aPath,
SurfacePattern(aSurface, aExtendMode,
aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
aSamplingFilter), aOptions);
}
BasicImplData*
ToData(Layer* aLayer)
{

View File

@ -127,6 +127,26 @@ FillRectWithMask(gfx::DrawTarget* aDT,
const gfx::DrawOptions& aOptions,
Layer* aMaskLayer);
void
FillPathWithMask(gfx::DrawTarget* aDT,
const gfx::Path* aPath,
const gfx::Rect& aClipRect,
const gfx::Color& aColor,
const gfx::DrawOptions& aOptions,
gfx::SourceSurface* aMaskSource = nullptr,
const gfx::Matrix* aMaskTransform = nullptr);
void
FillPathWithMask(gfx::DrawTarget* aDT,
const gfx::Path* aPath,
const gfx::Rect& aClipRect,
gfx::SourceSurface* aSurface,
gfx::SamplingFilter aSamplingFilter,
const gfx::DrawOptions& aOptions,
gfx::ExtendMode aExtendMode,
gfx::SourceSurface* aMaskSource,
const gfx::Matrix* aMaskTransform,
const gfx::Matrix* aSurfaceTransform);
BasicImplData*
ToData(Layer* aLayer);

View File

@ -429,9 +429,9 @@ RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager,
// should only occur transiently.
EffectChain effectChain(layer);
effectChain.mPrimaryEffect = new EffectSolidColor(color);
aManager->GetCompositor()->DrawQuad(gfx::Rect(layer->GetLayerBounds()), clipRect,
effectChain, layer->GetEffectiveOpacity(),
layer->GetEffectiveTransform());
aManager->GetCompositor()->DrawGeometry(gfx::Rect(layer->GetLayerBounds()), clipRect,
effectChain, layer->GetEffectiveOpacity(),
layer->GetEffectiveTransform(), Nothing());
}
if (layerToRender->HasLayerBeenComposited()) {

View File

@ -527,6 +527,7 @@ private:
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, true);
DECL_GFX_PREF(Live, "layers.draw-mask-debug", DrawMaskLayer, bool, false);
DECL_GFX_PREF(Live, "layers.geometry.opengl.enabled", OGLLayerGeometry, bool, false);
DECL_GFX_PREF(Live, "layers.geometry.basic.enabled", BasicLayerGeometry, bool, false);
DECL_GFX_PREF(Live, "layout.animation.prerender.partial", PartiallyPrerenderAnimatedContent, bool, false);
DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-x", AnimationPrerenderViewportRatioLimitX, float, 1.125f);

View File

@ -1,986 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et ft=cpp: tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <fcntl.h>
#include <limits.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define KEYSTORE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
#else
#define KEYSTORE_LOG(args...) printf(args);
#endif
#include "KeyStore.h"
#include "jsfriendapi.h"
#include "KeyStoreConnector.h"
#include "MainThreadUtils.h" // For NS_IsMainThread.
#include "nsICryptoHash.h"
#include "plbase64.h"
#include "certdb.h"
#include "ScopedNSSTypes.h"
using namespace mozilla::ipc;
#if ANDROID_VERSION >= 18
// After Android 4.3, it uses binder to access keystore instead of unix socket.
#include <android/log.h>
#include <binder/BinderService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <security/keystore/include/keystore/IKeystoreService.h>
#include <security/keystore/include/keystore/keystore.h>
using namespace android;
namespace android {
// This class is used to make compiler happy.
class BpKeystoreService : public BpInterface<IKeystoreService>
{
public:
BpKeystoreService(const sp<IBinder>& impl)
: BpInterface<IKeystoreService>(impl)
{
}
virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {return 0;}
virtual int32_t test() {return 0;}
virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid, int32_t flags) {return 0;}
virtual int32_t del(const String16& name, int uid) {return 0;}
virtual int32_t exist(const String16& name, int uid) {return 0;}
virtual int32_t saw(const String16& name, int uid, Vector<String16>* matches) {return 0;}
virtual int32_t reset() {return 0;}
virtual int32_t password(const String16& password) {return 0;}
virtual int32_t lock() {return 0;}
virtual int32_t unlock(const String16& password) {return 0;}
virtual int32_t zero() {return 0;}
virtual int32_t import(const String16& name, const uint8_t* data, size_t length, int uid, int32_t flags) {return 0;}
virtual int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, size_t* outLength) {return 0;}
virtual int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, const uint8_t* signature, size_t signatureLength) {return 0;}
virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {return 0;}
virtual int32_t del_key(const String16& name, int uid) {return 0;}
virtual int32_t grant(const String16& name, int32_t granteeUid) {return 0;}
virtual int32_t ungrant(const String16& name, int32_t granteeUid) {return 0;}
virtual int64_t getmtime(const String16& name) {return 0;}
virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, int32_t destUid) {return 0;}
virtual int32_t clear_uid(int64_t uid) {return 0;}
#if ANDROID_VERSION >= 21
virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return 0;}
virtual int32_t is_hardware_backed(const String16& keyType) {return 0;}
virtual int32_t reset_uid(int32_t uid) {return 0;}
virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {return 0;}
virtual int32_t password_uid(const String16& password, int32_t uid) {return 0;}
#elif ANDROID_VERSION == 18
virtual int32_t generate(const String16& name, int uid, int32_t flags) {return 0;}
virtual int32_t is_hardware_backed() {return 0;}
#else
virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return 0;}
virtual int32_t is_hardware_backed(const String16& keyType) {return 0;}
#endif
};
IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
// Here comes binder requests.
status_t BnKeystoreService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case TEST: {
CHECK_INTERFACE(IKeystoreService, data, reply);
reply->writeNoException();
reply->writeInt32(test());
return NO_ERROR;
} break;
case GET: {
CHECK_INTERFACE(IKeystoreService, data, reply);
String16 name = data.readString16();
String8 tmp(name);
uint8_t* data = NULL;
size_t dataLength = 0;
int32_t ret = get(name, &data, &dataLength);
reply->writeNoException();
if (ret == 1) {
reply->writeInt32(dataLength);
void* buf = reply->writeInplace(dataLength);
memcpy(buf, data, dataLength);
free(data);
} else {
reply->writeInt32(-1);
}
return NO_ERROR;
} break;
case GET_PUBKEY: {
CHECK_INTERFACE(IKeystoreService, data, reply);
String16 name = data.readString16();
uint8_t* data = nullptr;
size_t dataLength = 0;
int32_t ret = get_pubkey(name, &data, &dataLength);
reply->writeNoException();
if (dataLength > 0 && data != nullptr) {
reply->writeInt32(dataLength);
void* buf = reply->writeInplace(dataLength);
memcpy(buf, data, dataLength);
free(data);
} else {
reply->writeInt32(-1);
}
reply->writeInt32(ret);
return NO_ERROR;
} break;
case SIGN: {
CHECK_INTERFACE(IKeystoreService, data, reply);
String16 name = data.readString16();
ssize_t signDataSize = data.readInt32();
const uint8_t *signData = nullptr;
if (signDataSize >= 0 && (size_t)signDataSize <= data.dataAvail()) {
signData = (const uint8_t *)data.readInplace(signDataSize);
}
uint8_t *signResult = nullptr;
size_t signResultSize;
int32_t ret = sign(name, signData, (size_t)signDataSize, &signResult,
&signResultSize);
reply->writeNoException();
if (signResultSize > 0 && signResult != nullptr) {
reply->writeInt32(signResultSize);
void* buf = reply->writeInplace(signResultSize);
memcpy(buf, signResult, signResultSize);
free(signResult);
} else {
reply->writeInt32(-1);
}
reply->writeInt32(ret);
return NO_ERROR;
} break;
default:
return NO_ERROR;
}
}
// Provide service for binder.
class KeyStoreService : public BnKeystoreService
, public nsNSSShutDownObject
{
public:
int32_t test() {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!mozilla::ipc::checkPermission(callingUid)) {
return ::PERMISSION_DENIED;
}
return ::NO_ERROR;
}
int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return ::SYSTEM_ERROR;
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!mozilla::ipc::checkPermission(callingUid)) {
return ::PERMISSION_DENIED;
}
String8 certName(name);
if (!strncmp(certName.string(), "WIFI_USERKEY_", 13)) {
return getPrivateKey(certName.string(), (const uint8_t**)item, itemLength);
}
return getCertificate(certName.string(), (const uint8_t**)item, itemLength);
}
int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid, int32_t flags) {return ::UNDEFINED_ACTION;}
int32_t del(const String16& name, int uid) {return ::UNDEFINED_ACTION;}
int32_t exist(const String16& name, int uid) {return ::UNDEFINED_ACTION;}
int32_t saw(const String16& name, int uid, Vector<String16>* matches) {return ::UNDEFINED_ACTION;}
int32_t reset() {return ::UNDEFINED_ACTION;}
int32_t password(const String16& password) {return ::UNDEFINED_ACTION;}
int32_t lock() {return ::UNDEFINED_ACTION;}
int32_t unlock(const String16& password) {return ::UNDEFINED_ACTION;}
int32_t zero() {return ::UNDEFINED_ACTION;}
int32_t import(const String16& name, const uint8_t* data, size_t length, int uid, int32_t flags) {return ::UNDEFINED_ACTION;}
int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, size_t* outLength)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return ::SYSTEM_ERROR;
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!mozilla::ipc::checkPermission(callingUid)) {
return ::PERMISSION_DENIED;
}
if (data == nullptr) {
return ::SYSTEM_ERROR;
}
String8 keyName(name);
if (!strncmp(keyName.string(), "WIFI_USERKEY_", 13)) {
return signData(keyName.string(), data, length, out, outLength);
}
return ::UNDEFINED_ACTION;
}
int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, const uint8_t* signature, size_t signatureLength) {return ::UNDEFINED_ACTION;}
int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return ::SYSTEM_ERROR;
}
uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!mozilla::ipc::checkPermission(callingUid)) {
return ::PERMISSION_DENIED;
}
String8 keyName(name);
if (!strncmp(keyName.string(), "WIFI_USERKEY_", 13)) {
return getPublicKey(keyName.string(), (const uint8_t**)pubkey, pubkeyLength);
}
return ::UNDEFINED_ACTION;
}
int32_t del_key(const String16& name, int uid) {return ::UNDEFINED_ACTION;}
int32_t grant(const String16& name, int32_t granteeUid) {return ::UNDEFINED_ACTION;}
int32_t ungrant(const String16& name, int32_t granteeUid) {return ::UNDEFINED_ACTION;}
int64_t getmtime(const String16& name) {return ::UNDEFINED_ACTION;}
int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, int32_t destUid) {return ::UNDEFINED_ACTION;}
int32_t clear_uid(int64_t uid) {return ::UNDEFINED_ACTION;}
#if ANDROID_VERSION >= 21
virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return ::UNDEFINED_ACTION;}
virtual int32_t is_hardware_backed(const String16& keyType) {return ::UNDEFINED_ACTION;}
virtual int32_t reset_uid(int32_t uid) {return ::UNDEFINED_ACTION;;}
virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {return ::UNDEFINED_ACTION;}
virtual int32_t password_uid(const String16& password, int32_t uid) {return ::UNDEFINED_ACTION;}
#elif ANDROID_VERSION == 18
virtual int32_t generate(const String16& name, int uid, int32_t flags) {return ::UNDEFINED_ACTION;}
virtual int32_t is_hardware_backed() {return ::UNDEFINED_ACTION;}
#else
virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return ::UNDEFINED_ACTION;}
virtual int32_t is_hardware_backed(const String16& keyType) {return ::UNDEFINED_ACTION;}
#endif
protected:
virtual void virtualDestroyNSSReference() {}
private:
~KeyStoreService() {
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return;
}
shutdown(ShutdownCalledFrom::Object);
}
};
} // namespace android
void startKeyStoreService()
{
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::sp<android::KeyStoreService> keyStoreService = new android::KeyStoreService();
sm->addService(String16("android.security.keystore"), keyStoreService);
}
#else
void startKeyStoreService() { return; }
#endif
static const char *CA_BEGIN = "-----BEGIN ",
*CA_END = "-----END ",
*CA_TAILER = "-----\n";
namespace mozilla {
namespace ipc {
static const char* KEYSTORE_ALLOWED_USERS[] = {
"root",
"wifi",
NULL
};
static const char* KEYSTORE_ALLOWED_PREFIXES[] = {
"WIFI_SERVERCERT_",
"WIFI_USERCERT_",
"WIFI_USERKEY_",
NULL
};
// Transform base64 certification data into DER format
void
FormatCaData(const char *aCaData, int aCaDataLength,
const char *aName, const uint8_t **aFormatData,
size_t *aFormatDataLength)
{
size_t bufSize = strlen(CA_BEGIN) + strlen(CA_END) + strlen(CA_TAILER) * 2 +
strlen(aName) * 2 + aCaDataLength + aCaDataLength/CA_LINE_SIZE
+ 2;
char *buf = (char *)malloc(bufSize);
if (!buf) {
*aFormatData = nullptr;
return;
}
*aFormatDataLength = bufSize;
*aFormatData = (const uint8_t *)buf;
char *ptr = buf;
size_t len;
// Create DER header.
len = snprintf(ptr, bufSize, "%s%s%s", CA_BEGIN, aName, CA_TAILER);
ptr += len;
bufSize -= len;
// Split base64 data in lines.
int copySize;
while (aCaDataLength > 0) {
copySize = (aCaDataLength > CA_LINE_SIZE) ? CA_LINE_SIZE : aCaDataLength;
memcpy(ptr, aCaData, copySize);
ptr += copySize;
aCaData += copySize;
aCaDataLength -= copySize;
bufSize -= copySize;
*ptr = '\n';
ptr++;
bufSize--;
}
// Create DEA tailer.
snprintf(ptr, bufSize, "%s%s%s", CA_END, aName, CA_TAILER);
}
ResponseCode
getCertificate(const char *aCertName, const uint8_t **aCertData,
size_t *aCertDataLength)
{
// certificate name prefix check.
if (!aCertName) {
return KEY_NOT_FOUND;
}
const char **prefix = KEYSTORE_ALLOWED_PREFIXES;
for (; *prefix; prefix++ ) {
if (!strncmp(*prefix, aCertName, strlen(*prefix))) {
break;
}
}
if (!(*prefix)) {
return KEY_NOT_FOUND;
}
// Get cert from NSS by name
ScopedCERTCertificate cert(CERT_FindCertByNickname(CERT_GetDefaultCertDB(),
aCertName));
if (!cert) {
return KEY_NOT_FOUND;
}
char *certDER = PL_Base64Encode((const char *)cert->derCert.data,
cert->derCert.len, nullptr);
if (!certDER) {
return SYSTEM_ERROR;
}
FormatCaData(certDER, strlen(certDER), "CERTIFICATE", aCertData,
aCertDataLength);
PL_strfree(certDER);
if (!(*aCertData)) {
return SYSTEM_ERROR;
}
return SUCCESS;
}
ResponseCode getPrivateKey(const char *aKeyName, const uint8_t **aKeyData,
size_t *aKeyDataLength)
{
*aKeyData = nullptr;
// Get corresponding user certificate nickname
char userCertName[128] = {0};
snprintf(userCertName, sizeof(userCertName) - 1, "WIFI_USERCERT_%s", aKeyName + 13);
// Get private key from user certificate.
ScopedCERTCertificate userCert(
CERT_FindCertByNickname(CERT_GetDefaultCertDB(), userCertName));
if (!userCert) {
return KEY_NOT_FOUND;
}
ScopedSECKEYPrivateKey privateKey(
PK11_FindKeyByAnyCert(userCert.get(), nullptr));
if (!privateKey) {
return KEY_NOT_FOUND;
}
// Export private key in PKCS#12 encrypted format, no password.
unsigned char pwstr[] = {0, 0};
SECItem password = {siBuffer, pwstr, sizeof(pwstr)};
ScopedSECKEYEncryptedPrivateKeyInfo encryptedPrivateKey(
PK11_ExportEncryptedPrivKeyInfo(privateKey->pkcs11Slot,
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4, &password, privateKey, 1,
privateKey->wincx));
if (!encryptedPrivateKey) {
return KEY_NOT_FOUND;
}
// Decrypt into RSA private key.
//
// Generate key for PKCS#12 encryption, we use SHA1 with 1 iteration, as the
// parameters used in PK11_ExportEncryptedPrivKeyInfo() above.
// see: PKCS#12 v1.0, B.2.
//
uint8_t DSP[192] = {0};
memset(DSP, 0x01, 64); // Diversifier part, ID = 1 for decryption.
memset(DSP + 128, 0x00, 64); // Password part, no password.
uint8_t *S = &DSP[64]; // Salt part.
uint8_t *salt = encryptedPrivateKey->algorithm.parameters.data + 4;
int saltLength = (int)encryptedPrivateKey->algorithm.parameters.data[3];
if (saltLength <= 0) {
return SYSTEM_ERROR;
}
for (int i = 0; i < 64; i++) {
S[i] = salt[i % saltLength];
}
// Generate key by SHA-1
nsresult rv;
nsCOMPtr<nsICryptoHash> hash =
do_CreateInstance("@mozilla.org/security/hash;1", &rv);
if (NS_FAILED(rv)) {
return SYSTEM_ERROR;
}
rv = hash->Init(nsICryptoHash::SHA1);
if (NS_FAILED(rv)) {
return SYSTEM_ERROR;
}
rv = hash->Update(DSP, sizeof(DSP));
if (NS_FAILED(rv)) {
return SYSTEM_ERROR;
}
nsCString hashResult;
rv = hash->Finish(false, hashResult);
if (NS_FAILED(rv)) {
return SYSTEM_ERROR;
}
// First 40-bit as key for RC4.
uint8_t key[5];
memcpy(key, hashResult.get(), sizeof(key));
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
return SYSTEM_ERROR;
}
SECItem keyItem = {siBuffer, key, sizeof(key)};
ScopedPK11SymKey symKey(PK11_ImportSymKey(slot, CKM_RC4, PK11_OriginUnwrap,
CKA_DECRYPT, &keyItem, nullptr));
if (!symKey) {
return SYSTEM_ERROR;
}
// Get expected decrypted data size then allocate memory.
uint8_t *encryptedData = (uint8_t *)encryptedPrivateKey->encryptedData.data;
unsigned int encryptedDataLen = encryptedPrivateKey->encryptedData.len;
unsigned int decryptedDataLen = encryptedDataLen;
SECStatus srv = PK11_Decrypt(symKey, CKM_RC4, &keyItem, nullptr,
&decryptedDataLen, encryptedDataLen,
encryptedData, encryptedDataLen);
if (srv != SECSuccess) {
return SYSTEM_ERROR;
}
ScopedSECItem decryptedData(::SECITEM_AllocItem(nullptr, nullptr,
decryptedDataLen));
if (!decryptedData) {
return SYSTEM_ERROR;
}
// Decrypt by RC4.
srv = PK11_Decrypt(symKey, CKM_RC4, &keyItem, decryptedData->data,
&decryptedDataLen, decryptedData->len, encryptedData,
encryptedDataLen);
if (srv != SECSuccess) {
return SYSTEM_ERROR;
}
// Export key in PEM format.
char *keyPEM = PL_Base64Encode((const char *)decryptedData->data,
decryptedDataLen, nullptr);
if (!keyPEM) {
return SYSTEM_ERROR;
}
FormatCaData(keyPEM, strlen(keyPEM), "PRIVATE KEY", aKeyData, aKeyDataLength);
PL_strfree(keyPEM);
if (!(*aKeyData)) {
return SYSTEM_ERROR;
}
return SUCCESS;
}
ResponseCode getPublicKey(const char *aKeyName, const uint8_t **aKeyData,
size_t *aKeyDataLength)
{
*aKeyData = nullptr;
// Get corresponding user certificate nickname
char userCertName[128] = {0};
snprintf(userCertName, sizeof(userCertName) - 1, "WIFI_USERCERT_%s", aKeyName + 13);
// Get public key from user certificate.
ScopedCERTCertificate userCert(
CERT_FindCertByNickname(CERT_GetDefaultCertDB(), userCertName));
if (!userCert) {
return KEY_NOT_FOUND;
}
// Get public key.
ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(userCert));
if (!publicKey) {
return KEY_NOT_FOUND;
}
ScopedSECItem keyItem(PK11_DEREncodePublicKey(publicKey));
if (!keyItem) {
return KEY_NOT_FOUND;
}
size_t bufSize = keyItem->len;
char *buf = (char *)malloc(bufSize);
if (!buf) {
return SYSTEM_ERROR;
}
memcpy(buf, keyItem->data, bufSize);
*aKeyData = (const uint8_t *)buf;
*aKeyDataLength = bufSize;
return SUCCESS;
}
ResponseCode signData(const char *aKeyName, const uint8_t *data, size_t length,
uint8_t **out, size_t *outLength)
{
*out = nullptr;
// Get corresponding user certificate nickname
char userCertName[128] = {0};
snprintf(userCertName, sizeof(userCertName) - 1, "WIFI_USERCERT_%s", aKeyName + 13);
// Get private key from user certificate.
ScopedCERTCertificate userCert(
CERT_FindCertByNickname(CERT_GetDefaultCertDB(), userCertName));
if (!userCert) {
return KEY_NOT_FOUND;
}
ScopedSECKEYPrivateKey privateKey(
PK11_FindKeyByAnyCert(userCert.get(), nullptr));
if (!privateKey) {
return KEY_NOT_FOUND;
}
//
// Find hash data from incoming data.
//
// Incoming data might be padded by PKCS-1 format:
// 00 01 FF FF ... FF 00 || Hash of length 36
// If the padding part exists, we have to ignore them.
//
uint8_t *hash = (uint8_t *)data;
const size_t HASH_LENGTH = 36;
if (length < HASH_LENGTH) {
return VALUE_CORRUPTED;
}
if (hash[0] == 0x00 && hash[1] == 0x01 && hash[2] == 0xFF && hash[3] == 0xFF) {
hash += 4;
while (*hash == 0xFF) {
if (hash + HASH_LENGTH > data + length) {
return VALUE_CORRUPTED;
}
hash++;
}
if (*hash != 0x00) {
return VALUE_CORRUPTED;
}
hash++;
}
if (hash + HASH_LENGTH != data + length) {
return VALUE_CORRUPTED;
}
SECItem hashItem = {siBuffer, hash, HASH_LENGTH};
// Sign hash.
ScopedSECItem signItem(::SECITEM_AllocItem(nullptr, nullptr,
PK11_SignatureLen(privateKey)));
if (!signItem) {
return SYSTEM_ERROR;
}
SECStatus srv;
srv = PK11_Sign(privateKey, signItem.get(), &hashItem);
if (srv != SECSuccess) {
return SYSTEM_ERROR;
}
uint8_t *buf = (uint8_t *)malloc(signItem->len);
if (!buf) {
return SYSTEM_ERROR;
}
memcpy(buf, signItem->data, signItem->len);
*out = buf;
*outLength = signItem->len;
return SUCCESS;
}
bool
checkPermission(uid_t uid)
{
struct passwd *userInfo = getpwuid(uid);
for (const char **user = KEYSTORE_ALLOWED_USERS; *user; user++ ) {
if (!strcmp(*user, userInfo->pw_name)) {
return true;
}
}
return false;
}
//
// KeyStore
//
KeyStore::KeyStore()
: mShutdown(false)
{
MOZ_COUNT_CTOR(KeyStore);
::startKeyStoreService();
Listen();
}
KeyStore::~KeyStore()
{
nsNSSShutDownPreventionLock locker;
MOZ_COUNT_DTOR(KeyStore);
if (isAlreadyShutDown()) {
return;
}
shutdown(ShutdownCalledFrom::Object);
MOZ_ASSERT(!mListenSocket);
MOZ_ASSERT(!mStreamSocket);
}
void
KeyStore::Shutdown()
{
// We set mShutdown first, so that |OnDisconnect| won't try to reconnect.
mShutdown = true;
if (mStreamSocket) {
mStreamSocket->Close();
mStreamSocket = nullptr;
}
if (mListenSocket) {
mListenSocket->Close();
mListenSocket = nullptr;
}
}
void
KeyStore::Listen()
{
// We only allocate one |StreamSocket|, but re-use it for every connection.
if (mStreamSocket) {
mStreamSocket->Close();
} else {
mStreamSocket = new StreamSocket(this, STREAM_SOCKET);
}
if (!mListenSocket) {
// We only ever allocate one |ListenSocket|...
mListenSocket = new ListenSocket(this, LISTEN_SOCKET);
mListenSocket->Listen(new KeyStoreConnector(KEYSTORE_ALLOWED_USERS),
mStreamSocket);
} else {
// ... but keep it open.
mListenSocket->Listen(mStreamSocket);
}
ResetHandlerInfo();
}
void
KeyStore::ResetHandlerInfo()
{
mHandlerInfo.state = STATE_IDLE;
mHandlerInfo.command = 0;
mHandlerInfo.paramCount = 0;
mHandlerInfo.commandPattern = nullptr;
for (int i = 0; i < MAX_PARAM; i++) {
mHandlerInfo.param[i].length = 0;
memset(mHandlerInfo.param[i].data, 0, VALUE_SIZE);
}
}
bool
KeyStore::CheckSize(UnixSocketBuffer *aMessage, size_t aExpectSize)
{
return (aMessage->GetSize() >= aExpectSize);
}
ResponseCode
KeyStore::ReadCommand(UnixSocketBuffer *aMessage)
{
if (mHandlerInfo.state != STATE_IDLE) {
NS_WARNING("Wrong state in ReadCommand()!");
return SYSTEM_ERROR;
}
if (!CheckSize(aMessage, 1)) {
NS_WARNING("Data size error in ReadCommand()!");
return PROTOCOL_ERROR;
}
mHandlerInfo.command = *aMessage->GetData();
aMessage->Consume(1);
// Find corrsponding command pattern
const struct ProtocolCommand *command = commands;
while (command->command && command->command != mHandlerInfo.command) {
command++;
}
if (!command->command) {
NS_WARNING("Unsupported command!");
return PROTOCOL_ERROR;
}
// Get command pattern.
mHandlerInfo.commandPattern = command;
if (command->paramNum) {
// Read command parameter if needed.
mHandlerInfo.state = STATE_READ_PARAM_LEN;
} else {
mHandlerInfo.state = STATE_PROCESSING;
}
return SUCCESS;
}
ResponseCode
KeyStore::ReadLength(UnixSocketBuffer *aMessage)
{
if (mHandlerInfo.state != STATE_READ_PARAM_LEN) {
NS_WARNING("Wrong state in ReadLength()!");
return SYSTEM_ERROR;
}
if (!CheckSize(aMessage, 2)) {
NS_WARNING("Data size error in ReadLength()!");
return PROTOCOL_ERROR;
}
// Read length of command parameter.
// FIXME: Depends on endianess and (sizeof(unsigned short) == 2)
unsigned short dataLength;
memcpy(&dataLength, aMessage->GetData(), 2);
aMessage->Consume(2);
mHandlerInfo.param[mHandlerInfo.paramCount].length = ntohs(dataLength);
mHandlerInfo.state = STATE_READ_PARAM_DATA;
return SUCCESS;
}
ResponseCode
KeyStore::ReadData(UnixSocketBuffer *aMessage)
{
if (mHandlerInfo.state != STATE_READ_PARAM_DATA) {
NS_WARNING("Wrong state in ReadData()!");
return SYSTEM_ERROR;
}
if (!CheckSize(aMessage, mHandlerInfo.param[mHandlerInfo.paramCount].length)) {
NS_WARNING("Data size error in ReadData()!");
return PROTOCOL_ERROR;
}
// Read command parameter.
memcpy(mHandlerInfo.param[mHandlerInfo.paramCount].data,
aMessage->GetData(),
mHandlerInfo.param[mHandlerInfo.paramCount].length);
aMessage->Consume(mHandlerInfo.param[mHandlerInfo.paramCount].length);
mHandlerInfo.paramCount++;
if (mHandlerInfo.paramCount == mHandlerInfo.commandPattern->paramNum) {
mHandlerInfo.state = STATE_PROCESSING;
} else {
mHandlerInfo.state = STATE_READ_PARAM_LEN;
}
return SUCCESS;
}
// Status response
void
KeyStore::SendResponse(ResponseCode aResponse)
{
MOZ_ASSERT(mStreamSocket);
if (aResponse == NO_RESPONSE)
return;
uint8_t response = (uint8_t)aResponse;
UnixSocketRawData* data = new UnixSocketRawData((const void *)&response, 1);
mStreamSocket->SendSocketData(data);
}
// Data response
void
KeyStore::SendData(const uint8_t *aData, int aLength)
{
MOZ_ASSERT(mStreamSocket);
unsigned short dataLength = htons(aLength);
UnixSocketRawData* length = new UnixSocketRawData((const void *)&dataLength, 2);
mStreamSocket->SendSocketData(length);
UnixSocketRawData* data = new UnixSocketRawData((const void *)aData, aLength);
mStreamSocket->SendSocketData(data);
}
// |StreamSocketConsumer|, |ListenSocketConsumer|
void
KeyStore::ReceiveSocketData(int aIndex, UniquePtr<UnixSocketBuffer>& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
// Handle request.
ResponseCode result = SUCCESS;
while (aMessage->GetSize() ||
mHandlerInfo.state == STATE_PROCESSING) {
switch (mHandlerInfo.state) {
case STATE_IDLE:
result = ReadCommand(aMessage.get());
break;
case STATE_READ_PARAM_LEN:
result = ReadLength(aMessage.get());
break;
case STATE_READ_PARAM_DATA:
result = ReadData(aMessage.get());
break;
case STATE_PROCESSING:
if (mHandlerInfo.command == 'g') {
result = SYSTEM_ERROR;
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
break;
}
// Get CA
const uint8_t *data;
size_t dataLength;
const char *name = (const char *)mHandlerInfo.param[0].data;
if (!strncmp(name, "WIFI_USERKEY_", 13)) {
result = getPrivateKey(name, &data, &dataLength);
} else {
result = getCertificate(name, &data, &dataLength);
}
if (result != SUCCESS) {
break;
}
SendResponse(SUCCESS);
SendData(data, (int)dataLength);
free((void *)data);
}
ResetHandlerInfo();
break;
}
if (result != SUCCESS) {
SendResponse(result);
ResetHandlerInfo();
return;
}
}
}
void
KeyStore::OnConnectSuccess(int aIndex)
{
if (aIndex == STREAM_SOCKET) {
mShutdown = false;
}
}
void
KeyStore::OnConnectError(int aIndex)
{
if (mShutdown) {
return;
}
if (aIndex == STREAM_SOCKET) {
// Stream socket error; start listening again
Listen();
}
}
void
KeyStore::OnDisconnect(int aIndex)
{
if (mShutdown) {
return;
}
switch (aIndex) {
case LISTEN_SOCKET:
// Listen socket disconnected; start anew.
mListenSocket = nullptr;
Listen();
break;
case STREAM_SOCKET:
// Stream socket disconnected; start listening again.
Listen();
break;
}
}
} // namespace ipc
} // namespace mozilla

View File

@ -1,141 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et ft=cpp: tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_KeyStore_h
#define mozilla_ipc_KeyStore_h 1
#include <sys/socket.h>
#include <sys/un.h>
#include "cert.h"
#include "mozilla/ipc/ListenSocket.h"
#include "mozilla/ipc/ListenSocketConsumer.h"
#include "mozilla/ipc/StreamSocket.h"
#include "mozilla/ipc/StreamSocketConsumer.h"
#include "nsNSSShutDown.h"
namespace mozilla {
namespace ipc {
enum ResponseCode {
SUCCESS = 1,
LOCKED = 2,
UNINITIALIZED = 3,
SYSTEM_ERROR = 4,
PROTOCOL_ERROR = 5,
PERMISSION_DENIED = 6,
KEY_NOT_FOUND = 7,
VALUE_CORRUPTED = 8,
UNDEFINED_ACTION = 9,
WRONG_PASSWORD_0 = 10,
WRONG_PASSWORD_1 = 11,
WRONG_PASSWORD_2 = 12,
WRONG_PASSWORD_3 = 13, // MAX_RETRY = 4
NO_RESPONSE
};
void FormatCaData(const uint8_t *aCaData, int aCaDataLength,
const char *aName, const uint8_t **aFormatData,
size_t *aFormatDataLength);
ResponseCode getCertificate(const char *aCertName, const uint8_t **aCertData,
size_t *aCertDataLength);
ResponseCode getPrivateKey(const char *aKeyName, const uint8_t **aKeyData,
size_t *aKeyDataLength);
ResponseCode getPublicKey(const char *aKeyName, const uint8_t **aKeyData,
size_t *aKeyDataLength);
ResponseCode signData(const char *aKeyName, const uint8_t *data, size_t length,
uint8_t **out, size_t *outLength);
bool checkPermission(uid_t uid);
static const int MAX_PARAM = 2;
static const int KEY_SIZE = ((NAME_MAX - 15) / 2);
static const int VALUE_SIZE = 32768;
static const int PASSWORD_SIZE = VALUE_SIZE;
static const int CA_LINE_SIZE = 64;
struct ProtocolCommand {
int8_t command;
int paramNum;
};
static const struct ProtocolCommand commands[] = {
{'g', 1}, // Get CA, command "g CERT_NAME"
{ 0, 0}
};
struct ProtocolParam{
uint length;
int8_t data[VALUE_SIZE];
};
typedef enum {
STATE_IDLE,
STATE_READ_PARAM_LEN,
STATE_READ_PARAM_DATA,
STATE_PROCESSING
} ProtocolHandlerState;
class KeyStore final
: public StreamSocketConsumer
, public ListenSocketConsumer
, public nsNSSShutDownObject
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(KeyStore)
KeyStore();
void Shutdown();
protected:
virtual void virtualDestroyNSSReference() {}
private:
enum SocketType {
LISTEN_SOCKET,
STREAM_SOCKET
};
~KeyStore();
struct {
ProtocolHandlerState state;
uint8_t command;
struct ProtocolParam param[MAX_PARAM];
int paramCount;
const struct ProtocolCommand *commandPattern;
} mHandlerInfo;
void ResetHandlerInfo();
void Listen();
bool CheckSize(UnixSocketBuffer *aMessage, size_t aExpectSize);
ResponseCode ReadCommand(UnixSocketBuffer *aMessage);
ResponseCode ReadLength(UnixSocketBuffer *aMessage);
ResponseCode ReadData(UnixSocketBuffer *aMessage);
void SendResponse(ResponseCode response);
void SendData(const uint8_t *data, int length);
// Methods for |StreamSocketConsumer|
//
void ReceiveSocketData(int aIndex,
UniquePtr<UnixSocketBuffer>& aMessage) override;
void OnConnectSuccess(int aIndex) override;
void OnConnectError(int aIndex) override;
void OnDisconnect(int aIndex) override;
bool mShutdown;
RefPtr<ListenSocket> mListenSocket;
RefPtr<StreamSocket> mStreamSocket;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_KeyStore_h

View File

@ -1,239 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et ft=cpp: tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "KeyStoreConnector.h"
#include <fcntl.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/un.h>
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
#include "nsThreadUtils.h" // For NS_IsMainThread.
#ifdef MOZ_WIDGET_GONK
#include <android/log.h>
#define KEYSTORE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
#else
#define KEYSTORE_LOG(args...) printf(args);
#endif
namespace mozilla {
namespace ipc {
static const char KEYSTORE_SOCKET_PATH[] = "/dev/socket/keystore";
KeyStoreConnector::KeyStoreConnector(const char** const aAllowedUsers)
: mAllowedUsers(aAllowedUsers)
{
MOZ_COUNT_CTOR_INHERITED(KeyStoreConnector, UnixSocketConnector);
}
KeyStoreConnector::~KeyStoreConnector()
{
MOZ_COUNT_DTOR_INHERITED(KeyStoreConnector, UnixSocketConnector);
}
nsresult
KeyStoreConnector::CreateSocket(int& aFd) const
{
unlink(KEYSTORE_SOCKET_PATH);
aFd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (aFd < 0) {
KEYSTORE_LOG("Could not open KeyStore socket!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
KeyStoreConnector::SetSocketFlags(int aFd) const
{
static const int sReuseAddress = 1;
// Set close-on-exec bit.
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= FD_CLOEXEC;
int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set non-blocking status flag.
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
if (flags < 0) {
return NS_ERROR_FAILURE;
}
flags |= O_NONBLOCK;
res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
if (res < 0) {
return NS_ERROR_FAILURE;
}
// Set socket addr to be reused even if kernel is still waiting to close.
res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
sizeof(sReuseAddress));
if (res < 0) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
KeyStoreConnector::CheckPermission(int aFd) const
{
struct ucred userCred;
socklen_t len = sizeof(userCred);
if (getsockopt(aFd, SOL_SOCKET, SO_PEERCRED, &userCred, &len)) {
return NS_ERROR_FAILURE;
}
const struct passwd* userInfo = getpwuid(userCred.uid);
if (!userInfo) {
return NS_ERROR_FAILURE;
}
if (!mAllowedUsers) {
return NS_ERROR_FAILURE;
}
for (const char** user = mAllowedUsers; *user; ++user) {
if (!strcmp(*user, userInfo->pw_name)) {
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
nsresult
KeyStoreConnector::CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const
{
struct sockaddr_un* address =
reinterpret_cast<struct sockaddr_un*>(&aAddress);
size_t namesiz = strlen(KEYSTORE_SOCKET_PATH) + 1; // include trailing '\0'
if (namesiz > sizeof(address->sun_path)) {
KEYSTORE_LOG("Address too long for socket struct!");
return NS_ERROR_FAILURE;
}
address->sun_family = AF_UNIX;
memcpy(address->sun_path, KEYSTORE_SOCKET_PATH, namesiz);
aAddressLength = offsetof(struct sockaddr_un, sun_path) + namesiz;
return NS_OK;
}
// |UnixSocketConnector|
nsresult
KeyStoreConnector::ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString)
{
MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
const struct sockaddr_un* un =
reinterpret_cast<const struct sockaddr_un*>(&aAddress);
size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
aAddressString.Assign(un->sun_path, len);
return NS_OK;
}
nsresult
KeyStoreConnector::CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd)
{
ScopedClose fd;
nsresult rv = CreateSocket(fd.rwget());
if (NS_FAILED(rv)) {
return rv;
}
rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
if (aAddress && aAddressLength) {
rv = CreateAddress(*aAddress, *aAddressLength);
if (NS_FAILED(rv)) {
return rv;
}
}
// Allow access for wpa_supplicant (different user, different group)
//
// TODO: Improve this by setting specific user/group for
// wpa_supplicant by calling |fchmod| and |fchown|.
//
chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR|
S_IRGRP|S_IWGRP|
S_IROTH|S_IWOTH);
aListenFd = fd.forget();
return NS_OK;
}
nsresult
KeyStoreConnector::AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
ScopedClose fd(
TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
if (fd < 0) {
NS_WARNING("Cannot accept file descriptor!");
return NS_ERROR_FAILURE;
}
nsresult rv = SetSocketFlags(fd);
if (NS_FAILED(rv)) {
return rv;
}
rv = CheckPermission(fd);
if (NS_FAILED(rv)) {
return rv;
}
aStreamFd = fd.forget();
return NS_OK;
}
nsresult
KeyStoreConnector::CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd)
{
MOZ_CRASH("|KeyStoreConnector| does not support creating stream sockets.");
return NS_ERROR_FAILURE;
}
nsresult
KeyStoreConnector::Duplicate(UnixSocketConnector*& aConnector)
{
aConnector = new KeyStoreConnector(*this);
return NS_OK;
}
}
}

View File

@ -1,57 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et ft=cpp: tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_KeyStoreConnector_h
#define mozilla_ipc_KeyStoreConnector_h
#include "mozilla/ipc/UnixSocketConnector.h"
namespace mozilla {
namespace ipc {
class KeyStoreConnector final : public UnixSocketConnector
{
public:
KeyStoreConnector(const char** const aAllowedUsers);
~KeyStoreConnector();
// Methods for |UnixSocketConnector|
//
nsresult ConvertAddressToString(const struct sockaddr& aAddress,
socklen_t aAddressLength,
nsACString& aAddressString) override;
nsresult CreateListenSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aListenFd) override;
nsresult AcceptStreamSocket(int aListenFd,
struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
nsresult CreateStreamSocket(struct sockaddr* aAddress,
socklen_t* aAddressLength,
int& aStreamFd) override;
nsresult Duplicate(UnixSocketConnector*& aConnector) override;
private:
nsresult CreateSocket(int& aFd) const;
nsresult SetSocketFlags(int aFd) const;
nsresult CheckPermission(int aFd) const;
nsresult CreateAddress(struct sockaddr& aAddress,
socklen_t& aAddressLength) const;
const char** const mAllowedUsers;
};
}
}
#endif

View File

@ -1,18 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.ipc += [
'KeyStore.h'
]
SOURCES += [
'KeyStore.cpp',
'KeyStoreConnector.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

View File

@ -18,7 +18,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['unixfd', 'unixsocket']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['hal', 'keystore', 'netd']
DIRS += ['hal', 'netd']
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
DIRS += ['contentproc']

View File

@ -0,0 +1,44 @@
// |jit-test| test-also-wasm-baseline; error: TestComplete
load(libdir + "asserts.js");
if (!wasmIsSupported())
throw "TestComplete";
// Single-step profiling currently only works in the ARM simulator
if (!getBuildConfiguration()["arm-simulator"])
throw "TestComplete";
enableSPSProfiling();
enableSingleStepProfiling();
var g = newGlobal();
g.parent = this;
g.eval("Debugger(parent).onExceptionUnwind = function () {};");
let module = new WebAssembly.Module(wasmTextToBinary(`
(module
(import $imp "a" "b" (result i32))
(memory 1 1)
(table 2 2 anyfunc)
(elem (i32.const 0) $imp $def)
(func $def (result i32) (i32.load (i32.const 0)))
(type $v2i (func (result i32)))
(func $call (param i32) (result i32) (call_indirect $v2i (get_local 0)))
(export "call" $call)
)
`));
let instance = new WebAssembly.Instance(module, {
a: { b: function () { throw "test"; } }
});
try {
instance.exports.call(0);
assertEq(false, true);
} catch (e) {
assertEq(e, "test");
}
disableSPSProfiling();
throw "TestComplete";

View File

@ -0,0 +1,36 @@
// |jit-test| test-also-wasm-baseline; error: TestComplete
load(libdir + "asserts.js");
if (!wasmIsSupported())
throw "TestComplete";
var g = newGlobal();
g.parent = this;
g.eval("Debugger(parent).onExceptionUnwind = function () {};");
let module = new WebAssembly.Module(wasmTextToBinary(`
(module
(import $imp "a" "b" (result i32))
(memory 1 1)
(table 2 2 anyfunc)
(elem (i32.const 0) $imp $def)
(func $def (result i32) (i32.load (i32.const 0)))
(type $v2i (func (result i32)))
(func $call (param i32) (result i32) (call_indirect $v2i (get_local 0)))
(export "call" $call)
)
`));
let instance = new WebAssembly.Instance(module, {
a: { b: function () { throw "test"; } }
});
try {
instance.exports.call(0);
assertEq(false, true);
} catch (e) {
assertEq(e, "test");
}
throw "TestComplete";

View File

@ -127,7 +127,7 @@ testError(
(func (export "") (call $foo))
)`,
WebAssembly.RuntimeError,
["", ">", "1,>", "0,1,>", "trap handling,0,1,>", "inline stub,0,1,>", "trap handling,0,1,>", "inline stub,0,1,>", ""]);
["", ">", "1,>", "0,1,>", "trap handling,0,1,>", "inline stub,0,1,>", "trap handling,0,1,>", ""]);
testError(
`(module
@ -142,7 +142,7 @@ WebAssembly.RuntimeError,
// Technically we have this one *one-instruction* interval where
// the caller is lost (the stack with "1,>"). It's annoying to fix and shouldn't
// mess up profiles in practice so we ignore it.
["", ">", "0,>", "1,0,>", "1,>", "trap handling,0,>", "inline stub,0,>", "trap handling,0,>", "inline stub,0,>", ""]);
["", ">", "0,>", "1,0,>", "1,>", "trap handling,0,>", "inline stub,0,>", "trap handling,0,>", ""]);
(function() {
var e = wasmEvalText(`

View File

@ -545,7 +545,7 @@ FrameIter::settleOnActivation()
}
if (activation->isWasm()) {
data_.wasmFrames_ = wasm::FrameIterator(*data_.activations_->asWasm());
data_.wasmFrames_ = wasm::FrameIterator(data_.activations_->asWasm());
if (data_.wasmFrames_.done()) {
++data_.activations_;

View File

@ -1717,6 +1717,9 @@ class WasmActivation : public Activation
// Read/written from SIGSEGV handler:
void setResumePC(void* pc) { resumePC_ = pc; }
void* resumePC() const { return resumePC_; }
// Used by wasm::FrameIterator during stack unwinding.
void unwindFP(uint8_t* fp) { fp_ = fp; }
};
// A FrameIter walks over the runtime's stack of JS script activations,

View File

@ -59,18 +59,20 @@ FrameIterator::FrameIterator()
codeRange_(nullptr),
fp_(nullptr),
pc_(nullptr),
unwind_(Unwind::False),
missingFrameMessage_(false)
{
MOZ_ASSERT(done());
}
FrameIterator::FrameIterator(const WasmActivation& activation)
: activation_(&activation),
FrameIterator::FrameIterator(WasmActivation* activation, Unwind unwind)
: activation_(activation),
code_(nullptr),
callsite_(nullptr),
codeRange_(nullptr),
fp_(activation.fp()),
fp_(activation->fp()),
pc_(nullptr),
unwind_(unwind),
missingFrameMessage_(false)
{
if (fp_) {
@ -78,7 +80,7 @@ FrameIterator::FrameIterator(const WasmActivation& activation)
return;
}
void* pc = activation.resumePC();
void* pc = activation_->resumePC();
if (!pc) {
MOZ_ASSERT(done());
return;
@ -156,6 +158,9 @@ FrameIterator::settle()
case CodeRange::FarJumpIsland:
MOZ_CRASH("Should not encounter an exit during iteration");
}
if (unwind_ == Unwind::True)
activation_->unwindFP(fp_);
}
const char*
@ -229,7 +234,9 @@ FrameIterator::debugEnabled() const
{
MOZ_ASSERT(!done() && code_);
MOZ_ASSERT_IF(!missingFrameMessage_, codeRange_->kind() == CodeRange::Function);
return code_->metadata().debugEnabled;
// Only non-imported functions can have debug frames.
return code_->metadata().debugEnabled &&
codeRange_->funcIndex() >= code_->metadata().funcImports.length();
}
DebugFrame*

View File

@ -51,19 +51,24 @@ struct TrapOffset;
// function stack frame.
class FrameIterator
{
const WasmActivation* activation_;
public:
enum class Unwind { True, False };
private:
WasmActivation* activation_;
const Code* code_;
const CallSite* callsite_;
const CodeRange* codeRange_;
uint8_t* fp_;
uint8_t* pc_;
Unwind unwind_;
bool missingFrameMessage_;
void settle();
public:
explicit FrameIterator();
explicit FrameIterator(const WasmActivation& activation);
explicit FrameIterator(WasmActivation* activation, Unwind unwind = Unwind::False);
void operator++();
bool done() const;
const char* filename() const;

View File

@ -1131,17 +1131,24 @@ wasm::GenerateThrowStub(MacroAssembler& masm, Label* throwLabel)
Offsets offsets;
offsets.begin = masm.currentOffset();
// The following HandleThrow call sets fp of this WasmActivation to null.
masm.andToStackPtr(Imm32(~(ABIStackAlignment - 1)));
if (ShadowStackSpace)
masm.subFromStackPtr(Imm32(ShadowStackSpace));
masm.call(SymbolicAddress::HandleDebugThrow);
masm.call(SymbolicAddress::HandleThrow);
// We are about to pop all frames in this WasmActivation. Set fp to null to
// maintain the invariant that fp is either null or pointing to a valid
// frame.
Register scratch = ABINonArgReturnReg0;
masm.loadWasmActivationFromSymbolicAddress(scratch);
masm.storePtr(ImmWord(0), Address(scratch, WasmActivation::offsetOfFP()));
#ifdef DEBUG
// We are about to pop all frames in this WasmActivation. Checking if fp is
// set to null to maintain the invariant that fp is either null or pointing
// to a valid frame.
Label ok;
masm.branchPtr(Assembler::Equal, Address(scratch, WasmActivation::offsetOfFP()), ImmWord(0), &ok);
masm.breakpoint();
masm.bind(&ok);
#endif
masm.setFramePushed(FramePushedForEntrySP);
masm.loadStackPtr(Address(scratch, WasmActivation::offsetOfEntrySP()));

View File

@ -103,9 +103,10 @@ static bool
WasmHandleDebugTrap()
{
WasmActivation* activation = JSRuntime::innermostWasmActivation();
MOZ_ASSERT(activation);
JSContext* cx = activation->cx();
FrameIterator iter(*activation);
FrameIterator iter(activation);
MOZ_ASSERT(iter.debugEnabled());
const CallSite* site = iter.debugTrapCallsite();
MOZ_ASSERT(site);
@ -138,12 +139,13 @@ WasmHandleDebugTrap()
}
static void
WasmHandleDebugThrow()
WasmHandleThrow()
{
WasmActivation* activation = JSRuntime::innermostWasmActivation();
MOZ_ASSERT(activation);
JSContext* cx = activation->cx();
for (FrameIterator iter(*activation); !iter.done(); ++iter) {
for (FrameIterator iter(activation, FrameIterator::Unwind::True); !iter.done(); ++iter) {
if (!iter.debugEnabled())
continue;
@ -349,8 +351,8 @@ wasm::AddressOf(SymbolicAddress imm, ExclusiveContext* cx)
return FuncCast(WasmHandleExecutionInterrupt, Args_General0);
case SymbolicAddress::HandleDebugTrap:
return FuncCast(WasmHandleDebugTrap, Args_General0);
case SymbolicAddress::HandleDebugThrow:
return FuncCast(WasmHandleDebugThrow, Args_General0);
case SymbolicAddress::HandleThrow:
return FuncCast(WasmHandleThrow, Args_General0);
case SymbolicAddress::ReportTrap:
return FuncCast(WasmReportTrap, Args_General1);
case SymbolicAddress::ReportOutOfBounds:

View File

@ -1017,7 +1017,7 @@ enum class SymbolicAddress
ReportOverRecursed,
HandleExecutionInterrupt,
HandleDebugTrap,
HandleDebugThrow,
HandleThrow,
ReportTrap,
ReportOutOfBounds,
ReportUnalignedAccess,

View File

@ -81,3 +81,6 @@ fuzzy(1,10000) == opacity-preserve3d-4.html opacity-preserve3d-4-ref.html
== mask-layer-1.html mask-layer-ref.html
== mask-layer-2.html mask-layer-ref.html
== mask-layer-3.html mask-layer-ref.html
fails-if(winWidget&&layersGPUAccelerated) == split-intersect1.html split-intersect1-ref.html # Bug 1323791: implement DirectX compositor polygon support
fuzzy(255,150) fails-if(winWidget&&layersGPUAccelerated) == split-intersect2.html split-intersect2-ref.html # Bug 1323791
fuzzy(255,100) fails-if(winWidget&&layersGPUAccelerated) == split-non-ortho1.html split-non-ortho1-ref.html # Bug 1323791

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Split intersect 1 ref</title>
<style>
.container {
margin: 0 0;
width: 400px;
height: 400px;
}
.shape {
margin: 0 0;
position: absolute;
width: 50px;
height: 100px;
}
.first {
background-color: rgba(255,0,0,1);
left: 58px;
}
.second {
background-color: rgba(0,255,0,1);
}
</style>
</head>
<body>
<div class="container">
<div class="shape first"></div>
<div class="shape second"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Split intersect 1</title>
<style>
.container {
margin: 0 0;
width: 400px;
height: 400px;
transform-style: preserve-3d;
}
.shape {
margin: 0 0;
position: absolute;
width: 100px;
height: 100px;
}
.first {
background-color: rgba(255,0,0,1);
}
.second {
background-color: rgba(0,255,0,1);
transform: rotateY(0.1deg);
}
</style>
</head>
<body>
<div class="container">
<div class="shape first"></div>
<div class="shape second"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Split intersect 2 ref</title>
<style>
.container {
margin: 0 0;
width: 400px;
height: 400px;
}
.shape {
margin: 0 0;
position: absolute;
}
.red {
background-color: rgba(255,0,0,1);
width: 100px;
height: 15px;
top: 150.5px;
left: 73px;
}
.green1 {
background-color: rgba(0,255,0,1);
width: 30px;
height: 42.5px;
top: 108px;
left: 88px;
}
.green2 {
background-color: rgba(0,255,0,1);
width: 30px;
height: 50px;
top: 158px;
left: 88px;
}
.blue1 {
background-color: rgba(0,0,255,1);
top: 108px;
left: 128px;
width: 30px;
height: 42.5px;
}
.blue2 {
background-color: rgba(0,0,255,1);
width: 30px;
height: 50px;
top: 158px;
left: 128px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape red"></div>
<div class="shape green1"></div>
<div class="shape green2"></div>
<div class="shape blue1"></div>
<div class="shape blue2"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Split intersect 2</title>
<style>
.container {
margin: 0 0;
width: 400px;
height: 400px;
transform-style: preserve-3d;
}
.shape {
margin: 0 0;
position: absolute;
width: 30px;
height: 100px;
}
.red {
background-color: rgba(255,0,0,1);
transform: translate(100px, 100px) rotateZ(90deg) rotateY(60deg);
}
.green {
background-color: rgba(0,255,0,1);
transform: translate(80px, 100px);
}
.blue {
background-color: rgba(0,0,255,1);
transform: translate(120px, 100px);
}
</style>
</head>
<body>
<div class="container">
<div class="shape red"></div>
<div class="shape green"></div>
<div class="shape blue"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Split non-orthogonal 1 ref</title>
<style>
.container {
margin: 0 0;
width: 400px;
height: 400px;
position: absolute;
transform-style: preserve-3d;
}
.shape {
margin: 0 0;
position: absolute;
}
.red-square-back {
background-color: rgba(255,0,0,1);
width: 100px;
height: 100px;
top: 50px;
left: 50px;
}
.green-square-back {
background-color: rgba(0,255,0,1);
width: 150px;
height: 150px;
top: 50px;
left: 50px;
transform: rotateZ(45deg);
}
.red-square-front {
background-color: rgba(255,0,0,1);
width: 50px;
height: 50px;
top: 100px;
left: 100px;
}
.green-square-front {
background-color: rgba(0,255,0,1);
width: 72px;
height: 72px;
top: 63.5px;
left: 63.5px;
transform: rotateZ(45deg);
}
#canvas {
width: 100px
height: 100px;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="shape red-square-back"></div>
<div class="shape green-square-back"></div>
<div class="shape red-square-front"></div>
<div class="shape green-square-front"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Split non-orthogonal 1</title>
<style>
.container {
margin: 0 0;
width: 400px;
height: 400px;
position: absolute;
transform-style: preserve-3d;
}
.shape {
margin: 0 0;
position: absolute;
}
.first {
background-color: rgba(255,0,0,1);
width: 100px;
height: 100px;
top: 50px;
left: 50px;
}
.second {
background-color: rgba(0,255,0,1);
width: 150px;
height: 150px;
top: 50px;
left: 50px;
transform: rotateZ(45deg) rotateY(0.1deg);
}
</style>
</head>
<body>
<div class="container">
<div class="shape second"></div>
<div class="shape first"></div>
</div>
</body>
</html>

View File

@ -65,7 +65,7 @@ CSS::Supports(const GlobalObject& aGlobal,
if (info.mStyleBackendType == StyleBackendType::Servo) {
NS_ConvertUTF16toUTF8 property(aProperty);
NS_ConvertUTF16toUTF8 value(aValue);
return Servo_CSSSupports(&property, &value);
return Servo_CSSSupports2(&property, &value);
}
nsCSSParser parser;
@ -87,7 +87,8 @@ CSS::Supports(const GlobalObject& aGlobal,
}
if (info.mStyleBackendType == StyleBackendType::Servo) {
MOZ_CRASH("stylo: CSS.supports() with arguments is not yet implemented");
NS_ConvertUTF16toUTF8 cond(aCondition);
return Servo_CSSSupports(&cond);
}
nsCSSParser parser;

View File

@ -161,8 +161,10 @@ SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemovePropertyById, void,
nsCSSPropertyID property)
// CSS supports()
SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
SERVO_BINDING_FUNC(Servo_CSSSupports2, bool,
const nsACString* name, const nsACString* value)
SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
const nsACString* cond)
// Computed style data
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,

View File

@ -1041,8 +1041,8 @@ CSSAnimationBuilder::GetComputedValue(nsPresContext* aPresContext,
"ServoStyleSet should not use nsAnimationManager for "
"animations");
mStyleWithoutAnimation = aPresContext->StyleSet()->AsGecko()->
ResolveStyleWithoutAnimation(mTarget, mStyleContext,
eRestyle_AllHintsWithAnimations);
ResolveStyleByRemovingAnimation(mTarget, mStyleContext,
eRestyle_AllHintsWithAnimations);
}
if (StyleAnimationValue::ExtractComputedValue(aProperty,

View File

@ -448,12 +448,136 @@ nsComputedDOMStyle::GetStyleContextForElement(Element* aElement,
aStyleType);
}
/* static */
namespace {
class MOZ_STACK_CLASS StyleResolver final
{
public:
StyleResolver(nsPresContext* aPresContext,
nsComputedDOMStyle::AnimationFlag aAnimationFlag)
: mAnimationFlag(aAnimationFlag)
{
MOZ_ASSERT(aPresContext);
// Nothing to do if we are going to resolve style *with* animation.
if (mAnimationFlag == nsComputedDOMStyle::eWithAnimation) {
return;
}
// Set SkipAnimationRules flag if we are going to resolve style without
// animation.
if (aPresContext->RestyleManager()->IsGecko()) {
mRestyleManager = aPresContext->RestyleManager()->AsGecko();
mOldSkipAnimationRules = mRestyleManager->SkipAnimationRules();
mRestyleManager->SetSkipAnimationRules(true);
} else {
NS_WARNING("stylo: can't skip animaition rules yet");
}
}
already_AddRefed<nsStyleContext>
ResolveWithAnimation(StyleSetHandle aStyleSet,
Element* aElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
nsComputedDOMStyle::StyleType aStyleType,
bool aInDocWithShell)
{
MOZ_ASSERT(mAnimationFlag == nsComputedDOMStyle::eWithAnimation,
"AnimationFlag should be eWithAnimation");
RefPtr<nsStyleContext> result;
if (aType != CSSPseudoElementType::NotPseudo) {
nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
Element* pseudoElement =
frame && aInDocWithShell ? frame->GetPseudoElement(aType) : nullptr;
result = aStyleSet->ResolvePseudoElementStyle(aElement, aType,
aParentContext,
pseudoElement);
} else {
result = aStyleSet->ResolveStyleFor(aElement, aParentContext,
LazyComputeBehavior::Allow);
}
if (aStyleType == nsComputedDOMStyle::StyleType::eDefaultOnly) {
// We really only want the user and UA rules. Filter out the other ones.
nsTArray< nsCOMPtr<nsIStyleRule> > rules;
for (nsRuleNode* ruleNode = result->RuleNode();
!ruleNode->IsRoot();
ruleNode = ruleNode->GetParent()) {
if (ruleNode->GetLevel() == SheetType::Agent ||
ruleNode->GetLevel() == SheetType::User) {
rules.AppendElement(ruleNode->GetRule());
}
}
// We want to build a list of user/ua rules that is in order from least to
// most important, so we have to reverse the list.
// Integer division to get "stop" is purposeful here: if length is odd, we
// don't have to do anything with the middle element of the array.
for (uint32_t i = 0, length = rules.Length(), stop = length / 2;
i < stop; ++i) {
rules[i].swap(rules[length - i - 1]);
}
result = aStyleSet->AsGecko()->ResolveStyleForRules(aParentContext,
rules);
}
return result.forget();
}
already_AddRefed<nsStyleContext>
ResolveWithoutAnimation(StyleSetHandle aStyleSet,
Element* aElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
bool aInDocWithShell)
{
MOZ_ASSERT(!aStyleSet->IsServo(),
"Bug 1311257: Servo backend does not support the base value yet");
MOZ_ASSERT(mAnimationFlag == nsComputedDOMStyle::eWithoutAnimation,
"AnimationFlag should be eWithoutAnimation");
RefPtr<nsStyleContext> result;
if (aType != CSSPseudoElementType::NotPseudo) {
nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
Element* pseudoElement =
frame && aInDocWithShell ? frame->GetPseudoElement(aType) : nullptr;
result =
aStyleSet->AsGecko()->ResolvePseudoElementStyleWithoutAnimation(
aElement, aType,
aParentContext,
pseudoElement);
} else {
result =
aStyleSet->AsGecko()->ResolveStyleWithoutAnimation(aElement,
aParentContext);
}
return result.forget();
}
~StyleResolver()
{
if (mRestyleManager) {
mRestyleManager->SetSkipAnimationRules(mOldSkipAnimationRules);
}
}
private:
RestyleManager* mRestyleManager = nullptr;
bool mOldSkipAnimationRules = false;
nsComputedDOMStyle::AnimationFlag mAnimationFlag;
};
}
already_AddRefed<nsStyleContext>
nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell,
StyleType aStyleType)
nsComputedDOMStyle::DoGetStyleContextForElementNoFlush(
Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell,
StyleType aStyleType,
AnimationFlag aAnimationFlag)
{
MOZ_ASSERT(aElement, "NULL element");
// If the content has a pres shell, we must use it. Otherwise we'd
@ -517,50 +641,72 @@ nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement,
return servoSet->ResolveTransientStyle(aElement, type);
}
RefPtr<nsStyleContext> sc;
RefPtr<nsStyleContext> parentContext;
nsIContent* parent = aPseudo ? aElement : aElement->GetParent();
// Don't resolve parent context for document fragments.
if (parent && parent->IsElement())
if (parent && parent->IsElement()) {
parentContext = GetStyleContextForElementNoFlush(parent->AsElement(),
nullptr, aPresShell,
aStyleType);
if (type != CSSPseudoElementType::NotPseudo) {
nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
Element* pseudoElement =
frame && inDocWithShell ? frame->GetPseudoElement(type) : nullptr;
sc = styleSet->ResolvePseudoElementStyle(aElement, type, parentContext,
pseudoElement);
} else {
sc = styleSet->ResolveStyleFor(aElement, parentContext, LazyComputeBehavior::Allow);
}
if (aStyleType == eDefaultOnly) {
// We really only want the user and UA rules. Filter out the other ones.
nsTArray< nsCOMPtr<nsIStyleRule> > rules;
for (nsRuleNode* ruleNode = sc->RuleNode();
!ruleNode->IsRoot();
ruleNode = ruleNode->GetParent()) {
if (ruleNode->GetLevel() == SheetType::Agent ||
ruleNode->GetLevel() == SheetType::User) {
rules.AppendElement(ruleNode->GetRule());
}
}
StyleResolver styleResolver(presContext, aAnimationFlag);
// We want to build a list of user/ua rules that is in order from least to
// most important, so we have to reverse the list.
// Integer division to get "stop" is purposeful here: if length is odd, we
// don't have to do anything with the middle element of the array.
for (uint32_t i = 0, length = rules.Length(), stop = length / 2;
i < stop; ++i) {
rules[i].swap(rules[length - i - 1]);
}
sc = styleSet->AsGecko()->ResolveStyleForRules(parentContext, rules);
if (aAnimationFlag == eWithAnimation) {
return styleResolver.ResolveWithAnimation(styleSet,
aElement, type,
parentContext,
aStyleType,
inDocWithShell);
}
return sc.forget();
return styleResolver.ResolveWithoutAnimation(styleSet,
aElement, type,
parentContext,
inDocWithShell);
}
/* static */
already_AddRefed<nsStyleContext>
nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell,
StyleType aStyleType)
{
return DoGetStyleContextForElementNoFlush(aElement,
aPseudo,
aPresShell,
aStyleType,
eWithAnimation);
}
/* static */
already_AddRefed<nsStyleContext>
nsComputedDOMStyle::GetStyleContextForElementWithoutAnimation(
Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell)
{
// If the content has a pres shell, we must use it. Otherwise we'd
// potentially mix rule trees by using the wrong pres shell's style
// set. Using the pres shell from the content also means that any
// content that's actually *in* a document will get the style from the
// correct document.
nsCOMPtr<nsIPresShell> presShell = GetPresShellForContent(aElement);
if (!presShell) {
presShell = aPresShell;
if (!presShell)
return nullptr;
}
presShell->FlushPendingNotifications(FlushType::Style);
return DoGetStyleContextForElementNoFlush(aElement,
aPseudo,
presShell,
eAll,
eWithoutAnimation);
}
nsMargin

View File

@ -89,6 +89,16 @@ public:
nsIPresShell* aPresShell,
StyleType aStyleType = eAll);
enum AnimationFlag {
eWithAnimation,
eWithoutAnimation,
};
// Similar to the above but ignoring animation rules and with StyleType::eAll.
static already_AddRefed<nsStyleContext>
GetStyleContextForElementWithoutAnimation(mozilla::dom::Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell);
static already_AddRefed<nsStyleContext>
GetStyleContextForElementNoFlush(mozilla::dom::Element* aElement,
nsIAtom* aPseudo,
@ -144,6 +154,13 @@ private:
void SetResolvedStyleContext(RefPtr<nsStyleContext>&& aContext);
void SetFrameStyleContext(nsStyleContext* aContext);
static already_AddRefed<nsStyleContext>
DoGetStyleContextForElementNoFlush(mozilla::dom::Element* aElement,
nsIAtom* aPseudo,
nsIPresShell* aPresShell,
StyleType aStyleType,
AnimationFlag aAnimationFlag);
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * Style##name_() { \
return mStyleContext->Style##name_(); \

View File

@ -1351,9 +1351,10 @@ nsStyleSet::ResolveStyleFor(Element* aElement,
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleFor(Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext)
nsStyleSet::ResolveStyleForInternal(Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext,
AnimationFlag aAnimationFlag)
{
NS_ENSURE_FALSE(mInShutdown, nullptr);
NS_ASSERTION(aElement, "aElement must not be null");
@ -1377,7 +1378,7 @@ nsStyleSet::ResolveStyleFor(Element* aElement,
visitedRuleNode = ruleWalker.CurrentNode();
}
uint32_t flags = eDoAnimation;
uint32_t flags = (aAnimationFlag == eWithAnimation) ? eDoAnimation : eNoFlags;
if (nsCSSRuleProcessor::IsLink(aElement)) {
flags |= eIsLink;
}
@ -1394,6 +1395,17 @@ nsStyleSet::ResolveStyleFor(Element* aElement,
aElement, flags);
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleFor(Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext)
{
return ResolveStyleForInternal(aElement,
aParentContext,
aTreeMatchContext,
eWithAnimation);
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleForRules(nsStyleContext* aParentContext,
const nsTArray< nsCOMPtr<nsIStyleRule> > &aRules)
@ -1748,9 +1760,9 @@ nsStyleSet::ResolveStyleWithReplacement(Element* aElement,
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget,
nsStyleContext* aStyleContext,
nsRestyleHint aWhichToRemove)
nsStyleSet::ResolveStyleByRemovingAnimation(dom::Element* aTarget,
nsStyleContext* aStyleContext,
nsRestyleHint aWhichToRemove)
{
#ifdef DEBUG
CSSPseudoElementType pseudoType = aStyleContext->GetPseudoType();
@ -1777,6 +1789,34 @@ nsStyleSet::ResolveStyleWithoutAnimation(dom::Element* aTarget,
return result.forget();
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleWithoutAnimation(Element* aTarget,
nsStyleContext* aParentContext)
{
RestyleManager* restyleManager = PresContext()->RestyleManager()->AsGecko();
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aTarget->OwnerDoc());
InitStyleScopes(treeContext, aTarget);
bool oldSkipAnimationRules = restyleManager->SkipAnimationRules();
restyleManager->SetSkipAnimationRules(true);
// Here we can call ResolveStyleForInternal() instead of
// ResolveStyleWithReplacement() since we don't need any animation rules
// (CSS Animations, Transitions and script animations). That's because
// EffectCompositor::GetAnimationRule() skips all of animations rules if
// SkipAnimationRules flag is true.
RefPtr<nsStyleContext> result = ResolveStyleForInternal(aTarget,
aParentContext,
treeContext,
eWithoutAnimation);
restyleManager->SetSkipAnimationRules(oldSkipAnimationRules);
return result.forget();
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleForText(nsIContent* aTextNode,
nsStyleContext* aParentContext)
@ -1818,10 +1858,12 @@ nsStyleSet::WalkDisableTextZoomRule(Element* aElement, nsRuleWalker* aRuleWalker
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
Element* aPseudoElement)
nsStyleSet::ResolvePseudoElementStyleInternal(
Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
Element* aPseudoElement,
AnimationFlag aAnimationFlag)
{
NS_ENSURE_FALSE(mInShutdown, nullptr);
@ -1857,7 +1899,9 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
uint32_t flags = eNoFlags;
if (aType == CSSPseudoElementType::before ||
aType == CSSPseudoElementType::after) {
flags |= eDoAnimation;
if (aAnimationFlag == eWithAnimation) {
flags |= eDoAnimation;
}
} else {
// Flex and grid containers don't expect to have any pseudo-element children
// aside from ::before and ::after. So if we have such a child, we're not
@ -1871,6 +1915,33 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
aParentElement, flags);
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
Element* aPseudoElement)
{
return ResolvePseudoElementStyleInternal(aParentElement,
aType,
aParentContext,
aPseudoElement,
eWithAnimation);
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolvePseudoElementStyleWithoutAnimation(
Element* aParentElement,
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
Element* aPseudoElement)
{
return ResolvePseudoElementStyleInternal(aParentElement,
aType,
aParentContext,
aPseudoElement,
eWithoutAnimation);
}
already_AddRefed<nsStyleContext>
nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
CSSPseudoElementType aType,

View File

@ -181,9 +181,23 @@ class nsStyleSet final
// data with eRestyle_AllHintsWithAnimations, or by using any other
// hints that are allowed by ResolveStyleWithReplacement.
already_AddRefed<nsStyleContext>
ResolveStyleWithoutAnimation(mozilla::dom::Element* aElement,
nsStyleContext* aStyleContext,
nsRestyleHint aWhichToRemove);
ResolveStyleByRemovingAnimation(mozilla::dom::Element* aElement,
nsStyleContext* aStyleContext,
nsRestyleHint aWhichToRemove);
// Similar to the above, but resolving style without all animation data in
// the first place.
already_AddRefed<nsStyleContext>
ResolveStyleWithoutAnimation(mozilla::dom::Element* aTarget,
nsStyleContext* aParentContext);
// Pseudo-element version of the above, ResolveStyleWithoutAnimation.
already_AddRefed<nsStyleContext>
ResolvePseudoElementStyleWithoutAnimation(
mozilla::dom::Element* aParentElement,
mozilla::CSSPseudoElementType aType,
nsStyleContext* aParentContext,
mozilla::dom::Element* aPseudoElement);
// Get a style context for a text node (which no rules will match).
//
@ -526,6 +540,23 @@ private:
mozilla::dom::Element* aElementForAnimation,
uint32_t aFlags);
enum AnimationFlag {
eWithAnimation,
eWithoutAnimation,
};
already_AddRefed<nsStyleContext>
ResolveStyleForInternal(mozilla::dom::Element* aElement,
nsStyleContext* aParentContext,
TreeMatchContext& aTreeMatchContext,
AnimationFlag aAnimationFlag);
already_AddRefed<nsStyleContext>
ResolvePseudoElementStyleInternal(mozilla::dom::Element* aParentElement,
mozilla::CSSPseudoElementType aType,
nsStyleContext* aParentContext,
mozilla::dom::Element* aPseudoElement,
AnimationFlag aAnimationFlag);
nsPresContext* PresContext() { return mRuleTree->PresContext(); }
// The sheets in each array in mSheets are stored with the most significant

View File

@ -558,8 +558,8 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
"for transitions");
nsStyleSet* styleSet = mPresContext->StyleSet()->AsGecko();
afterChangeStyle =
styleSet->ResolveStyleWithoutAnimation(aElement, newStyleContext,
eRestyle_CSSTransitions);
styleSet->ResolveStyleByRemovingAnimation(aElement, newStyleContext,
eRestyle_CSSTransitions);
} else {
afterChangeStyle = newStyleContext;
}

View File

@ -26,6 +26,7 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.util.Log;
/**
@ -295,6 +296,11 @@ public class BrowserLocaleManager implements LocaleManager {
// We should use setLocale, but it's unexpectedly missing
// on real devices.
config.locale = locale;
// LayoutDirection is also updated in setLocale, do this manually.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
config.setLayoutDirection(locale);
}
res.updateConfiguration(config, null);
}

View File

@ -111,6 +111,7 @@ import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.util.ViewUtil;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -1502,6 +1503,9 @@ public abstract class GeckoApp
if (loc.equals(mLastLocale)) {
Log.d(LOGTAG, "New locale same as old; onLocaleReady has nothing to do.");
}
BrowserLocaleManager.getInstance().updateConfiguration(GeckoApp.this, loc);
ViewUtil.setLayoutDirection(getWindow().getDecorView(), loc);
refreshChrome();
// The URL bar hint needs to be populated.
TextView urlBar = (TextView) findViewById(R.id.url_bar_title);

View File

@ -50,6 +50,7 @@ import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.InputOptionsUtils;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.ViewUtil;
import android.annotation.TargetApi;
import android.app.AlertDialog;
@ -80,12 +81,16 @@ import android.preference.TwoStatePreference;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.ActionBar;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
@ -262,6 +267,14 @@ public class GeckoPreferences
Log.d(LOGTAG, "onLocaleChanged: " + newLocale);
BrowserLocaleManager.getInstance().updateConfiguration(getApplicationContext(), newLocale);
// If activity is not recreated, also update locale to current activity configuration
BrowserLocaleManager.getInstance().updateConfiguration(GeckoPreferences.this, newLocale);
ViewUtil.setLayoutDirection(getWindow().getDecorView(), newLocale);
// Force update navigate up icon by current layout direction
final ActionBar actionBar = getSupportActionBar();
actionBar.setHomeAsUpIndicator(android.support.v7.appcompat.R.drawable.abc_ic_ab_back_mtrl_am_alpha);
this.lastLocale = newLocale;
if (isMultiPane()) {

View File

@ -359,6 +359,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
}
public void refresh() {
progressBar.setImageDrawable(getResources().getDrawable(R.drawable.progress));
urlDisplayLayout.dismissSiteIdentityPopup();
}

View File

@ -127,6 +127,13 @@ abstract class BrowserToolbarTabletBase extends BrowserToolbar {
canDoForward(tab) ? ForwardButtonAnimation.SHOW : ForwardButtonAnimation.HIDE);
}
@Override
public void refresh() {
super.refresh();
forwardButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_menu_forward));
backButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_menu_back));
}
@Override
public void setNextFocusDownId(int nextId) {
super.setNextFocusDownId(nextId);

View File

@ -6,13 +6,17 @@ package org.mozilla.gecko.util;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.MarginLayoutParamsCompat;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewGroup;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
import java.util.Locale;
public class ViewUtil {
/**
@ -51,4 +55,21 @@ public class ViewUtil {
MarginLayoutParamsCompat.setMarginStart(layoutParams, marginStart);
}
}
/**
* Force set layout direction to RTL or LTR by Locale.
* @param view
* @param locale
*/
public static void setLayoutDirection(View view, Locale locale) {
switch (TextUtilsCompat.getLayoutDirectionFromLocale(locale)) {
case ViewCompat.LAYOUT_DIRECTION_RTL:
ViewCompat.setLayoutDirection(view, ViewCompat.LAYOUT_DIRECTION_RTL);
break;
case ViewCompat.LAYOUT_DIRECTION_LTR:
default:
ViewCompat.setLayoutDirection(view, ViewCompat.LAYOUT_DIRECTION_LTR);
break;
}
}
}

View File

@ -9,7 +9,7 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.support.v4.view.ViewCompat;
import android.support.v4.text.BidiFormatter;
import android.util.AttributeSet;
import android.view.View;
@ -24,6 +24,7 @@ import android.view.View;
public class FadedSingleColorTextView extends FadedTextView {
// Shader for the fading edge.
private FadedTextGradient mTextGradient;
private boolean mIsTextDirectionRtl;
public FadedSingleColorTextView(Context context, AttributeSet attrs) {
super(context, attrs);
@ -39,13 +40,21 @@ public class FadedSingleColorTextView extends FadedTextView {
final boolean needsEllipsis = needsEllipsis();
if (needsEllipsis && needsNewGradient) {
final boolean isRTL = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
mTextGradient = new FadedTextGradient(width, fadeWidth, color, isRTL);
mTextGradient = new FadedTextGradient(width, fadeWidth, color, mIsTextDirectionRtl);
}
getPaint().setShader(needsEllipsis ? mTextGradient : null);
}
@Override
public void setText(CharSequence text, BufferType type) {
super.setText(text, type);
mIsTextDirectionRtl = BidiFormatter.getInstance().isRtl((String) text);
if (mIsTextDirectionRtl) {
setTextDirection(TEXT_DIRECTION_RTL);
}
}
@Override
public void onDraw(Canvas canvas) {
updateGradientShader();

View File

@ -347,8 +347,9 @@ pref("media.wmf.decoder.thread-count", -1);
pref("media.wmf.low-latency.enabled", false);
pref("media.wmf.skip-blacklist", false);
pref("media.wmf.vp9.enabled", true);
pref("media.wmf.allow-unsupported-resolutions", false);
pref("media.windows-media-foundation.allow-d3d11-dxva", true);
pref("media.wmf.disable-d3d11-for-dlls", "igd11dxva64.dll: 20.19.15.4463, 20.19.15.4454, 20.19.15.4444, 20.19.15.4416, 20.19.15.4390, 20.19.15.4380, 20.19.15.4377, 20.19.15.4364, 20.19.15.4360, 20.19.15.4352, 20.19.15.4331, 20.19.15.4326, 20.19.15.4300; igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 10.18.13.6510, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5382, 9.18.13.4195, 9.18.13.3165; atidxx32.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822");
pref("media.wmf.disable-d3d11-for-dlls", "igd11dxva64.dll: 20.19.15.4463, 20.19.15.4454, 20.19.15.4444, 20.19.15.4416, 20.19.15.4404, 20.19.15.4390, 20.19.15.4380, 20.19.15.4377, 20.19.15.4364, 20.19.15.4360, 20.19.15.4352, 20.19.15.4331, 20.19.15.4326, 20.19.15.4300; igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 10.18.13.6510, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5382, 9.18.13.4195, 9.18.13.3165; atidxx32.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.137.1, 21.19.134.1, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822");
pref("media.wmf.disable-d3d9-for-dlls", "igdumd64.dll: 8.15.10.2189, 8.15.10.2119, 8.15.10.2104, 8.15.10.2102, 8.771.1.0; atiumd64.dll: 7.14.10.833, 7.14.10.867, 7.14.10.885, 7.14.10.903, 7.14.10.911, 8.14.10.768, 9.14.10.1001, 9.14.10.1017, 9.14.10.1080, 9.14.10.1128, 9.14.10.1162, 9.14.10.1171, 9.14.10.1183, 9.14.10.1197, 9.14.10.945, 9.14.10.972, 9.14.10.984, 9.14.10.996");
#endif
#if defined(MOZ_FFMPEG)
@ -609,6 +610,9 @@ pref("layout.event-regions.enabled", false);
// Whether to enable arbitrary layer geometry for OpenGL compositor
pref("layers.geometry.opengl.enabled", true);
// Whether to enable arbitrary layer geometry for Basic compositor
pref("layers.geometry.basic.enabled", true);
// APZ preferences. For documentation/details on what these prefs do, check
// gfx/layers/apz/src/AsyncPanZoomController.cpp.
pref("apz.allow_checkerboarding", true);
@ -5527,7 +5531,12 @@ pref("dom.webkitBlink.dirPicker.enabled", true);
pref("dom.webkitBlink.filesystem.enabled", true);
#endif
#ifdef NIGHTLY_BUILD
pref("media.block-autoplay-until-in-foreground", true);
#else
pref("media.block-autoplay-until-in-foreground", false);
#endif
#ifdef MOZ_STYLO
// Is the Servo-backed style system enabled?
pref("layout.css.servo.enabled", true);

View File

@ -1581,7 +1581,7 @@ nsHttpChannel::ProcessSingleSecurityHeader(uint32_t aType,
// Process header will now discard the headers itself if the channel
// wasn't secure (whereas before it had to be checked manually)
uint32_t failureResult;
rv = sss->ProcessHeader(aType, mURI, securityHeader.get(), aSSLStatus,
rv = sss->ProcessHeader(aType, mURI, securityHeader, aSSLStatus,
aFlags, nullptr, nullptr, &failureResult);
if (NS_FAILED(rv)) {
nsAutoString consoleErrorCategory;

View File

@ -18,6 +18,7 @@
#include "nsISupportsPriority.h"
#include "nsIURI.h"
#include "nsNSSComponent.h"
#include "nsPromiseFlatString.h"
#include "nsSecurityHeaderParser.h"
#include "nsStreamUtils.h"
#include "nsWhitespaceTokenizer.h"
@ -433,7 +434,8 @@ ContentSignatureVerifier::ParseContentSignatureHeader(
NS_NAMED_LITERAL_CSTRING(signature_var, "p384ecdsa");
NS_NAMED_LITERAL_CSTRING(certChainURL_var, "x5u");
nsSecurityHeaderParser parser(aContentSignatureHeader.BeginReading());
const nsCString& flatHeader = PromiseFlatCString(aContentSignatureHeader);
nsSecurityHeaderParser parser(flatHeader);
nsresult rv = parser.Parse();
if (NS_FAILED(rv)) {
CSVerifier_LOG(("CSVerifier: could not parse ContentSignature header\n"));

View File

@ -13,6 +13,7 @@
#include "nsIContentSignatureVerifier.h"
#include "nsIStreamListener.h"
#include "nsNSSShutDown.h"
#include "nsString.h"
#include "ScopedNSSTypes.h"
// 45a5fe2f-c350-4b86-962d-02d5aaaa955a

View File

@ -9,6 +9,7 @@
#include "mozilla/Casting.h"
#include "mozilla/Logging.h"
#include "mozilla/Telemetry.h"
#include "nsDependentString.h"
#include "nsISiteSecurityService.h"
#include "nsServiceManagerUtils.h"
#include "nsSiteSecurityService.h"
@ -181,8 +182,8 @@ FindPinningInformation(const char* hostname, mozilla::pkix::Time time,
bool found;
bool includeSubdomains;
nsTArray<nsCString> pinArray;
rv = sssService->GetKeyPinsForHostname(evalHost, time, pinArray,
&includeSubdomains, &found);
rv = sssService->GetKeyPinsForHostname(nsDependentCString(evalHost), time,
pinArray, &includeSubdomains, &found);
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -512,7 +512,7 @@ CertErrorRunnable::CheckCertOverrides()
mDefaultErrorCodeToReport);
}
nsresult nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HSTS,
mInfoObject->GetHostNameRaw(),
mInfoObject->GetHostName(),
mProviderFlags,
nullptr,
&strictTransportSecurityEnabled);
@ -523,7 +523,7 @@ CertErrorRunnable::CheckCertOverrides()
mDefaultErrorCodeToReport);
}
nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HPKP,
mInfoObject->GetHostNameRaw(),
mInfoObject->GetHostName(),
mProviderFlags,
nullptr,
&hasPinningInformation);

View File

@ -18,7 +18,6 @@
#include "cryptohi.h"
#include "keyhi.h"
#include "mozilla/Likely.h"
#include "mozilla/Scoped.h"
#include "mozilla/UniquePtr.h"
#include "nsDebug.h"
#include "nsError.h"
@ -57,12 +56,6 @@ MapSECStatus(SECStatus rv)
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
// Alphabetical order by NSS type
// Deprecated: use the equivalent UniquePtr templates instead.
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTCertificate,
CERTCertificate,
CERT_DestroyCertificate)
namespace internal {
inline void
@ -176,13 +169,6 @@ private:
SECItem mItem;
};
// Deprecated: use the equivalent UniquePtr templates instead.
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotInfo,
PK11SlotInfo,
PK11_FreeSlot)
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SymKey,
PK11SymKey,
PK11_FreeSymKey)
namespace internal {
inline void
@ -277,20 +263,6 @@ inline void VFY_DestroyContext_true(VFYContext * ctx)
} // namespace internal
// Deprecated: use the equivalent UniquePtr templates instead.
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECItem,
SECItem,
internal::SECITEM_FreeItem_true)
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPrivateKey,
SECKEYPrivateKey,
SECKEY_DestroyPrivateKey)
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYEncryptedPrivateKeyInfo,
SECKEYEncryptedPrivateKeyInfo,
internal::SECKEYEncryptedPrivateKeyInfo_true)
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPublicKey,
SECKEYPublicKey,
SECKEY_DestroyPublicKey)
MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertificate,
CERTCertificate,
CERT_DestroyCertificate)

View File

@ -1149,4 +1149,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1492958449465000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1493044853644000);

View File

@ -60,8 +60,8 @@ interface nsISiteSecurityService : nsISupports
*
* @param aType the type of security header in question.
* @param aSourceURI the URI of the resource with the HTTP header.
* @param aSSLStatus the SSLStatus of the current channel
* @param aHeader the HTTP response header specifying security data.
* @param aSSLStatus the SSLStatus of the current channel.
* @param aFlags options for this request as defined in nsISocketProvider:
* NO_PERMANENT_STORAGE
* @param aMaxAge the parsed max-age directive of the header.
@ -75,7 +75,7 @@ interface nsISiteSecurityService : nsISupports
*/
void processHeader(in uint32_t aType,
in nsIURI aSourceURI,
in string aHeader,
in ACString aHeader,
in nsISSLStatus aSSLStatus,
in uint32_t aFlags,
[optional] out unsigned long long aMaxAge,
@ -88,7 +88,7 @@ interface nsISiteSecurityService : nsISupports
*/
void unsafeProcessHeader(in uint32_t aType,
in nsIURI aSourceURI,
in string aHeader,
in ACString aHeader,
in uint32_t aFlags,
[optional] out unsigned long long aMaxAge,
[optional] out boolean aIncludeSubdomains,
@ -119,7 +119,7 @@ interface nsISiteSecurityService : nsISupports
* the host is HSTS, false otherwise.
*/
boolean isSecureHost(in uint32_t aType,
in string aHost,
in ACString aHost,
in uint32_t aFlags,
[optional] out boolean aCached);
@ -159,14 +159,14 @@ interface nsISiteSecurityService : nsISupports
* aIncludeSubdomains will be true. Pins returned are only for non-built-in
* pin entries.
*
* @param aHostname the hosname (punycode) to be queried about
* @param the time at which the pins should be valid. This is in
* @param aHostname the hostname (punycode) to be queried about
* @param evalTime the time at which the pins should be valid. This is in
mozilla::pkix::Time which uses internally seconds since 0 AD.
* @param aPinArray the set of sha256-hashed key pins for the given domain
* @param aIncludeSubdomains true if the pins apply to subdomains of the
* given domain
*/
[noscript] boolean getKeyPinsForHostname(in string aHostname,
[noscript] boolean getKeyPinsForHostname(in ACString aHostname,
in mozillaPkixTime evalTime,
out nsCStringTArrayRef aPinArray,
out boolean aIncludeSubdomains);
@ -184,7 +184,7 @@ interface nsISiteSecurityService : nsISupports
* @param aIsPreload are these key pins for a preload entry? (false by
* default)
*/
boolean setKeyPins(in string aHost, in boolean aIncludeSubdomains,
boolean setKeyPins(in ACString aHost, in boolean aIncludeSubdomains,
in int64_t aExpires, in unsigned long aPinCount,
[array, size_is(aPinCount)] in string aSha256Pins,
[optional] in boolean aIsPreload);
@ -199,7 +199,7 @@ interface nsISiteSecurityService : nsISupports
* @param aIncludeSubdomains whether this entry also applies to subdomains
* @param aExpires the time this entry should expire (millis since epoch)
*/
boolean setHSTSPreload(in string aHost, in boolean aIncludesSubdomains,
boolean setHSTSPreload(in ACString aHost, in boolean aIncludesSubdomains,
in int64_t aExpires);
/**

View File

@ -28,7 +28,6 @@
2or3.tk: could not connect to host
300651.ru: did not receive HSTS header
302.nyc: could not connect to host
314chan.org: could not connect to host
33drugstore.com: did not receive HSTS header
360ds.co.in: could not connect to host
360gradus.com: did not receive HSTS header
@ -61,9 +60,9 @@
9point6.com: could not connect to host
a-plus.space: could not connect to host
a9c.co: could not connect to host
aaeblog.com: did not receive HSTS header
aaeblog.net: did not receive HSTS header
aaeblog.org: did not receive HSTS header
aaeblog.com: could not connect to host
aaeblog.net: could not connect to host
aaeblog.org: could not connect to host
aapp.space: could not connect to host
aaron-gustafson.com: did not receive HSTS header
abearofsoap.com: could not connect to host
@ -71,6 +70,7 @@ abecodes.net: could not connect to host
abeestrada.com: did not receive HSTS header
abilitylist.org: did not receive HSTS header
abioniere.de: could not connect to host
abnarnro.com: did not receive HSTS header
about.ge: could not connect to host
aboutmyip.info: did not receive HSTS header
aboutmyproperty.ca: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
@ -96,14 +96,13 @@ adam-kostecki.de: did not receive HSTS header
adamkostecki.de: did not receive HSTS header
adams.net: max-age too low: 0
adamwk.com: did not receive HSTS header
adayinthelifeof.nl: could not connect to host
adboos.com: did not receive HSTS header
addaxpetroleum.com: could not connect to host
addvocate.com: could not connect to host
adelevie.com: could not connect to host
aderal.io: could not connect to host
adfa-1.com: did not receive HSTS header
adhs-chaoten.net: did not receive HSTS header
adjagu.org: could not connect to host
admin.google.com: did not receive HSTS header (error ignored - included regardless)
admsel.ec: could not connect to host
adopteunsiteflash.com: did not receive HSTS header
@ -191,7 +190,6 @@ amilx.org: could not connect to host
amitube.com: could not connect to host
amri.nl: could not connect to host
anagra.ms: could not connect to host
anakros.me: did not receive HSTS header
analytic-s.ml: could not connect to host
anarchistischegroepnijmegen.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
anassiriphotography.com: could not connect to host
@ -227,6 +225,7 @@ anonymousstatecollegelulzsec.com: could not connect to host
anook.com: max-age too low: 0
another.ch: could not connect to host
ant.land: could not connect to host
antarcti.co: did not receive HSTS header
anthenor.co.uk: could not connect to host
antimine.kr: could not connect to host
antocom.com: did not receive HSTS header
@ -249,6 +248,7 @@ apnakliyat.com: did not receive HSTS header
aponkralsunucu.com: did not receive HSTS header
app.lookout.com: could not connect to host
app.manilla.com: could not connect to host
appart.ninja: could not connect to host
appengine.google.com: did not receive HSTS header (error ignored - included regardless)
applez.xyz: could not connect to host
applic8.com: did not receive HSTS header
@ -280,6 +280,7 @@ as9178.net: could not connect to host
asasuou.pw: could not connect to host
asc16.com: could not connect to host
asdpress.cn: could not connect to host
ashleymedway.com: could not connect to host
ashutoshmishra.org: did not receive HSTS header
asianodor.com: could not connect to host
askfit.cz: did not receive HSTS header
@ -328,6 +329,7 @@ autokovrik-diskont.ru: did not receive HSTS header
autotsum.com: could not connect to host
autumnwindsagility.com: could not connect to host
auverbox.ovh: could not connect to host
auxiliumincrementum.co.uk: could not connect to host
av.de: did not receive HSTS header
avec-ou-sans-ordonnance.fr: could not connect to host
avinet.com: max-age too low: 0
@ -400,6 +402,7 @@ beneffy.com: did not receive HSTS header
benk.press: could not connect to host
benny003.de: did not receive HSTS header
benzkosmetik.de: could not connect to host
berger.work: could not connect to host
bermytraq.bm: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
berrymark.be: max-age too low: 0
besixdouze.world: could not connect to host
@ -418,7 +421,6 @@ bf.am: max-age too low: 0
bgcparkstad.nl: did not receive HSTS header
bgmn.net: could not connect to host
bi.search.yahoo.com: did not receive HSTS header
bianinapiccanovias.com: could not connect to host
bidon.ca: did not receive HSTS header
bieberium.de: could not connect to host
bienenblog.cc: could not connect to host
@ -450,6 +452,7 @@ bithosting.io: did not receive HSTS header
bitnet.io: did not receive HSTS header
bitsafe.systems: could not connect to host
bitvigor.com: could not connect to host
biurokarier.edu.pl: could not connect to host
bivsi.com: could not connect to host
bizcms.com: did not receive HSTS header
bizon.sk: did not receive HSTS header
@ -461,7 +464,7 @@ bl4ckb0x.net: did not receive HSTS header
bl4ckb0x.org: did not receive HSTS header
black-armada.com.pl: could not connect to host
black-armada.pl: could not connect to host
blackburn.link: did not receive HSTS header
blackburn.link: could not connect to host
blackhelicopters.net: could not connect to host
blacklane.com: did not receive HSTS header
blackly.uk: could not connect to host
@ -494,7 +497,6 @@ boensou.com: did not receive HSTS header
bogosity.se: could not connect to host
bohan.life: could not connect to host
bonapp.restaurant: could not connect to host
bondskampeerder.nl: could not connect to host
bonfi.net: did not receive HSTS header
bonigo.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
bonitabrazilian.co.nz: did not receive HSTS header
@ -539,7 +541,6 @@ bsquared.org: could not connect to host
btcdlc.com: could not connect to host
buchheld.at: did not receive HSTS header
bucket.tk: could not connect to host
budger.nl: could not connect to host
budgetthostels.nl: did not receive HSTS header
budskap.eu: could not connect to host
bugtrack.io: did not receive HSTS header
@ -558,7 +559,7 @@ burrow.ovh: could not connect to host
burtrum.me: could not connect to host
burtrum.top: could not connect to host
business.lookout.com: could not connect to host
business.medbank.com.mt: max-age too low: 10011201
business.medbank.com.mt: max-age too low: 9924796
businesshosting.nl: did not receive HSTS header
businessloanstoday.com: max-age too low: 0
busold.ws: could not connect to host
@ -590,6 +591,7 @@ cake.care: could not connect to host
calendarr.com: did not receive HSTS header
calgaryconstructionjobs.com: could not connect to host
calix.com: max-age too low: 0
call.me: did not receive HSTS header
calltrackingreports.com: could not connect to host
calvin.me: max-age too low: 2592000
calvinallen.net: did not receive HSTS header
@ -628,7 +630,6 @@ catarsisvr.com: did not receive HSTS header
catcontent.cloud: could not connect to host
catinmay.com: did not receive HSTS header
catnapstudios.com: could not connect to host
cattivo.nl: did not receive HSTS header
caveclan.org: did not receive HSTS header
cavedroid.xyz: could not connect to host
cbhq.net: could not connect to host
@ -756,6 +757,7 @@ code.google.com: did not receive HSTS header (error ignored - included regardles
codeco.pw: could not connect to host
codeforce.io: could not connect to host
codepoet.de: could not connect to host
codepult.com: could not connect to host
codepx.com: did not receive HSTS header
codiva.io: max-age too low: 2592000
coffeeetc.co.uk: did not receive HSTS header
@ -807,6 +809,7 @@ count.sh: could not connect to host
couragewhispers.ca: did not receive HSTS header
coursdeprogrammation.com: could not connect to host
coursella.com: did not receive HSTS header
courtlistener.com: could not connect to host
covenantbank.net: could not connect to host
coverduck.ru: could not connect to host
cr.search.yahoo.com: did not receive HSTS header
@ -839,7 +842,7 @@ cryptify.eu: could not connect to host
cryptobin.org: could not connect to host
cryptojar.io: did not receive HSTS header
cryptoki.fr: max-age too low: 7776000
cryptolab.pro: did not receive HSTS header
cryptolab.tk: could not connect to host
cryptopartyatx.org: could not connect to host
cryptopush.com: did not receive HSTS header
crysadm.com: max-age too low: 1
@ -872,9 +875,12 @@ cydia-search.io: could not connect to host
cyphertite.com: could not connect to host
dad256.tk: could not connect to host
dadtheimpaler.com: could not connect to host
daemen.org: could not connect to host
daemon.xin: could not connect to host
dah5.com: did not receive HSTS header
dailystormerpodcasts.com: did not receive HSTS header
daimadi.com: could not connect to host
daiweihu.com: could not connect to host
dakrib.net: could not connect to host
dalingk.co: could not connect to host
dango.in: did not receive HSTS header
@ -890,6 +896,7 @@ dario.im: could not connect to host
dark-x.cf: could not connect to host
darkengine.io: could not connect to host
darkhole.cn: could not connect to host
darkkeepers.dk: could not connect to host
darknebula.space: could not connect to host
darkpony.ru: could not connect to host
darksideof.it: could not connect to host
@ -945,6 +952,7 @@ delayrefunds.co.uk: could not connect to host
deliverance.co.uk: could not connect to host
deltaconcepts.de: did not receive HSTS header
deltanet-production.de: max-age too low: 0
demdis.org: could not connect to host
demilitarized.ninja: could not connect to host
democracychronicles.com: did not receive HSTS header
demotops.com: did not receive HSTS header
@ -994,7 +1002,6 @@ dislocated.de: did not receive HSTS header
disowned.net: max-age too low: 0
dissimulo.me: could not connect to host
dittvertshus.no: could not connect to host
dixmag.com: could not connect to host
dizihocasi.com: did not receive HSTS header
dizorg.net: could not connect to host
dj4et.de: did not receive HSTS header
@ -1063,6 +1070,7 @@ duria.de: max-age too low: 3600
dutchrank.com: could not connect to host
dutchrank.nl: could not connect to host
dwhd.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
dworzak.ch: could not connect to host
dxa.io: could not connect to host
dycontrol.de: could not connect to host
dylanscott.com.au: did not receive HSTS header
@ -1074,6 +1082,7 @@ e-deca2.org: did not receive HSTS header
e-sa.com: did not receive HSTS header
earga.sm: could not connect to host
earlybirdsnacks.com: could not connect to host
earthrise16.com: could not connect to host
easez.net: did not receive HSTS header
easychiller.org: could not connect to host
easyhaul.com: did not receive HSTS header
@ -1150,7 +1159,6 @@ emmable.com: could not connect to host
emnitech.com: could not connect to host
empleosentorreon.mx: could not connect to host
empleostampico.com: did not receive HSTS header
emyr.net: could not connect to host
enaah.de: could not connect to host
enargia.jp: max-age too low: 0
encode.space: did not receive HSTS header
@ -1183,7 +1191,6 @@ equatetechnologies.com.au: max-age too low: 3600
equilibre-yoga-jennifer-will.com: could not connect to host
erawanarifnugroho.com: did not receive HSTS header
eressea.xyz: could not connect to host
ericyl.com: could not connect to host
ernesto.at: could not connect to host
eromixx.com: did not receive HSTS header
erotalia.es: could not connect to host
@ -1193,7 +1200,6 @@ errlytics.com: [Exception... "Component returned failure code: 0x80004005 (NS_ER
errolz.com: could not connect to host
errors.zenpayroll.com: could not connect to host
ersindemirtas.com: did not receive HSTS header
esclear.de: could not connect to host
escotour.com: did not receive HSTS header
esec.rs: did not receive HSTS header
esln.org: did not receive HSTS header
@ -1202,6 +1208,7 @@ esquonic.com: could not connect to host
essexcosmeticdentists.co.uk: did not receive HSTS header
essexghosthunters.co.uk: did not receive HSTS header
estilosapeca.com: could not connect to host
estrietoit.com: did not receive HSTS header
etdonline.co.uk: could not connect to host
eternitylove.us: could not connect to host
ethanfaust.com: could not connect to host
@ -1279,7 +1286,6 @@ fedux.com.ar: could not connect to host
feezmodo.com: max-age too low: 0
felisslovakia.sk: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
feliwyn.fr: did not receive HSTS header
felixklein.at: could not connect to host
feminists.co: could not connect to host
fenteo.com: could not connect to host
feragon.net: max-age too low: 84600
@ -1289,11 +1295,11 @@ fexmen.com: could not connect to host
ffmradio.de: did not receive HSTS header
fhdhelp.de: could not connect to host
fhdhilft.de: could not connect to host
fierlafijn.net: could not connect to host
fiftyshadesofluca.ml: could not connect to host
fig.co: did not receive HSTS header
fightr.co: could not connect to host
fikt.space: could not connect to host
filestar.io: did not receive HSTS header
filmipop.com: max-age too low: 0
finalgear.com: did not receive HSTS header
financieringsportaal.nl: did not receive HSTS header
@ -1307,6 +1313,7 @@ firebaseio.com: could not connect to host (error ignored - included regardless)
firefall.rocks: could not connect to host
firemail.io: could not connect to host
fireorbit.de: did not receive HSTS header
firstdogonthemoon.com.au: did not receive HSTS header
firstforex.co.uk: did not receive HSTS header
fish2.me: did not receive HSTS header
fit4medien.de: did not receive HSTS header
@ -1336,7 +1343,6 @@ flowersandclouds.com: could not connect to host
flukethoughts.com: could not connect to host
flushstudios.com: did not receive HSTS header
flyaces.com: did not receive HSTS header
flyserver.co.il: did not receive HSTS header
fm83.nl: could not connect to host
fndout.com: did not receive HSTS header
fnvsecurity.com: could not connect to host
@ -1369,6 +1375,7 @@ franta.biz: did not receive HSTS header
franta.email: did not receive HSTS header
franzt.de: could not connect to host
frasys.io: max-age too low: 7776000
free-your-pc.com: did not receive HSTS header
freeflow.tv: could not connect to host
freematthale.net: did not receive HSTS header
freemedforms.com: did not receive HSTS header
@ -1479,9 +1486,11 @@ gglks.com: did not receive HSTS header
gh16.com.ar: could not connect to host
gheorghesarcov.ga: could not connect to host
gheorghesarcov.tk: could not connect to host
ghostblog.info: could not connect to host
giakki.eu: could not connect to host
gietvloergarant.nl: did not receive HSTS header
gigacloud.org: max-age too low: 0
gigacog.com: could not connect to host
gilly.berlin: did not receive HSTS header
gingali.de: did not receive HSTS header
gintenreiter-photography.com: did not receive HSTS header
@ -1541,7 +1550,6 @@ gottcode.org: did not receive HSTS header
gov.ax: could not connect to host
govillemo.ca: did not receive HSTS header
gparent.org: did not receive HSTS header
gpfclan.de: could not connect to host
gpsfix.cz: could not connect to host
gpstuner.com: did not receive HSTS header
gracesofgrief.com: max-age too low: 86400
@ -1578,7 +1586,6 @@ guava.studio: did not receive HSTS header
guilde-vindicta.fr: did not receive HSTS header
gulenet.com: did not receive HSTS header
gunnarhafdal.com: did not receive HSTS header
gurochan.ch: could not connect to host
gurusupe.com: could not connect to host
gussi.is: could not connect to host
gvt2.com: could not connect to host (error ignored - included regardless)
@ -1623,8 +1630,8 @@ happygadget.me: could not connect to host
happygastro.com: could not connect to host
harabuhouse.com: did not receive HSTS header
harbor-light.net: could not connect to host
hardfalcon.net: could not connect to host
hardline.xyz: could not connect to host
haribosupermix.com: could not connect to host
harmonycosmetic.com: max-age too low: 300
harristony.com: could not connect to host
hartmancpa.com: did not receive HSTS header
@ -1655,8 +1662,8 @@ hdwallpapers.net: did not receive HSTS header
healtious.com: did not receive HSTS header
heart.ge: did not receive HSTS header
heartlandrentals.com: did not receive HSTS header
heartsucker.com: could not connect to host
heftkaufen.de: did not receive HSTS header
heijblok.com: could not connect to host
helloworldhost.com: did not receive HSTS header
helpadmin.net: could not connect to host
helpium.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
@ -1668,7 +1675,6 @@ hepteract.us: did not receive HSTS header
hermes-net.de: could not connect to host
herpaderp.net: did not receive HSTS header
herzbotschaft.de: did not receive HSTS header
hethely.ch: could not connect to host
hex2013.com: did not receive HSTS header
hexid.me: could not connect to host
hibilog.com: could not connect to host
@ -1721,10 +1727,8 @@ housingstudents.org.uk: could not connect to host
howbigismybuilding.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
howrandom.org: could not connect to host
hr-intranet.com: did not receive HSTS header
hsandbox.tech: did not receive HSTS header
hsir.me: could not connect to host
hsts.date: could not connect to host
html5.org: could not connect to host
http418.xyz: could not connect to host
httpstatuscode418.xyz: could not connect to host
hu.search.yahoo.com: did not receive HSTS header
@ -1747,7 +1751,6 @@ iamusingtheinter.net: could not connect to host
iamveto.com: could not connect to host
iapws.com: did not receive HSTS header
iban.is: could not connect to host
icebat.dyndns.org: could not connect to host
icewoman.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
ichnichtskaufmann.de: could not connect to host
ichoosebtec.com: could not connect to host
@ -1783,7 +1786,6 @@ ilbuongiorno.it: did not receive HSTS header
ilhadocaranguejo.com.br: could not connect to host
ilikerainbows.co: could not connect to host
ilikerainbows.co.uk: could not connect to host
illegalpornography.me: could not connect to host
ilmconpm.de: did not receive HSTS header
ilona.graphics: max-age too low: 3600
iluvscotland.co.uk: did not receive HSTS header
@ -1837,10 +1839,8 @@ intel.li: could not connect to host
intelldynamics.com: could not connect to host
interference.io: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
interlun.com: could not connect to host
internect.co.za: did not receive HSTS header
internetcasinos.de: could not connect to host
internetcensus.org: could not connect to host
internetpro.me: could not connect to host
interserved.com: did not receive HSTS header
intex.es: max-age too low: 0
intim-uslugi-kazan.net: could not connect to host
@ -1860,7 +1860,6 @@ ip6.im: did not receive HSTS header
ipmimagazine.com: did not receive HSTS header
iptel.by: max-age too low: 0
iptel.ro: could not connect to host
ipv6-adresse.dk: could not connect to host
ipv6cloud.club: could not connect to host
iqcn.co: did not receive HSTS header
iqualtech.com: did not receive HSTS header
@ -1885,7 +1884,6 @@ itos.asia: did not receive HSTS header
itos.pl: did not receive HSTS header
itsadog.co.uk: did not receive HSTS header
itsamurai.ru: max-age too low: 2592000
itsatrap.nl: could not connect to host
itsecurityassurance.pw: did not receive HSTS header
itsg-faq.de: could not connect to host
itshost.ru: could not connect to host
@ -1894,11 +1892,12 @@ ivi.es: max-age too low: 0
ivk.website: could not connect to host
ivo.co.za: could not connect to host
iwannarefill.com: could not connect to host
iwizerunek.pl: could not connect to host
izdiwho.com: could not connect to host
izolight.ch: could not connect to host
izoox.com: did not receive HSTS header
izzzorgconcerten.nl: could not connect to host
ja-publications.com: could not connect to host
ja-publications.com: did not receive HSTS header
jabbari.io: did not receive HSTS header
jackalworks.com: could not connect to host
jacobhaug.com: could not connect to host
@ -1907,7 +1906,6 @@ jahliveradio.com: could not connect to host
jakenbake.com: did not receive HSTS header
jakubtopic.cz: could not connect to host
james.je: could not connect to host
jamesandpame.la: could not connect to host
jamesbradach.com: did not receive HSTS header
jamesburton.london: could not connect to host
jamesbywater.me: could not connect to host
@ -1937,7 +1935,6 @@ jasonroe.me: did not receive HSTS header
jasonsansone.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
jastoria.pl: could not connect to host
jayblock.com: did not receive HSTS header
jayharris.ca: could not connect to host
jayschulman.com: could not connect to host
jayscoaching.com: could not connect to host
jayshao.com: did not receive HSTS header
@ -2009,6 +2006,7 @@ junaos.xyz: did not receive HSTS header
junge-selbsthilfe.info: could not connect to host
junqtion.com: could not connect to host
jupp0r.de: did not receive HSTS header
jurriaan.ninja: could not connect to host
justlikethat.hosting: did not receive HSTS header
justnaw.co.uk: could not connect to host
justudin.com: did not receive HSTS header
@ -2020,6 +2018,7 @@ jznet.org: max-age too low: 86400
k-dev.de: could not connect to host
ka-clan.com: could not connect to host
kabuabc.com: did not receive HSTS header
kabus.org: could not connect to host
kadioglumakina.com.tr: did not receive HSTS header
kaela.design: did not receive HSTS header
kahopoon.net: could not connect to host
@ -2052,8 +2051,6 @@ kerangalam.com: could not connect to host
kerksanders.nl: did not receive HSTS header
kermadec.net: could not connect to host
kernl.us: did not receive HSTS header
kesteren.com: could not connect to host
kesteren.org: could not connect to host
keymaster.lookout.com: did not receive HSTS header
kgxtech.com: max-age too low: 2592000
ki-on.net: did not receive HSTS header
@ -2083,8 +2080,8 @@ kisun.co.jp: could not connect to host
kitakemon.com: could not connect to host
kitchenpunx.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
kitk.at: could not connect to host
kitsostech.com: could not connect to host
kitsta.com: could not connect to host
kittmedia.com: did not receive HSTS header
kiwiirc.com: max-age too low: 5256000
kizil.net: could not connect to host
kjaermaxi.me: did not receive HSTS header
@ -2102,6 +2099,7 @@ knowledgesnap.com: did not receive HSTS header
kodokushi.fr: could not connect to host
koen.io: did not receive HSTS header
koenrouwhorst.nl: did not receive HSTS header
kojipkgs.fedoraproject.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
kollabria.com: max-age too low: 0
komikito.com: could not connect to host
kompetenzwerft.de: did not receive HSTS header
@ -2118,7 +2116,6 @@ kotovstyle.ru: could not connect to host
kr.search.yahoo.com: did not receive HSTS header
kredite.sale: could not connect to host
kriegt.es: could not connect to host
kristikala.nl: could not connect to host
krmela.com: could not connect to host
kroetenfuchs.de: could not connect to host
kropkait.pl: could not connect to host
@ -2144,6 +2141,8 @@ kylinj.com: could not connect to host
kyochon.fr: could not connect to host
kz.search.yahoo.com: did not receive HSTS header
kzjnet.com: could not connect to host
kzsdabas.hu: could not connect to host
l2guru.ru: could not connect to host
labaia.info: could not connect to host
labina.com.tr: did not receive HSTS header
laboiteapc.fr: did not receive HSTS header
@ -2162,6 +2161,7 @@ lampl.info: did not receive HSTS header
landscape.canonical.com: max-age too low: 2592000
langenbach.rocks: could not connect to host
langhun.me: did not receive HSTS header
lantian.pub: could not connect to host
laozhu.me: did not receive HSTS header
laserfuchs.de: did not receive HSTS header
lashstuff.com: did not receive HSTS header
@ -2175,6 +2175,7 @@ lbrt.xyz: could not connect to host
ldarby.me.uk: could not connect to host
leadership9.com: could not connect to host
leardev.de: did not receive HSTS header
learnedovo.com: could not connect to host
learnfrenchfluently.com: did not receive HSTS header
learningorder.com: could not connect to host
lechiennoir.net: did not receive HSTS header
@ -2228,6 +2229,7 @@ lifeskillsdirect.com: did not receive HSTS header
lifestylehunter.co.uk: did not receive HSTS header
lifetimemoneymachine.com: did not receive HSTS header
lifi.digital: did not receive HSTS header
lifi.is: could not connect to host
lightarmory.com: could not connect to host
lightpaste.com: could not connect to host
lightworx.io: did not receive HSTS header
@ -2236,14 +2238,13 @@ lilpwny.com: could not connect to host
limalama.eu: max-age too low: 1
limeyeti.com: could not connect to host
limiteddata.co.uk: could not connect to host
limpid.nl: could not connect to host
limpido.it: could not connect to host
lincolnwayflorist.com: could not connect to host
lindberg.io: did not receive HSTS header
lingotaxi.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
lingros-test.tk: could not connect to host
linguaquote.com: did not receive HSTS header
link2serve.com: could not connect to host
link2serve.com: did not receive HSTS header
linmi.cc: did not receive HSTS header
linorman1997.me: could not connect to host
lintmx.com: could not connect to host
@ -2312,6 +2313,7 @@ lumi.do: did not receive HSTS header
luody.info: could not connect to host
luoe.ml: could not connect to host
luoxiao.im: could not connect to host
luripump.se: could not connect to host
lusis.fr: did not receive HSTS header
lusis.net: did not receive HSTS header
lustrumxi.nl: did not receive HSTS header
@ -2326,11 +2328,13 @@ m2tc.fr: could not connect to host
m3-gmbh.de: did not receive HSTS header
m82labs.com: could not connect to host
maarten.nyc: did not receive HSTS header
maartenterpstra.xyz: could not connect to host
maartenvandekamp.nl: did not receive HSTS header
macchaberrycream.com: could not connect to host
macchedil.com: did not receive HSTS header
macgeneral.de: did not receive HSTS header
machon.biz: could not connect to host
macker.io: could not connect to host
madars.org: did not receive HSTS header
maddin.ga: could not connect to host
madebymagnitude.com: did not receive HSTS header
@ -2363,6 +2367,7 @@ marcuskoh.com: could not connect to host
mariannematthew.com: could not connect to host
marie-curie.fr: could not connect to host
marie-elisabeth.dk: did not receive HSTS header
marie.club: could not connect to host
mariehane.com: could not connect to host
markaconnor.com: could not connect to host
markayapilandirma.com: did not receive HSTS header
@ -2430,7 +2435,6 @@ meghudson.com: could not connect to host
mein-gesundheitsmanager.com: did not receive HSTS header
meincenter-meinemeinung.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
meinebo.it: could not connect to host
melcher.it: did not receive HSTS header
melted.pw: could not connect to host
members.mayfirst.org: did not receive HSTS header
mencap.org.uk: max-age too low: 0
@ -2443,7 +2447,6 @@ merson.me: could not connect to host
meshok.ru: did not receive HSTS header
mesmoque.com: did not receive HSTS header
metagrader.com: could not connect to host
metasyntactic.xyz: could not connect to host
metebalci.com: could not connect to host
meteosky.net: could not connect to host
metin2blog.de: did not receive HSTS header
@ -2468,6 +2471,7 @@ micro-rain-systems.com: did not receive HSTS header
microme.ga: could not connect to host
micropple.net: could not connect to host
midwestwomenworkers.org: did not receive HSTS header
miegl.cz: could not connect to host
mightydicks.io: could not connect to host
mightydicks.tech: could not connect to host
mightysounds.cz: max-age too low: 0
@ -2612,7 +2616,6 @@ mypagella.it: could not connect to host
mypension.ca: could not connect to host
myraytech.net: did not receive HSTS header
mysecretrewards.com: did not receive HSTS header
myshirtsize.com: could not connect to host
mystery-science-theater-3000.de: did not receive HSTS header
mystudy.me: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
myvirtualserver.com: max-age too low: 2592000
@ -2681,6 +2684,7 @@ neutralox.com: max-age too low: 3600
never-afk.de: did not receive HSTS header
neveta.com: could not connect to host
newcitygas.ca: max-age too low: 0
newkaliningrad.ru: did not receive HSTS header
newlooknow.com: did not receive HSTS header
newtonwarp.com: could not connect to host
nextcloud.org: could not connect to host
@ -2738,7 +2742,7 @@ nosecretshop.com: could not connect to host
nossasenhoradaconceicao.com.br: could not connect to host
notadd.com: did not receive HSTS header
notarvysocina.cz: could not connect to host
nottheonion.net: did not receive HSTS header
nottheonion.net: could not connect to host
nouvelle-vague-saint-cast.fr: did not receive HSTS header
novacoast.com: did not receive HSTS header
novatrucking.de: could not connect to host
@ -2776,6 +2780,7 @@ nwa.xyz: could not connect to host
nwgh.org: max-age too low: 86400
nwork.media: could not connect to host
nyantec.com: did not receive HSTS header
nymphetomania.net: did not receive HSTS header
nysepho.pw: could not connect to host
nystart.no: did not receive HSTS header
nz.search.yahoo.com: max-age too low: 172800
@ -2784,7 +2789,6 @@ o0o.one: did not receive HSTS header
oasis.mobi: did not receive HSTS header
oasisim.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
obdolbacca.ru: could not connect to host
obfuscate.xyz: could not connect to host
obsydian.org: could not connect to host
occasion-impro.com: could not connect to host
occentus.net: did not receive HSTS header
@ -2838,7 +2842,6 @@ ookjesprookje.nl: could not connect to host
ooonja.de: could not connect to host
oopsmycase.com: could not connect to host
oost.io: could not connect to host
open-coding.org: could not connect to host
open-mx.de: could not connect to host
open-to-repair.fr: did not receive HSTS header
opendesk.cc: did not receive HSTS header
@ -2867,7 +2870,6 @@ orionfcu.com: did not receive HSTS header
orleika.ml: could not connect to host
osacrypt.studio: could not connect to host
osaiyuwu.com: could not connect to host
oscarvk.ch: could not connect to host
oscsdp.cz: could not connect to host
oslfoundation.org: could not connect to host
osp.cx: could not connect to host
@ -2882,6 +2884,7 @@ otherstuff.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ER
otichi.com: did not receive HSTS header
ottospora.nl: could not connect to host
ourbank.com: did not receive HSTS header
ourevents.net: could not connect to host
outdoorproducts.com: did not receive HSTS header
outetc.com: could not connect to host
outreachbuddy.com: could not connect to host
@ -2965,6 +2968,7 @@ pdf.yt: could not connect to host
peissen.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
pekkapikkarainen.fi: did not receive HSTS header
pekkarik.ru: could not connect to host
peliculasaudiolatinoonline.com: could not connect to host
penguinclientsystem.com: did not receive HSTS header
pensacolawinterfest.org: could not connect to host
pepchid.com: did not receive HSTS header
@ -3008,7 +3012,7 @@ pinesandneedles.com: did not receive HSTS header
pippen.io: could not connect to host
piratedb.com: could not connect to host
piratedot.com: could not connect to host
piratelist.online: could not connect to host
piratelist.online: did not receive HSTS header
piratenlogin.de: could not connect to host
pirateproxy.sx: could not connect to host
pirati.cz: max-age too low: 604800
@ -3060,18 +3064,20 @@ poolsandstuff.com: did not receive HSTS header
poon.tech: could not connect to host
porno-gif.ru: did not receive HSTS header
portalplatform.net: did not receive HSTS header
portalzine.de: did not receive HSTS header
poshpak.com: max-age too low: 86400
postcodewise.co.uk: did not receive HSTS header
postscheduler.org: could not connect to host
posylka.de: did not receive HSTS header
poussinooz.fr: could not connect to host
povitria.net: could not connect to host
power99press.com: did not receive HSTS header
power99press.com: could not connect to host
powerplannerapp.com: did not receive HSTS header
powerxequality.com: could not connect to host
ppr-truby.ru: could not connect to host
ppy3.com: did not receive HSTS header
pr.search.yahoo.com: did not receive HSTS header
praguepsychology.cz: did not receive HSTS header
prattpokemon.com: could not connect to host
prefontaine.name: could not connect to host
prego-shop.de: did not receive HSTS header
@ -3092,7 +3098,6 @@ privacyrup.net: could not connect to host
prnt.li: did not receive HSTS header
pro-zone.com: could not connect to host
prodpad.com: did not receive HSTS header
productdesignsoftware.com.au: could not connect to host
professionalboundaries.com: did not receive HSTS header
profi-durchgangsmelder.de: did not receive HSTS header
profundr.com: could not connect to host
@ -3112,7 +3117,7 @@ proximato.com: could not connect to host
proxybay.al: could not connect to host
proxybay.club: could not connect to host
proxybay.info: did not receive HSTS header
prxio.site: could not connect to host
prxio.site: did not receive HSTS header
prytkov.com: did not receive HSTS header
psw.academy: did not receive HSTS header
psw.consulting: did not receive HSTS header
@ -3152,7 +3157,6 @@ queercoders.com: did not receive HSTS header
questsandrewards.com: could not connect to host
quotehex.com: could not connect to host
quranserver.net: could not connect to host
quuz.org: could not connect to host
qvi.st: did not receive HSTS header
qwaser.fr: could not connect to host
qwilink.me: did not receive HSTS header
@ -3167,6 +3171,7 @@ rainbowbarracuda.com: could not connect to host
ramonj.nl: could not connect to host
randomcage.com: did not receive HSTS header
randomcloud.net: could not connect to host
randomprecision.co.uk: did not receive HSTS header
rankthespot.com: could not connect to host
rannseier.org: did not receive HSTS header
rapidresearch.me: could not connect to host
@ -3246,6 +3251,7 @@ richsiciliano.com: could not connect to host
rid-wan.com: could not connect to host
rideworks.com: did not receive HSTS header
riesenweber.id.au: did not receive HSTS header
right-to-love.name: did not receive HSTS header
right2.org: could not connect to host
righttoknow.ie: did not receive HSTS header
rijndael.xyz: could not connect to host
@ -3273,6 +3279,7 @@ roddis.net: did not receive HSTS header
rodney.id.au: did not receive HSTS header
rodosto.com: did not receive HSTS header
roeper.party: could not connect to host
roessner-network-solutions.com: could not connect to host
rolemaster.net: could not connect to host
romans-place.me.uk: did not receive HSTS header
ronvandordt.info: could not connect to host
@ -3339,7 +3346,7 @@ sandviks.com: did not receive HSTS header
sansemea.com: could not connect to host
sansonehowell.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
sarah-beckett-harpist.com: did not receive HSTS header
sarisonproductions.com: did not receive HSTS header
sarisonproductions.com: could not connect to host
saruwebshop.co.za: did not receive HSTS header
satmep.com: did not receive HSTS header
satriyowibowo.my.id: did not receive HSTS header
@ -3461,6 +3468,7 @@ shiftins.com: did not receive HSTS header
shiinko.com: could not connect to host
shinebijoux.com.br: could not connect to host
shinju.moe: could not connect to host
shiona.xyz: did not receive HSTS header
shocksrv.com: did not receive HSTS header
shooshosha.com: did not receive HSTS header
shopontarget.com: did not receive HSTS header
@ -3468,7 +3476,6 @@ shoprose.ru: could not connect to host
shops.neonisi.com: could not connect to host
shortr.li: could not connect to host
showkeeper.tv: did not receive HSTS header
shtorku.com: could not connect to host
shukatsu-note.com: could not connect to host
shv25.se: could not connect to host
shwongacc.com: could not connect to host
@ -3488,7 +3495,6 @@ simbast.com: could not connect to host
simod.org: could not connect to host
simon.butcher.name: max-age too low: 2629743
simongong.net: did not receive HSTS header
simonhirscher.de: could not connect to host
simpleai.net: max-age too low: 600
simplefraud.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
simplelearner.com: could not connect to host
@ -3511,7 +3517,7 @@ skyasker.cn: could not connect to host
skyflix.me: did not receive HSTS header
skyoy.com: could not connect to host
slash-dev.de: did not receive HSTS header
slashem.me: could not connect to host
slashem.me: did not receive HSTS header
slattery.co: could not connect to host
sleep10.com: could not connect to host
slicketl.com: did not receive HSTS header
@ -3519,6 +3525,7 @@ slightfuture.click: could not connect to host
slix.io: could not connect to host
slope.haus: could not connect to host
slovakiana.sk: did not receive HSTS header
slowfood.es: could not connect to host
sluitkampzeist.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
slycurity.de: did not receive HSTS header
smart-mirror.de: did not receive HSTS header
@ -3556,7 +3563,7 @@ socialhams.net: did not receive HSTS header
socialhead.io: could not connect to host
socialspirit.com.br: did not receive HSTS header
sockeye.cc: could not connect to host
socomponents.co.uk: could not connect to host
socomponents.co.uk: did not receive HSTS header
sogeek.me: did not receive HSTS header
sol-3.de: did not receive HSTS header
solidfuelappliancespares.co.uk: did not receive HSTS header
@ -3567,7 +3574,6 @@ someshit.xyz: could not connect to host
somethingnew.xyz: did not receive HSTS header
sonic.sk: max-age too low: 0
sonicrainboom.rocks: did not receive HSTS header
sortaweird.net: could not connect to host
sotiran.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
sotor.de: did not receive HSTS header
soulboy.io: did not receive HSTS header
@ -3629,10 +3635,10 @@ sss3s.com: did not receive HSTS header
stabletoken.com: could not connect to host
stadjerspasonline.nl: could not connect to host
stahl.xyz: could not connect to host
standardssuck.org: could not connect to host
standingmist.com: could not connect to host
stargatepartners.com: did not receive HSTS header
starmusic.ga: did not receive HSTS header
starwatches.eu: could not connect to host
stat.ink: did not receive HSTS header
stateofexception.io: could not connect to host
static.or.at: did not receive HSTS header
@ -3667,6 +3673,7 @@ stqry.com: did not receive HSTS header
str0.at: did not receive HSTS header
strasweb.fr: did not receive HSTS header
streamingmagazin.de: could not connect to host
streampanel.net: did not receive HSTS header
streams.dyndns.org: could not connect to host
strictlysudo.com: could not connect to host
stroeercrm.de: could not connect to host
@ -3702,7 +3709,6 @@ suos.io: could not connect to host
superbabysitting.ch: could not connect to host
superbike.tw: could not connect to host
supereight.net: did not receive HSTS header
superhome.com.au: did not receive HSTS header
superiorfloridavacation.com: did not receive HSTS header
supersalescontest.nl: did not receive HSTS header
supersecurefancydomain.com: could not connect to host
@ -3803,7 +3809,6 @@ terrax.info: could not connect to host
testandroid.xyz: could not connect to host
testbawks.com: did not receive HSTS header
testnode.xyz: could not connect to host
testsuite.org: could not connect to host
texte-zur-taufe.de: did not receive HSTS header
texter-linz.at: did not receive HSTS header
textoplano.xyz: could not connect to host
@ -3820,7 +3825,7 @@ thaianthro.com: did not receive HSTS header
thaihostcool.com: max-age too low: 0
the-construct.com: could not connect to host
the-sky-of-valkyries.com: could not connect to host
theamateurs.net: did not receive HSTS header
theamateurs.net: could not connect to host
theater.cf: could not connect to host
theberkshirescompany.com: could not connect to host
thebrotherswarde.com: could not connect to host
@ -3842,7 +3847,6 @@ themerchandiser.net: [Exception... "Component returned failure code: 0x80004005
themicrocapital.com: could not connect to host
themillerslive.com: could not connect to host
theodorejones.info: could not connect to host
theojones.name: did not receive HSTS header
thepartywarehouse.co.uk: did not receive HSTS header
thepiratebay.al: could not connect to host
thepiratebay.tech: could not connect to host
@ -3927,6 +3931,7 @@ toomanypillows.com: could not connect to host
topbargains.com.au: did not receive HSTS header
topmarine.se: could not connect to host
topnewstoday.org: could not connect to host
topodin.com: did not receive HSTS header
topshelfguild.com: could not connect to host
torahanytime.com: did not receive HSTS header
tosecure.link: could not connect to host
@ -3967,7 +3972,6 @@ tubepro.de: max-age too low: 600000
tuingereedschappen.net: could not connect to host
tunai.id: could not connect to host
turnik-67.ru: could not connect to host
turniker.ru: could not connect to host
turtlementors.com: could not connect to host
tuturulianda.com: did not receive HSTS header
tuvalie.com: could not connect to host
@ -4066,7 +4070,6 @@ uy.search.yahoo.com: did not receive HSTS header
uz.search.yahoo.com: did not receive HSTS header
uzmandroid.net: could not connect to host
uzmandroid.top: could not connect to host
v2ex.us: could not connect to host
v4veedu.com: could not connect to host
vaddder.com: could not connect to host
valethound.com: could not connect to host
@ -4121,7 +4124,6 @@ vistarait.com: did not receive HSTS header
vitalorange.com: did not receive HSTS header
viva-french.com: did not receive HSTS header
vlastimilburian.cz: did not receive HSTS header
vlogge.com: could not connect to host
vlora.city: could not connect to host
vm0.eu: did not receive HSTS header
vmrdev.com: could not connect to host
@ -4141,7 +4143,7 @@ vxstream-sandbox.com: [Exception... "Component returned failure code: 0x80004005
vyncke.org: max-age too low: 2678400
vyskocil.eu: could not connect to host
vzk.io: could not connect to host
w4a.fr: max-age too low: 0
w4a.fr: did not receive HSTS header
w4xzr.top: could not connect to host
w4xzr.xyz: could not connect to host
waixingrenfuli7.vip: could not connect to host
@ -4150,6 +4152,7 @@ walkeryoung.ca: could not connect to host
wallet.google.com: did not receive HSTS header (error ignored - included regardless)
wallsblog.dk: could not connect to host
walnutgaming.co.uk: could not connect to host
walnutgaming.com: could not connect to host
wanban.io: could not connect to host
wangqiliang.org: could not connect to host
wangzuan168.cc: did not receive HSTS header
@ -4159,8 +4162,10 @@ warehost.de: did not receive HSTS header
warhistoryonline.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
warmlyyours.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
warped.com: did not receive HSTS header
warsentech.com: could not connect to host
wassim.is: could not connect to host
watchium.com: did not receive HSTS header
watertrails.io: could not connect to host
watsonhall.uk: could not connect to host
wave.is: could not connect to host
wavefrontsystemstech.com: could not connect to host
@ -4169,8 +4174,8 @@ wear2work.nl: did not receive HSTS header
wearandcare.net: could not connect to host
weaverhairextensions.nl: could not connect to host
web.cc: did not receive HSTS header
web4all.fr: max-age too low: 0
web4pro.fr: max-age too low: 0
web4all.fr: did not receive HSTS header
web4pro.fr: did not receive HSTS header
webandwords.com.au: could not connect to host
webassadors.com: could not connect to host
webdesign-kronberg.de: did not receive HSTS header
@ -4184,7 +4189,6 @@ webmaniabr.com: did not receive HSTS header
webmarketingfestival.it: did not receive HSTS header
webnosql.com: could not connect to host
webperformance.ru: max-age too low: 3600
websenat.de: could not connect to host
webstory.xyz: could not connect to host
webswitch.io: could not connect to host
webtiles.co.uk: could not connect to host
@ -4192,7 +4196,6 @@ webwork.pw: could not connect to host
weddingenvelopes.co.uk: did not receive HSTS header
weddingibiza.nl: could not connect to host
weekly.fyi: could not connect to host
weggeweest.nl: could not connect to host
weicn.org: could not connect to host
weizenke.im: could not connect to host
wellsolveit.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
@ -4270,6 +4273,7 @@ wootton95.com: could not connect to host
woresite.jp: did not receive HSTS header
workfone.io: did not receive HSTS header
workwithgo.com: could not connect to host
wow-foederation.de: could not connect to host
wowapi.org: could not connect to host
wphostingspot.com: did not receive HSTS header
wpmetadatastandardsproject.org: could not connect to host
@ -4337,11 +4341,11 @@ xn--lgb3a8bcpn.ga: could not connect to host
xn--lgb3a8bcpn.gq: could not connect to host
xn--lgb3a8bcpn.ml: could not connect to host
xn--ls8hi7a.tk: could not connect to host
xn--maraa-rta.org: could not connect to host
xn--mgbbh2a9fub.xn--ngbc5azd: did not receive HSTS header
xn--neb-tma3u8u.xyz: could not connect to host
xn--werner-schffer-fib.de: could not connect to host
xnode.org: did not receive HSTS header
xobox.me: could not connect to host
xoffy.com: did not receive HSTS header
xombra.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121" data: no]
xpi.fr: could not connect to host
@ -4435,7 +4439,6 @@ zoneminder.com: did not receive HSTS header
zoo24.de: did not receive HSTS header
zoomingin.net: max-age too low: 5184000
zortium.report: could not connect to host
zorz.info: could not connect to host
zoznamrealit.sk: did not receive HSTS header
zqhong.com: could not connect to host
ztan.tk: could not connect to host

File diff suppressed because it is too large Load Diff

View File

@ -50,8 +50,8 @@ static mozilla::LazyLogModule sSHParserLog("nsSecurityHeaderParser");
#define SHPARSERLOG(args) MOZ_LOG(sSHParserLog, mozilla::LogLevel::Debug, args)
nsSecurityHeaderParser::nsSecurityHeaderParser(const char *aHeader)
: mCursor(aHeader)
nsSecurityHeaderParser::nsSecurityHeaderParser(const nsCString& aHeader)
: mCursor(aHeader.get())
, mError(false)
{
}

View File

@ -2,12 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsSecurityHeaderParser_h__
#define nsSecurityHeaderParser_h__
#ifndef nsSecurityHeaderParser_h
#define nsSecurityHeaderParser_h
#include "nsString.h"
#include "mozilla/LinkedList.h"
#include "nsCOMPtr.h"
#include "nsString.h"
// Utility class for handing back parsed directives and (optional) values
class nsSecurityHeaderDirective : public mozilla::LinkedListElement<nsSecurityHeaderDirective> {
@ -36,7 +36,9 @@ public:
class nsSecurityHeaderParser {
public:
explicit nsSecurityHeaderParser(const char *aHeader);
// The input to this class must be null-terminated, and must have a lifetime
// greater than or equal to the lifetime of the created nsSecurityHeaderParser.
explicit nsSecurityHeaderParser(const nsCString& aHeader);
~nsSecurityHeaderParser();
// Only call Parse once.
@ -71,4 +73,4 @@ private:
bool mError;
};
#endif /* nsSecurityHeaderParser_h__ */
#endif // nsSecurityHeaderParser_h

View File

@ -21,11 +21,10 @@
#include "nsIX509Cert.h"
#include "nsNSSComponent.h"
#include "nsNetUtil.h"
#include "nsPromiseFlatString.h"
#include "nsSecurityHeaderParser.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "pkix/pkixtypes.h"
#include "plstr.h"
#include "prnetdb.h"
#include "prprf.h"
@ -436,26 +435,28 @@ nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
}
static bool
HostIsIPAddress(const char *hostname)
HostIsIPAddress(const nsCString& hostname)
{
PRNetAddr hostAddr;
return (PR_StringToNetAddr(hostname, &hostAddr) == PR_SUCCESS);
PRErrorCode prv = PR_StringToNetAddr(hostname.get(), &hostAddr);
return (prv == PR_SUCCESS);
}
NS_IMETHODIMP
nsSiteSecurityService::ProcessHeader(uint32_t aType,
nsIURI* aSourceURI,
const char* aHeader,
const nsACString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::ProcessHeader");
}
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to "
"nsISiteSecurityService::ProcessHeader");
}
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
@ -465,32 +466,35 @@ nsSiteSecurityService::ProcessHeader(uint32_t aType,
NS_ERROR_NOT_IMPLEMENTED);
NS_ENSURE_ARG(aSSLStatus);
return ProcessHeaderInternal(aType, aSourceURI, aHeader, aSSLStatus, aFlags,
aMaxAge, aIncludeSubdomains, aFailureResult);
return ProcessHeaderInternal(aType, aSourceURI, PromiseFlatCString(aHeader),
aSSLStatus, aFlags, aMaxAge, aIncludeSubdomains,
aFailureResult);
}
NS_IMETHODIMP
nsSiteSecurityService::UnsafeProcessHeader(uint32_t aType,
nsIURI* aSourceURI,
const char* aHeader,
const nsACString& aHeader,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::UnsafeProcessHeader");
}
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to "
"nsISiteSecurityService::UnsafeProcessHeader");
}
return ProcessHeaderInternal(aType, aSourceURI, aHeader, nullptr, aFlags,
aMaxAge, aIncludeSubdomains, aFailureResult);
return ProcessHeaderInternal(aType, aSourceURI, PromiseFlatCString(aHeader),
nullptr, aFlags, aMaxAge, aIncludeSubdomains,
aFailureResult);
}
nsresult
nsSiteSecurityService::ProcessHeaderInternal(uint32_t aType,
nsIURI* aSourceURI,
const char* aHeader,
const nsCString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags,
uint64_t* aMaxAge,
@ -540,7 +544,7 @@ nsSiteSecurityService::ProcessHeaderInternal(uint32_t aType,
nsAutoCString host;
nsresult rv = GetHost(aSourceURI, host);
NS_ENSURE_SUCCESS(rv, rv);
if (HostIsIPAddress(host.get())) {
if (HostIsIPAddress(host)) {
/* Don't process headers if a site is accessed by IP address. */
return NS_OK;
}
@ -562,7 +566,7 @@ nsSiteSecurityService::ProcessHeaderInternal(uint32_t aType,
static uint32_t
ParseSSSHeaders(uint32_t aType,
const char* aHeader,
const nsCString& aHeader,
bool& foundIncludeSubdomains,
bool& foundMaxAge,
bool& foundUnrecognizedDirective,
@ -703,7 +707,7 @@ ParseSSSHeaders(uint32_t aType,
nsresult
nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
const char* aHeader,
const nsCString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags,
uint64_t* aMaxAge,
@ -713,7 +717,7 @@ nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
}
SSSLOG(("SSS: processing HPKP header '%s'", aHeader));
SSSLOG(("SSS: processing HPKP header '%s'", aHeader.get()));
NS_ENSURE_ARG(aSSLStatus);
const uint32_t aType = nsISiteSecurityService::HEADER_HPKP;
@ -877,7 +881,7 @@ nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
nsresult
nsSiteSecurityService::ProcessSTSHeader(nsIURI* aSourceURI,
const char* aHeader,
const nsCString& aHeader,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
@ -886,7 +890,7 @@ nsSiteSecurityService::ProcessSTSHeader(nsIURI* aSourceURI,
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
}
SSSLOG(("SSS: processing HSTS header '%s'", aHeader));
SSSLOG(("SSS: processing HSTS header '%s'", aHeader.get()));
const uint32_t aType = nsISiteSecurityService::HEADER_HSTS;
bool foundMaxAge = false;
@ -965,12 +969,12 @@ nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI,
nsresult rv = GetHost(aURI, hostname);
NS_ENSURE_SUCCESS(rv, rv);
/* An IP address never qualifies as a secure URI. */
if (HostIsIPAddress(hostname.get())) {
if (HostIsIPAddress(hostname)) {
*aResult = false;
return NS_OK;
}
return IsSecureHost(aType, hostname.get(), aFlags, aCached, aResult);
return IsSecureHost(aType, hostname, aFlags, aCached, aResult);
}
int STSPreloadCompare(const void *key, const void *entry)
@ -1109,16 +1113,16 @@ nsSiteSecurityService::HostHasHSTSEntry(const nsAutoCString& aHost,
}
NS_IMETHODIMP
nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost,
nsSiteSecurityService::IsSecureHost(uint32_t aType, const nsACString& aHost,
uint32_t aFlags, bool* aCached,
bool* aResult)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) {
MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::IsSecureHost for non-HSTS entries");
}
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) {
MOZ_CRASH("Child process: no direct access to "
"nsISiteSecurityService::IsSecureHost for non-HSTS entries");
}
NS_ENSURE_ARG(aHost);
NS_ENSURE_ARG(aResult);
// Only HSTS and HPKP are supported at the moment.
@ -1133,7 +1137,8 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost,
}
/* An IP address never qualifies as a secure URI. */
if (HostIsIPAddress(aHost)) {
const nsCString& flatHost = PromiseFlatCString(aHost);
if (HostIsIPAddress(flatHost)) {
return NS_OK;
}
@ -1148,12 +1153,14 @@ nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost,
}
bool enforceTestMode = certVerifier->mPinningMode ==
CertVerifier::PinningMode::pinningEnforceTestMode;
return PublicKeyPinningService::HostHasPins(aHost, mozilla::pkix::Now(),
return PublicKeyPinningService::HostHasPins(flatHost.get(),
mozilla::pkix::Now(),
enforceTestMode, *aResult);
}
// Holepunch chart.apis.google.com and subdomains.
nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost));
nsAutoCString host(
PublicKeyPinningService::CanonicalizeHostname(flatHost.get()));
if (host.EqualsLiteral("chart.apis.google.com") ||
StringEndsWith(host, NS_LITERAL_CSTRING(".chart.apis.google.com"))) {
if (aCached) {
@ -1227,25 +1234,28 @@ bool entryStateNotOK(SiteHPKPState& state, mozilla::pkix::Time& aEvalTime) {
}
NS_IMETHODIMP
nsSiteSecurityService::GetKeyPinsForHostname(const char* aHostname,
nsSiteSecurityService::GetKeyPinsForHostname(const nsACString& aHostname,
mozilla::pkix::Time& aEvalTime,
/*out*/ nsTArray<nsCString>& pinArray,
/*out*/ bool* aIncludeSubdomains,
/*out*/ bool* afound) {
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::GetKeyPinsForHostname");
}
/*out*/ bool* afound)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to "
"nsISiteSecurityService::GetKeyPinsForHostname");
}
NS_ENSURE_ARG(afound);
NS_ENSURE_ARG(aHostname);
SSSLOG(("Top of GetKeyPinsForHostname for %s", aHostname));
const nsCString& flatHostname = PromiseFlatCString(aHostname);
SSSLOG(("Top of GetKeyPinsForHostname for %s", flatHostname.get()));
*afound = false;
*aIncludeSubdomains = false;
pinArray.Clear();
nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHostname));
nsAutoCString host(
PublicKeyPinningService::CanonicalizeHostname(flatHostname.get()));
nsAutoCString storageKey;
SetStorageKey(storageKey, host, nsISiteSecurityService::HEADER_HPKP);
@ -1279,18 +1289,19 @@ nsSiteSecurityService::GetKeyPinsForHostname(const char* aHostname,
}
NS_IMETHODIMP
nsSiteSecurityService::SetKeyPins(const char* aHost, bool aIncludeSubdomains,
nsSiteSecurityService::SetKeyPins(const nsACString& aHost,
bool aIncludeSubdomains,
int64_t aExpires, uint32_t aPinCount,
const char** aSha256Pins,
bool aIsPreload,
/*out*/ bool* aResult)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::SetKeyPins");
}
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to "
"nsISiteSecurityService::SetKeyPins");
}
NS_ENSURE_ARG_POINTER(aHost);
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_ARG_POINTER(aSha256Pins);
@ -1308,27 +1319,31 @@ nsSiteSecurityService::SetKeyPins(const char* aHost, bool aIncludeSubdomains,
SiteHPKPState dynamicEntry(aExpires, SecurityPropertySet,
aIncludeSubdomains, sha256keys);
// we always store data in permanent storage (ie no flags)
nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost));
const nsCString& flatHost = PromiseFlatCString(aHost);
nsAutoCString host(
PublicKeyPinningService::CanonicalizeHostname(flatHost.get()));
return SetHPKPState(host.get(), dynamicEntry, 0, aIsPreload);
}
NS_IMETHODIMP
nsSiteSecurityService::SetHSTSPreload(const char* aHost,
nsSiteSecurityService::SetHSTSPreload(const nsACString& aHost,
bool aIncludeSubdomains,
int64_t aExpires,
/*out*/ bool* aResult)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::SetHSTSPreload");
}
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
MOZ_CRASH("Child process: no direct access to "
"nsISiteSecurityService::SetHSTSPreload");
}
NS_ENSURE_ARG_POINTER(aHost);
NS_ENSURE_ARG_POINTER(aResult);
SSSLOG(("Top of SetHSTSPreload"));
nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost));
const nsCString& flatHost = PromiseFlatCString(aHost);
nsAutoCString host(
PublicKeyPinningService::CanonicalizeHostname(flatHost.get()));
return SetHSTSState(nsISiteSecurityService::HEADER_HSTS, host.get(), aExpires,
aIncludeSubdomains, 0, SecurityPropertySet, true);
}

View File

@ -132,14 +132,15 @@ private:
bool includeSubdomains, uint32_t flags,
SecurityPropertyState aHSTSState, bool aIsPreload);
nsresult ProcessHeaderInternal(uint32_t aType, nsIURI* aSourceURI,
const char* aHeader, nsISSLStatus* aSSLStatus,
const nsCString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags, uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult);
nsresult ProcessSTSHeader(nsIURI* aSourceURI, const char* aHeader,
nsresult ProcessSTSHeader(nsIURI* aSourceURI, const nsCString& aHeader,
uint32_t flags, uint64_t* aMaxAge,
bool* aIncludeSubdomains, uint32_t* aFailureResult);
nsresult ProcessPKPHeader(nsIURI* aSourceURI, const char* aHeader,
nsresult ProcessPKPHeader(nsIURI* aSourceURI, const nsCString& aHeader,
nsISSLStatus* aSSLStatus, uint32_t flags,
uint64_t* aMaxAge, bool* aIncludeSubdomains,
uint32_t* aFailureResult);

View File

@ -5,6 +5,7 @@
#include <stdio.h>
#include "gtest/gtest.h"
#include "nsDependentString.h"
#include "nsNetUtil.h"
#include "nsISiteSecurityService.h"
#include "nsIURI.h"
@ -21,7 +22,8 @@ TestSuccess(const char* hdr, bool extraTokens,
uint64_t maxAge = 0;
bool includeSubdomains = false;
rv = sss->UnsafeProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri,
hdr, 0, &maxAge, &includeSubdomains, nullptr);
nsDependentCString(hdr), 0, &maxAge,
&includeSubdomains, nullptr);
ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Failed to process valid header: " << hdr;
ASSERT_EQ(maxAge, expectedMaxAge) << "Did not correctly parse maxAge";
@ -46,7 +48,8 @@ void TestFailure(const char* hdr,
ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Failed to create URI";
rv = sss->UnsafeProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri,
hdr, 0, nullptr, nullptr, nullptr);
nsDependentCString(hdr), 0, nullptr, nullptr,
nullptr);
ASSERT_TRUE(NS_FAILED(rv)) << "Parsed invalid header: " << hdr;
printf("%s\n", hdr);

View File

@ -427,7 +427,7 @@ extensions.registerSchemaAPI("cookies", "addon_parent", context => {
if (!(tab.cookieStoreId in data)) {
data[tab.cookieStoreId] = [];
}
data[tab.cookieStoreId].push(tab);
data[tab.cookieStoreId].push(tab.id);
}
}

View File

@ -85,7 +85,8 @@ add_task(function* test_cookies() {
let stores = await browser.cookies.getAllCookieStores();
browser.test.assertEq(1, stores.length, "expected number of stores returned");
browser.test.assertEq(STORE_ID, stores[0].id, "expected store id returned");
browser.test.assertEq(1, stores[0].tabIds.length, "one tab returned for store");
browser.test.assertEq(1, stores[0].tabIds.length, "one tabId returned for store");
browser.test.assertEq("number", typeof stores[0].tabIds[0], "tabId is a number");
{
let privateWindow = await browser.windows.create({incognito: true});

View File

@ -5,12 +5,9 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'nsPrintingPromptService.cpp',
'nsPrintProgress.cpp',
'nsPrintProgressParams.cpp',
]
SOURCES += [
'nsPrintingPromptServiceX.mm',
]
FINAL_LIBRARY = 'xul'

View File

@ -7,7 +7,6 @@
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsObjCExceptions.h"
#include "nsIPrintingPromptService.h"
#include "nsIFactory.h"
@ -38,8 +37,6 @@ nsresult nsPrintingPromptService::Init()
NS_IMETHODIMP
nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
NS_PRINTDIALOGSERVICE_CONTRACTID));
if (dlgPrint) {
@ -48,8 +45,6 @@ nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrows
}
return NS_ERROR_FAILURE;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP
@ -68,7 +63,6 @@ nsPrintingPromptService::ShowProgress(mozIDOMWindowProxy* parent,
NS_IMETHODIMP
nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
NS_PRINTDIALOGSERVICE_CONTRACTID));
if (dlgPrint) {
@ -76,8 +70,6 @@ nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSetti
}
return NS_ERROR_FAILURE;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMETHODIMP

View File

@ -4175,13 +4175,14 @@
"bug_numbers": [1311910],
"description": "Server HTTP status code from SafeBrowsing database updates. (0=1xx, 1=200, 2=2xx, 3=204, 4=3xx, 5=400, 6=4xx, 7=403, 8=404, 9=408, 10=413, 11=5xx, 12=502|504|511, 13=503, 14=505, 15=Other). Keyed by provider"
},
"URLCLASSIFIER_COMPLETE_REMOTE_STATUS": {
"URLCLASSIFIER_COMPLETE_REMOTE_STATUS2": {
"alert_emails": ["safebrowsing-telemetry@mozilla.org"],
"expires_in_version": "never",
"kind": "enumerated",
"keyed": true,
"n_values": 16,
"bug_numbers": [1150921],
"description": "Server HTTP status code from remote SafeBrowsing gethash lookups. (0=1xx, 1=200, 2=2xx, 3=204, 4=3xx, 5=400, 6=4xx, 7=403, 8=404, 9=408, 10=413, 11=5xx, 12=502|504|511, 13=503, 14=505, 15=Other)"
"bug_numbers": [1150921, 1311926],
"description": "Server HTTP status code from remote SafeBrowsing gethash lookups. (0=1xx, 1=200, 2=2xx, 3=204, 4=3xx, 5=400, 6=4xx, 7=403, 8=404, 9=408, 10=413, 11=5xx, 12=502|504|511, 13=503, 14=505, 15=Other). Keyed by provider"
},
"URLCLASSIFIER_COMPLETION_ERROR": {
"alert_emails": ["safebrowsing-telemetry@mozilla.org"],
@ -4191,12 +4192,13 @@
"bug_numbers": [1276826],
"description": "SafeBrowsing v4 hash completion error (0 = success, 1 = parsing failure, 2 = unknown threat type)"
},
"URLCLASSIFIER_COMPLETE_TIMEOUT": {
"URLCLASSIFIER_COMPLETE_TIMEOUT2": {
"alert_emails": ["safebrowsing-telemetry@mozilla.org"],
"expires_in_version": "56",
"expires_in_version": "59",
"kind": "boolean",
"bug_numbers": [1172688],
"description": "This metric is recorded every time a gethash lookup is performed, `true` is recorded if the lookup times out."
"keyed": true,
"bug_numbers": [1172688, 1311926],
"description": "This metric is recorded every time a gethash lookup is performed, `true` is recorded if the lookup times out. Keyed by provider"
},
"URLCLASSIFIER_UPDATE_ERROR": {
"alert_emails": ["safebrowsing-telemetry@mozilla.org"],

View File

@ -290,6 +290,8 @@ function HashCompleterRequest(aCompleter, aGethashUrl) {
// Multiple partial hashes can be associated with the same tables
// so we use a map here.
this.tableNames = new Map();
this.telemetryProvider = "";
}
HashCompleterRequest.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
@ -316,6 +318,11 @@ HashCompleterRequest.prototype = {
'the same gethash URL.');
}
this.tableNames.set(aTableName);
// Assuming all tables with the same gethash URL have the same provider
if (this.telemetryProvider == "") {
this.telemetryProvider = gUrlUtil.getTelemetryProvider(aTableName);
}
}
},
@ -376,7 +383,8 @@ HashCompleterRequest.prototype = {
// channel.
if (this._channel && this._channel.isPending()) {
log("cancelling request to " + this.gethashUrl + "\n");
Services.telemetry.getHistogramById("URLCLASSIFIER_COMPLETE_TIMEOUT").add(1);
Services.telemetry.getKeyedHistogramById("URLCLASSIFIER_COMPLETE_TIMEOUT2").
add(this.telemetryProvider, 1);
this._channel.cancel(Cr.NS_BINDING_ABORTED);
}
},
@ -664,10 +672,10 @@ HashCompleterRequest.prototype = {
let success = Components.isSuccessCode(aStatusCode);
log('Received a ' + httpStatus + ' status code from the gethash server (success=' + success + ').');
let histogram =
Services.telemetry.getHistogramById("URLCLASSIFIER_COMPLETE_REMOTE_STATUS");
histogram.add(httpStatusToBucket(httpStatus));
Services.telemetry.getHistogramById("URLCLASSIFIER_COMPLETE_TIMEOUT").add(0);
Services.telemetry.getKeyedHistogramById("URLCLASSIFIER_COMPLETE_REMOTE_STATUS2").
add(this.telemetryProvider, httpStatusToBucket(httpStatus));
Services.telemetry.getKeyedHistogramById("URLCLASSIFIER_COMPLETE_TIMEOUT2").
add(this.telemetryProvider, 0);
// Notify the RequestBackoff once a response is received.
this._completer.finishRequest(this.gethashUrl, httpStatus);

Some files were not shown because too many files have changed in this diff Show More