mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
0c21611303
@ -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);
|
||||
|
||||
|
@ -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':
|
||||
|
@ -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;
|
||||
|
@ -419,6 +419,12 @@ class Viewport {
|
||||
});
|
||||
}
|
||||
|
||||
save() {
|
||||
this._doAction({
|
||||
type: 'save'
|
||||
});
|
||||
}
|
||||
|
||||
// A handler for delivering messages to runtime.
|
||||
registerActionHandler(handler) {
|
||||
if (typeof handler === 'function') {
|
||||
|
@ -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);
|
||||
|
@ -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]
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
@ -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();
|
||||
|
@ -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"),
|
||||
|
@ -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"],
|
||||
|
@ -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"], []],
|
||||
|
@ -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");
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
location: ["cookies", "sectest1.example.org"],
|
||||
location: ["cookies", "https://sectest1.example.org"],
|
||||
sidebarHidden: true
|
||||
},
|
||||
{
|
||||
|
134
devtools/client/storage/test/storage-listings-with-fragment.html
Normal file
134
devtools/client/storage/test/storage-listings-with-fragment.html
Normal 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>
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 970517 - Storage inspector front end - tests
|
||||
Storage inspector front end - tests
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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",
|
||||
|
@ -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/")
|
||||
]
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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/"),
|
||||
]
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
11
dom/animation/test/crashtests/1330190-1.html
Normal file
11
dom/animation/test/crashtests/1330190-1.html
Normal 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>
|
35
dom/animation/test/crashtests/1330190-2.html
Normal file
35
dom/animation/test/crashtests/1330190-2.html
Normal 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>
|
@ -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
|
||||
|
@ -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())) {
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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
|
@ -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'
|
@ -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']
|
||||
|
44
js/src/jit-test/tests/debug/bug1330489-sps.js
Normal file
44
js/src/jit-test/tests/debug/bug1330489-sps.js
Normal 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";
|
36
js/src/jit-test/tests/debug/bug1330489.js
Normal file
36
js/src/jit-test/tests/debug/bug1330489.js
Normal 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";
|
@ -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(`
|
||||
|
@ -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_;
|
||||
|
@ -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,
|
||||
|
@ -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*
|
||||
|
@ -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;
|
||||
|
@ -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()));
|
||||
|
@ -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:
|
||||
|
@ -1017,7 +1017,7 @@ enum class SymbolicAddress
|
||||
ReportOverRecursed,
|
||||
HandleExecutionInterrupt,
|
||||
HandleDebugTrap,
|
||||
HandleDebugThrow,
|
||||
HandleThrow,
|
||||
ReportTrap,
|
||||
ReportOutOfBounds,
|
||||
ReportUnalignedAccess,
|
||||
|
@ -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
|
||||
|
41
layout/reftests/transform-3d/split-intersect1-ref.html
Normal file
41
layout/reftests/transform-3d/split-intersect1-ref.html
Normal 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>
|
43
layout/reftests/transform-3d/split-intersect1.html
Normal file
43
layout/reftests/transform-3d/split-intersect1.html
Normal 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>
|
82
layout/reftests/transform-3d/split-intersect2-ref.html
Normal file
82
layout/reftests/transform-3d/split-intersect2-ref.html
Normal 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>
|
50
layout/reftests/transform-3d/split-intersect2.html
Normal file
50
layout/reftests/transform-3d/split-intersect2.html
Normal 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>
|
88
layout/reftests/transform-3d/split-non-ortho1-ref.html
Normal file
88
layout/reftests/transform-3d/split-non-ortho1-ref.html
Normal 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>
|
54
layout/reftests/transform-3d/split-non-ortho1.html
Normal file
54
layout/reftests/transform-3d/split-non-ortho1.html
Normal 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>
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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_(); \
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -359,6 +359,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
progressBar.setImageDrawable(getResources().getDrawable(R.drawable.progress));
|
||||
urlDisplayLayout.dismissSiteIdentityPopup();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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"));
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsIContentSignatureVerifier.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
#include "nsString.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
|
||||
// 45a5fe2f-c350-4b86-962d-02d5aaaa955a
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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});
|
||||
|
@ -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'
|
||||
|
@ -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
|
@ -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"],
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user