зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1355166 - Remove remote newtab's dead code. r=ursula
This commit is contained in:
Родитель
623d991cc1
Коммит
fc42b2fa73
|
@ -90,10 +90,6 @@ var whitelist = [
|
||||||
// browser/extensions/pdfjs/content/web/viewer.js
|
// browser/extensions/pdfjs/content/web/viewer.js
|
||||||
{file: "resource://pdf.js/build/pdf.worker.js"},
|
{file: "resource://pdf.js/build/pdf.worker.js"},
|
||||||
|
|
||||||
// browser/components/newtab bug 1355166
|
|
||||||
{file: "resource://app/modules/NewTabSearchProvider.jsm"},
|
|
||||||
{file: "resource://app/modules/NewTabWebChannel.jsm"},
|
|
||||||
|
|
||||||
// layout/mathml/nsMathMLChar.cpp
|
// layout/mathml/nsMathMLChar.cpp
|
||||||
{file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties"},
|
{file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties"},
|
||||||
{file: "resource://gre/res/fonts/mathfontUnicode.properties"},
|
{file: "resource://gre/res/fonts/mathfontUnicode.properties"},
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["NewTabPrefsProvider"];
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
|
|
||||||
const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
|
|
||||||
return EventEmitter;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Supported prefs and data type
|
|
||||||
const gPrefsMap = new Map([
|
|
||||||
["browser.newtabpage.enabled", "bool"],
|
|
||||||
["browser.newtabpage.enhanced", "bool"],
|
|
||||||
["browser.newtabpage.introShown", "bool"],
|
|
||||||
["browser.newtabpage.updateIntroShown", "bool"],
|
|
||||||
["browser.newtabpage.pinned", "str"],
|
|
||||||
["browser.newtabpage.blocked", "str"],
|
|
||||||
["browser.search.hiddenOneOffs", "str"],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// prefs that are important for the newtab page
|
|
||||||
const gNewtabPagePrefs = new Set([
|
|
||||||
"browser.newtabpage.enabled",
|
|
||||||
"browser.newtabpage.enhanced",
|
|
||||||
"browser.newtabpage.pinned",
|
|
||||||
"browser.newtabpage.blocked",
|
|
||||||
"browser.newtabpage.introShown",
|
|
||||||
"browser.newtabpage.updateIntroShown",
|
|
||||||
"browser.search.hiddenOneOffs",
|
|
||||||
]);
|
|
||||||
|
|
||||||
let PrefsProvider = function PrefsProvider() {
|
|
||||||
EventEmitter.decorate(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
PrefsProvider.prototype = {
|
|
||||||
|
|
||||||
observe(subject, topic, data) { // jshint ignore:line
|
|
||||||
if (topic === "nsPref:changed") {
|
|
||||||
if (gPrefsMap.has(data)) {
|
|
||||||
switch (gPrefsMap.get(data)) {
|
|
||||||
case "bool":
|
|
||||||
this.emit(data, Services.prefs.getBoolPref(data, false));
|
|
||||||
break;
|
|
||||||
case "str":
|
|
||||||
this.emit(data, Services.prefs.getStringPref(data, ""));
|
|
||||||
break;
|
|
||||||
case "localized":
|
|
||||||
if (Services.prefs.getPrefType(data) == Ci.nsIPrefBranch.PREF_INVALID) {
|
|
||||||
this.emit(data, "");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
this.emit(data, Services.prefs.getComplexValue(data, Ci.nsIPrefLocalizedString));
|
|
||||||
} catch (e) {
|
|
||||||
this.emit(data, Services.prefs.getStringPref(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.emit(data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Cu.reportError(new Error("NewTabPrefsProvider observing unknown topic"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the preferences that are important to the newtab page
|
|
||||||
*/
|
|
||||||
get newtabPagePrefs() {
|
|
||||||
let results = {};
|
|
||||||
for (let pref of gNewtabPagePrefs) {
|
|
||||||
results[pref] = null;
|
|
||||||
|
|
||||||
if (Services.prefs.getPrefType(pref) != Ci.nsIPrefBranch.PREF_INVALID) {
|
|
||||||
switch (gPrefsMap.get(pref)) {
|
|
||||||
case "bool":
|
|
||||||
results[pref] = Services.prefs.getBoolPref(pref);
|
|
||||||
break;
|
|
||||||
case "str":
|
|
||||||
results[pref] = Services.prefs.getStringPref(pref);
|
|
||||||
break;
|
|
||||||
case "localized":
|
|
||||||
try {
|
|
||||||
results[pref] = Services.prefs.getComplexValue(pref, Ci.nsIPrefLocalizedString);
|
|
||||||
} catch (e) {
|
|
||||||
results[pref] = Services.prefs.getStringPref(pref);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
},
|
|
||||||
|
|
||||||
get prefsMap() {
|
|
||||||
return gPrefsMap;
|
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
|
||||||
for (let pref of gPrefsMap.keys()) {
|
|
||||||
Services.prefs.addObserver(pref, this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
for (let pref of gPrefsMap.keys()) {
|
|
||||||
Services.prefs.removeObserver(pref, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Singleton that serves as the default new tab pref provider for the grid.
|
|
||||||
*/
|
|
||||||
const gPrefs = new PrefsProvider();
|
|
||||||
|
|
||||||
let NewTabPrefsProvider = {
|
|
||||||
prefs: gPrefs,
|
|
||||||
newtabPagePrefSet: gNewtabPagePrefs,
|
|
||||||
};
|
|
|
@ -1,15 +0,0 @@
|
||||||
/* exported NewTabRemoteResources */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["NewTabRemoteResources"];
|
|
||||||
|
|
||||||
const NewTabRemoteResources = {
|
|
||||||
MODE_CHANNEL_MAP: {
|
|
||||||
production: {origin: "https://content.cdn.mozilla.net"},
|
|
||||||
staging: {origin: "https://s3_proxy_tiles.stage.mozaws.net"},
|
|
||||||
test: {origin: "https://example.com"},
|
|
||||||
test2: {origin: "http://mochi.test:8888"},
|
|
||||||
dev: {origin: "http://localhost:8888"}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,98 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["NewTabSearchProvider"];
|
|
||||||
|
|
||||||
const CURRENT_ENGINE = "browser-search-engine-modified";
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "ContentSearch",
|
|
||||||
"resource:///modules/ContentSearch.jsm");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
|
|
||||||
const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
|
|
||||||
return EventEmitter;
|
|
||||||
});
|
|
||||||
|
|
||||||
function SearchProvider() {
|
|
||||||
EventEmitter.decorate(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchProvider.prototype = {
|
|
||||||
|
|
||||||
observe(subject, topic, data) { // jshint unused:false
|
|
||||||
// all other topics are not relevant to content searches and can be
|
|
||||||
// ignored by NewTabSearchProvider
|
|
||||||
if (data === "engine-current" && topic === CURRENT_ENGINE) {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
let state = await ContentSearch.currentStateObj(true);
|
|
||||||
let engine = state.currentEngine;
|
|
||||||
this.emit(CURRENT_ENGINE, engine);
|
|
||||||
} catch (e) {
|
|
||||||
Cu.reportError(e);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
|
||||||
try {
|
|
||||||
Services.obs.addObserver(this, CURRENT_ENGINE, true);
|
|
||||||
} catch (e) {
|
|
||||||
Cu.reportError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
|
||||||
Ci.nsISupportsWeakReference
|
|
||||||
]),
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
try {
|
|
||||||
Services.obs.removeObserver(this, CURRENT_ENGINE);
|
|
||||||
} catch (e) {
|
|
||||||
Cu.reportError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get searchSuggestionUIStrings() {
|
|
||||||
return ContentSearch.searchSuggestionUIStrings;
|
|
||||||
},
|
|
||||||
|
|
||||||
removeFormHistory({browser}, suggestion) {
|
|
||||||
ContentSearch.removeFormHistoryEntry({target: browser}, suggestion);
|
|
||||||
},
|
|
||||||
|
|
||||||
manageEngines(browser) {
|
|
||||||
const browserWin = browser.ownerGlobal;
|
|
||||||
browserWin.openPreferences("paneSearch", { origin: "contentSearch" });
|
|
||||||
},
|
|
||||||
|
|
||||||
async asyncGetState() {
|
|
||||||
let state = await ContentSearch.currentStateObj(true);
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
|
|
||||||
async asyncPerformSearch({browser}, searchData) {
|
|
||||||
ContentSearch.performSearch({target: browser}, searchData);
|
|
||||||
await ContentSearch.addFormHistoryEntry({target: browser}, searchData.searchString);
|
|
||||||
},
|
|
||||||
|
|
||||||
async asyncCycleEngine(engineName) {
|
|
||||||
Services.search.currentEngine = Services.search.getEngineByName(engineName);
|
|
||||||
let state = await ContentSearch.currentStateObj(true);
|
|
||||||
let newEngine = state.currentEngine;
|
|
||||||
this.emit(CURRENT_ENGINE, newEngine);
|
|
||||||
},
|
|
||||||
|
|
||||||
async asyncGetSuggestions(engineName, searchString, target) {
|
|
||||||
let suggestions = ContentSearch.getSuggestions(engineName, searchString, target.browser);
|
|
||||||
return suggestions;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const NewTabSearchProvider = {
|
|
||||||
search: new SearchProvider(),
|
|
||||||
};
|
|
|
@ -1,286 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["NewTabWebChannel"];
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "NewTabPrefsProvider",
|
|
||||||
"resource:///modules/NewTabPrefsProvider.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "NewTabRemoteResources",
|
|
||||||
"resource:///modules/NewTabRemoteResources.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "WebChannel",
|
|
||||||
"resource://gre/modules/WebChannel.jsm");
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
|
|
||||||
const {EventEmitter} = ChromeUtils.import("resource://gre/modules/EventEmitter.jsm", {});
|
|
||||||
return EventEmitter;
|
|
||||||
});
|
|
||||||
|
|
||||||
const CHAN_ID = "newtab";
|
|
||||||
const PREF_ENABLED = "browser.newtabpage.remote";
|
|
||||||
const PREF_MODE = "browser.newtabpage.remote.mode";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NewTabWebChannel is the conduit for all communication with unprivileged newtab instances.
|
|
||||||
*
|
|
||||||
* It allows for the ability to broadcast to all newtab browsers.
|
|
||||||
* If the browser.newtab.remote pref is false, the object will be in an uninitialized state.
|
|
||||||
*
|
|
||||||
* Mode choices:
|
|
||||||
* 'production': pages from our production CDN
|
|
||||||
* 'staging': pages from our staging CDN
|
|
||||||
* 'test': intended for tests
|
|
||||||
* 'test2': intended for tests
|
|
||||||
* 'dev': intended for development
|
|
||||||
*
|
|
||||||
* An unknown mode will result in 'production' mode, which is the default
|
|
||||||
*
|
|
||||||
* Incoming messages are expected to be JSON-serialized and in the format:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* type: "REQUEST_SCREENSHOT",
|
|
||||||
* data: {
|
|
||||||
* url: "https://example.com"
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Or:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* type: "REQUEST_SCREENSHOT",
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Outgoing messages are expected to be objects serializable by structured cloning, in a similar format:
|
|
||||||
* {
|
|
||||||
* type: "RECEIVE_SCREENSHOT",
|
|
||||||
* data: {
|
|
||||||
* "url": "https://example.com",
|
|
||||||
* "image": "dataURi:....."
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
let NewTabWebChannelImpl = function NewTabWebChannelImpl() {
|
|
||||||
EventEmitter.decorate(this);
|
|
||||||
this._handlePrefChange = this._handlePrefChange.bind(this);
|
|
||||||
this._incomingMessage = this._incomingMessage.bind(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
NewTabWebChannelImpl.prototype = {
|
|
||||||
_prefs: {},
|
|
||||||
_channel: null,
|
|
||||||
|
|
||||||
// a WeakMap containing browsers as keys and a weak ref to their principal
|
|
||||||
// as value
|
|
||||||
_principals: null,
|
|
||||||
|
|
||||||
// a Set containing weak refs to browsers
|
|
||||||
_browsers: null,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns current channel's ID
|
|
||||||
*/
|
|
||||||
get chanId() {
|
|
||||||
return CHAN_ID;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the number of browsers currently tracking
|
|
||||||
*/
|
|
||||||
get numBrowsers() {
|
|
||||||
return this._getBrowserRefs().length;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns current channel's origin
|
|
||||||
*/
|
|
||||||
get origin() {
|
|
||||||
if (!(this._prefs.mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
|
|
||||||
this._prefs.mode = "production";
|
|
||||||
}
|
|
||||||
return NewTabRemoteResources.MODE_CHANNEL_MAP[this._prefs.mode].origin;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unloads all browsers and principals
|
|
||||||
*/
|
|
||||||
_unloadAll() {
|
|
||||||
if (this._principals != null) {
|
|
||||||
this._principals = new WeakMap();
|
|
||||||
}
|
|
||||||
this._browsers = new Set();
|
|
||||||
this.emit("targetUnloadAll");
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks if a browser is known
|
|
||||||
*
|
|
||||||
* This will cause an iteration through all known browsers.
|
|
||||||
* That's ok, we don't expect a lot of browsers
|
|
||||||
*/
|
|
||||||
_isBrowserKnown(browser) {
|
|
||||||
for (let bRef of this._getBrowserRefs()) {
|
|
||||||
let b = bRef.get();
|
|
||||||
if (b && b.permanentKey === browser.permanentKey) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Obtains all known browser refs
|
|
||||||
*/
|
|
||||||
_getBrowserRefs() {
|
|
||||||
// Some code may try to emit messages after teardown.
|
|
||||||
if (!this._browsers) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
let refs = [];
|
|
||||||
for (let bRef of this._browsers) {
|
|
||||||
/*
|
|
||||||
* even though we hold a weak ref to browser, it seems that browser
|
|
||||||
* objects aren't gc'd immediately after a tab closes. They stick around
|
|
||||||
* in memory, but thankfully they don't have a documentURI in that case
|
|
||||||
*/
|
|
||||||
let browser = bRef.get();
|
|
||||||
if (browser && browser.documentURI) {
|
|
||||||
refs.push(bRef);
|
|
||||||
} else {
|
|
||||||
// need to clean up principals because the browser object is not gc'ed
|
|
||||||
// immediately
|
|
||||||
this._principals.delete(browser);
|
|
||||||
this._browsers.delete(bRef);
|
|
||||||
this.emit("targetUnload");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return refs;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Receives a message from content.
|
|
||||||
*
|
|
||||||
* Keeps track of browsers for broadcast, relays messages to listeners.
|
|
||||||
*/
|
|
||||||
_incomingMessage(id, message, target) {
|
|
||||||
if (this.chanId !== id) {
|
|
||||||
Cu.reportError(new Error("NewTabWebChannel unexpected message destination"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* need to differentiate by browser, because event targets are created each
|
|
||||||
* time a message is sent.
|
|
||||||
*/
|
|
||||||
if (!this._isBrowserKnown(target.browser)) {
|
|
||||||
this._browsers.add(Cu.getWeakReference(target.browser));
|
|
||||||
this._principals.set(target.browser, Cu.getWeakReference(target.principal));
|
|
||||||
this.emit("targetAdd");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let msg = JSON.parse(message);
|
|
||||||
this.emit(msg.type, {data: msg.data, target});
|
|
||||||
} catch (err) {
|
|
||||||
Cu.reportError(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sends a message to all known browsers
|
|
||||||
*/
|
|
||||||
broadcast(actionType, message) {
|
|
||||||
for (let bRef of this._getBrowserRefs()) {
|
|
||||||
let browser = bRef.get();
|
|
||||||
try {
|
|
||||||
let principal = this._principals.get(browser).get();
|
|
||||||
if (principal && browser && browser.documentURI) {
|
|
||||||
this._channel.send({type: actionType, data: message}, {browser, principal});
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Cu.reportError(new Error("NewTabWebChannel WeakRef is dead"));
|
|
||||||
this._principals.delete(browser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sends a message to a specific target
|
|
||||||
*/
|
|
||||||
send(actionType, message, target) {
|
|
||||||
try {
|
|
||||||
this._channel.send({type: actionType, data: message}, target);
|
|
||||||
} catch (e) {
|
|
||||||
// Web Channel might be dead
|
|
||||||
Cu.reportError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pref change observer callback
|
|
||||||
*/
|
|
||||||
_handlePrefChange(prefName, newState, forceState) { // eslint-disable-line no-unused-vars
|
|
||||||
switch (prefName) {
|
|
||||||
case PREF_ENABLED:
|
|
||||||
if (!this._prefs.enabled && newState) {
|
|
||||||
// changing state from disabled to enabled
|
|
||||||
this.setupState();
|
|
||||||
} else if (this._prefs.enabled && !newState) {
|
|
||||||
// changing state from enabled to disabled
|
|
||||||
this.tearDownState();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PREF_MODE:
|
|
||||||
if (this._prefs.mode !== newState) {
|
|
||||||
// changing modes
|
|
||||||
this.tearDownState();
|
|
||||||
this.setupState();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets up the internal state
|
|
||||||
*/
|
|
||||||
setupState() {
|
|
||||||
this._prefs.enabled = Services.prefs.getBoolPref(PREF_ENABLED, false);
|
|
||||||
|
|
||||||
let mode = Services.prefs.getStringPref(PREF_MODE, "production");
|
|
||||||
if (!(mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
|
|
||||||
mode = "production";
|
|
||||||
}
|
|
||||||
this._prefs.mode = mode;
|
|
||||||
this._principals = new WeakMap();
|
|
||||||
this._browsers = new Set();
|
|
||||||
|
|
||||||
if (this._prefs.enabled) {
|
|
||||||
this._channel = new WebChannel(this.chanId, Services.io.newURI(this.origin));
|
|
||||||
this._channel.listen(this._incomingMessage);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
tearDownState() {
|
|
||||||
if (this._channel) {
|
|
||||||
this._channel.stopListening();
|
|
||||||
}
|
|
||||||
this._prefs = {};
|
|
||||||
this._unloadAll();
|
|
||||||
this._channel = null;
|
|
||||||
this._principals = null;
|
|
||||||
this._browsers = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.setupState();
|
|
||||||
NewTabPrefsProvider.prefs.on(PREF_ENABLED, this._handlePrefChange);
|
|
||||||
NewTabPrefsProvider.prefs.on(PREF_MODE, this._handlePrefChange);
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
this.tearDownState();
|
|
||||||
NewTabPrefsProvider.prefs.off(PREF_ENABLED, this._handlePrefChange);
|
|
||||||
NewTabPrefsProvider.prefs.off(PREF_MODE, this._handlePrefChange);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let NewTabWebChannel = new NewTabWebChannelImpl();
|
|
|
@ -13,13 +13,6 @@ XPCSHELL_TESTS_MANIFESTS += [
|
||||||
'tests/xpcshell/xpcshell.ini',
|
'tests/xpcshell/xpcshell.ini',
|
||||||
]
|
]
|
||||||
|
|
||||||
EXTRA_JS_MODULES += [
|
|
||||||
'NewTabPrefsProvider.jsm',
|
|
||||||
'NewTabRemoteResources.jsm',
|
|
||||||
'NewTabSearchProvider.jsm',
|
|
||||||
'NewTabWebChannel.jsm'
|
|
||||||
]
|
|
||||||
|
|
||||||
XPIDL_SOURCES += [
|
XPIDL_SOURCES += [
|
||||||
'nsIAboutNewTabService.idl',
|
'nsIAboutNewTabService.idl',
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
ChromeUtils.import("resource://gre/modules/Preferences.jsm");
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "NewTabPrefsProvider",
|
|
||||||
"resource:///modules/NewTabPrefsProvider.jsm");
|
|
||||||
|
|
||||||
add_task(async function test_observe() {
|
|
||||||
let prefsMap = NewTabPrefsProvider.prefs.prefsMap;
|
|
||||||
for (let prefName of prefsMap.keys()) {
|
|
||||||
let prefValueType = prefsMap.get(prefName);
|
|
||||||
|
|
||||||
let beforeVal;
|
|
||||||
let afterVal;
|
|
||||||
|
|
||||||
switch (prefValueType) {
|
|
||||||
case "bool":
|
|
||||||
beforeVal = false;
|
|
||||||
afterVal = true;
|
|
||||||
Preferences.set(prefName, beforeVal);
|
|
||||||
break;
|
|
||||||
case "localized":
|
|
||||||
case "str":
|
|
||||||
beforeVal = "";
|
|
||||||
afterVal = "someStr";
|
|
||||||
Preferences.set(prefName, beforeVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
NewTabPrefsProvider.prefs.init();
|
|
||||||
let promise = new Promise(resolve => {
|
|
||||||
NewTabPrefsProvider.prefs.once(prefName, (name, data) => { // jshint ignore:line
|
|
||||||
resolve([name, data]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Preferences.set(prefName, afterVal);
|
|
||||||
let [actualName, actualData] = await promise;
|
|
||||||
equal(prefName, actualName, `emitter sent the correct pref: ${prefName}`);
|
|
||||||
equal(afterVal, actualData, `emitter collected correct pref data for ${prefName}`);
|
|
||||||
NewTabPrefsProvider.prefs.uninit();
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,74 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "NewTabSearchProvider",
|
|
||||||
"resource:///modules/NewTabSearchProvider.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "ContentSearch",
|
|
||||||
"resource:///modules/ContentSearch.jsm");
|
|
||||||
|
|
||||||
// ensure a profile exists
|
|
||||||
do_get_profile();
|
|
||||||
|
|
||||||
function hasProp(obj) {
|
|
||||||
return function(aProp) {
|
|
||||||
ok(obj.hasOwnProperty(aProp), `expect to have property ${aProp}`);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
add_task(async function test_search() {
|
|
||||||
ContentSearch.init();
|
|
||||||
let observerPromise = new Promise(resolve => {
|
|
||||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
|
||||||
if (aData === "init-complete" && aTopic === "browser-search-service") {
|
|
||||||
Services.obs.removeObserver(observer, "browser-search-service");
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}, "browser-search-service");
|
|
||||||
});
|
|
||||||
Services.search.init();
|
|
||||||
await observerPromise;
|
|
||||||
Assert.ok(Services.search.isInitialized);
|
|
||||||
|
|
||||||
// get initial state of search and check it has correct properties
|
|
||||||
let state = await NewTabSearchProvider.search.asyncGetState();
|
|
||||||
let stateProps = hasProp(state);
|
|
||||||
["engines", "currentEngine"].forEach(stateProps);
|
|
||||||
|
|
||||||
// check that the current engine is correct and has correct properties
|
|
||||||
let {currentEngine} = state;
|
|
||||||
equal(currentEngine.name, Services.search.currentEngine.name, "Current engine has been correctly set");
|
|
||||||
var engineProps = hasProp(currentEngine);
|
|
||||||
["name", "placeholder", "iconBuffer"].forEach(engineProps);
|
|
||||||
|
|
||||||
// create dummy test engines to test observer
|
|
||||||
Services.search.addEngineWithDetails("TestSearch1", "", "", "", "GET",
|
|
||||||
"http://example.com/?q={searchTerms}");
|
|
||||||
Services.search.addEngineWithDetails("TestSearch2", "", "", "", "GET",
|
|
||||||
"http://example.com/?q={searchTerms}");
|
|
||||||
|
|
||||||
// set one of the dummy test engines to the default engine
|
|
||||||
Services.search.defaultEngine = Services.search.getEngineByName("TestSearch1");
|
|
||||||
|
|
||||||
// test that the event emitter is working by setting a new current engine "TestSearch2"
|
|
||||||
let engineName = "TestSearch2";
|
|
||||||
NewTabSearchProvider.search.init();
|
|
||||||
|
|
||||||
// event emitter will fire when current engine is changed
|
|
||||||
let promise = new Promise(resolve => {
|
|
||||||
NewTabSearchProvider.search.once("browser-search-engine-modified", (name, data) => { // jshint ignore:line
|
|
||||||
resolve([name, data.name]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// set a new current engine
|
|
||||||
Services.search.currentEngine = Services.search.getEngineByName(engineName);
|
|
||||||
let expectedEngineName = Services.search.currentEngine.name;
|
|
||||||
|
|
||||||
// emitter should fire and return the new engine
|
|
||||||
let [eventName, actualEngineName] = await promise;
|
|
||||||
equal(eventName, "browser-search-engine-modified", `emitter sent the correct event ${eventName}`);
|
|
||||||
equal(expectedEngineName, actualEngineName, `emitter set the correct engine ${expectedEngineName}`);
|
|
||||||
NewTabSearchProvider.search.uninit();
|
|
||||||
});
|
|
|
@ -4,5 +4,3 @@ firefox-appdir = browser
|
||||||
skip-if = toolkit == 'android'
|
skip-if = toolkit == 'android'
|
||||||
|
|
||||||
[test_AboutNewTabService.js]
|
[test_AboutNewTabService.js]
|
||||||
[test_NewTabPrefsProvider.js]
|
|
||||||
[test_NewTabSearchProvider.js]
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
[DEFAULT]
|
|
||||||
support-files =
|
|
||||||
file_contentserver.sjs
|
|
||||||
file_about_newtab.html
|
|
||||||
file_about_newtab_bad.html
|
|
||||||
file_about_newtab_bad_csp.html
|
|
||||||
file_about_newtab_bad_csp_signature
|
|
||||||
file_about_newtab_good_signature
|
|
||||||
file_about_newtab_bad_signature
|
|
||||||
file_about_newtab_broken_signature
|
|
||||||
file_about_newtab_sri.html
|
|
||||||
file_about_newtab_sri_signature
|
|
||||||
goodChain.pem
|
|
||||||
head.js
|
|
||||||
script.js
|
|
||||||
style.css
|
|
||||||
|
|
||||||
[browser_verify_content_about_newtab.js]
|
|
||||||
[browser_verify_content_about_newtab2.js]
|
|
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
const TESTS = [
|
|
||||||
// { newtab (aboutURI) or regular load (url) : url,
|
|
||||||
// testStrings : expected strings in the loaded page }
|
|
||||||
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
|
|
||||||
{ "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "url" : URI_BAD_FILE_CACHED, "testStrings" : [BAD_ABOUT_STRING] },
|
|
||||||
{ "aboutURI" : URI_BAD_FILE_CACHED, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
|
|
||||||
{ "aboutURI" : URI_SRI, "testStrings" : [
|
|
||||||
STYLESHEET_WITHOUT_SRI_BLOCKED,
|
|
||||||
STYLESHEET_WITH_SRI_LOADED,
|
|
||||||
SCRIPT_WITHOUT_SRI_BLOCKED,
|
|
||||||
SCRIPT_WITH_SRI_LOADED,
|
|
||||||
]},
|
|
||||||
{ "aboutURI" : URI_BAD_CSP, "testStrings" : [CSP_TEST_SUCCESS_STRING] },
|
|
||||||
{ "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] },
|
|
||||||
];
|
|
||||||
|
|
||||||
add_task(runTests);
|
|
|
@ -1,19 +0,0 @@
|
||||||
|
|
||||||
const TESTS = [
|
|
||||||
// { newtab (aboutURI) or regular load (url) : url,
|
|
||||||
// testStrings : expected strings in the loaded page }
|
|
||||||
{ "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] },
|
|
||||||
{ "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_KEYERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_SIGERROR_HEADER, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_NO_HEADER, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_BAD_SIG, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_BROKEN_SIG, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_BAD_X5U, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_HTTP_X5U, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_BAD_FILE, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "aboutURI" : URI_BAD_ALL, "testStrings" : [ABOUT_BLANK] },
|
|
||||||
{ "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] },
|
|
||||||
];
|
|
||||||
|
|
||||||
add_task(runTests);
|
|
|
@ -1,11 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1226928 -->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Testpage for bug 1226928</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Just a fully good testpage for Bug 1226928<br/>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1226928 -->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Testpage for bug 1226928</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Just a bad testpage for Bug 1226928<br/>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Testpage for CSP violation (inline script)</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
CSP violation test succeeded.
|
|
||||||
<script>
|
|
||||||
// This inline script would override the success string if loaded.
|
|
||||||
document.body.innerHTML = "CSP violation test failed.";
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1 +0,0 @@
|
||||||
oiypz3lb-IyJsmKNsnlp2zDrqncste8yONn9WUE6ksgJWMhSEQ9lp8vRqN0W3JPwJb6uSk16RI-tDv7uy0jxon5jL1BZpqlqIpvimg7FCQEedMKoHZwtE9an-e95sOTd
|
|
|
@ -1 +0,0 @@
|
||||||
KirX94omQL7lKfWGhc777t8U29enDg0O0UcJLH3PRXcvWGO8KA6mmLS3yNCFnGiTjP3vNnVtm-sUkXr4ix8WTkKABkU4fEAi77sNOkLCKw40M9sDJOesmYInS_J2AuXX
|
|
|
@ -1 +0,0 @@
|
||||||
MGUCMFwSs3o95ukwBWXN1WbLgnpJ_uHWFiQROPm9zjrSqzlfiSMyLwJwIZzldWo_pBJtOwIxAJIfhXIiMVfl5NkFEJUUMxzu6FuxOJl5DCpG2wHLy9AhayLUzm4X4SpwZ6QBPapdTg
|
|
|
@ -1 +0,0 @@
|
||||||
HUndgHvxHNMiAe1SXoeyOOraUJCdxHqWkAYTu0Cq1KpAHcWZEVelNTvyXGbTLWj8btsmqNLAm08UlyK43q_2oO9DQfez3Fo8DhsKvm7TqgSXCkhUoxsYNanxWXhqw-Jw
|
|
|
@ -1,36 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1235572 -->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Testpage for bug 1235572</title>
|
|
||||||
<script>
|
|
||||||
function loaded(resource) {
|
|
||||||
document.getElementById("result").innerHTML += resource + " loaded\n";
|
|
||||||
}
|
|
||||||
function blocked(resource) {
|
|
||||||
document.getElementById("result").innerHTML += resource + " blocked\n";
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Testing script loading without SRI for Bug 1235572<br/>
|
|
||||||
<div id="result"></div>
|
|
||||||
|
|
||||||
<!-- use css1 and css2 to make urls different to avoid the resource being cached-->
|
|
||||||
<link rel="stylesheet" href="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=css1"
|
|
||||||
onload="loaded('Stylesheet without SRI')"
|
|
||||||
onerror="blocked('Stylesheet without SRI')">
|
|
||||||
<link rel="stylesheet" href="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=css2"
|
|
||||||
integrity="sha384-/6Tvxh7SX39y62qePcvYoi5Vrf0lK8Ix3wJFLCYKI5KNJ5wIlCR8UsFC1OXwmwgd"
|
|
||||||
onload="loaded('Stylesheet with SRI')"
|
|
||||||
onerror="blocked('Stylesheet with SRI')">
|
|
||||||
<script src="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=script"
|
|
||||||
onload="loaded('Script without SRI')"
|
|
||||||
onerror="blocked('Script without SRI')"></script>
|
|
||||||
<script src="https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?resource=script"
|
|
||||||
integrity="sha384-zDCkvKOHXk8mM6Nk07oOGXGME17PA4+ydFw+hq0r9kgF6ZDYFWK3fLGPEy7FoOAo"
|
|
||||||
onload="loaded('Script with SRI')"
|
|
||||||
onerror="blocked('Script with SRI')"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1 +0,0 @@
|
||||||
yoIyAYiiEzdP1zpkRy3KaqdsjUy62Notku89cytwVwcH0x6fKsMCdM-df1wbk9N28CSTaIOW5kcSenFy5K3nU-zPIoqZDjQo6aSjF8hF6lrw1a1xbhfl9K3g4YJsuWsO
|
|
|
@ -1,260 +0,0 @@
|
||||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
|
||||||
/* 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/. */
|
|
||||||
// sjs for remote about:newtab (bug 1226928)
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
|
||||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
|
||||||
Cu.importGlobalProperties(["URLSearchParams"]);
|
|
||||||
|
|
||||||
const path = "browser/dom/security/test/contentverifier/";
|
|
||||||
|
|
||||||
const goodFileName = "file_about_newtab.html";
|
|
||||||
const goodFileBase = path + goodFileName;
|
|
||||||
const goodFile = FileUtils.getDir("TmpD", [], true);
|
|
||||||
goodFile.append(goodFileName);
|
|
||||||
const goodSignature = path + "file_about_newtab_good_signature";
|
|
||||||
const goodX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\"";
|
|
||||||
|
|
||||||
const scriptFileName = "script.js";
|
|
||||||
const cssFileName = "style.css";
|
|
||||||
const badFile = path + "file_about_newtab_bad.html";
|
|
||||||
const brokenSignature = path + "file_about_newtab_broken_signature";
|
|
||||||
const badSignature = path + "file_about_newtab_bad_signature";
|
|
||||||
const badX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=bad\"";
|
|
||||||
const httpX5UString = "\"http://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\"";
|
|
||||||
|
|
||||||
const sriFile = path + "file_about_newtab_sri.html";
|
|
||||||
const sriSignature = path + "file_about_newtab_sri_signature";
|
|
||||||
|
|
||||||
const badCspFile = path + "file_about_newtab_bad_csp.html";
|
|
||||||
const badCspSignature = path + "file_about_newtab_bad_csp_signature";
|
|
||||||
|
|
||||||
// This cert chain is copied from
|
|
||||||
// security/manager/ssl/tests/unit/test_content_signing/
|
|
||||||
// using the certificates
|
|
||||||
// * content_signing_remote_newtab_ee.pem
|
|
||||||
// * content_signing_int.pem
|
|
||||||
// * content_signing_root.pem
|
|
||||||
const goodCertChainPath = path + "goodChain.pem";
|
|
||||||
|
|
||||||
const tempFileNames = [goodFileName, scriptFileName, cssFileName];
|
|
||||||
|
|
||||||
// we copy the file to serve as newtab to a temp directory because
|
|
||||||
// we modify it during tests.
|
|
||||||
setupTestFiles();
|
|
||||||
|
|
||||||
function setupTestFiles() {
|
|
||||||
for (let fileName of tempFileNames) {
|
|
||||||
let tempFile = FileUtils.getDir("TmpD", [], true);
|
|
||||||
tempFile.append(fileName);
|
|
||||||
if (!tempFile.exists()) {
|
|
||||||
let fileIn = getFileName(path + fileName, "CurWorkD");
|
|
||||||
fileIn.copyTo(FileUtils.getDir("TmpD", [], true), "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFileName(filePath, dir) {
|
|
||||||
// Since it's relative to the cwd of the test runner, we start there and
|
|
||||||
// append to get to the actual path of the file.
|
|
||||||
let testFile =
|
|
||||||
Cc["@mozilla.org/file/directory_service;1"].
|
|
||||||
getService(Components.interfaces.nsIProperties).
|
|
||||||
get(dir, Components.interfaces.nsIFile);
|
|
||||||
let dirs = filePath.split("/");
|
|
||||||
for (let i = 0; i < dirs.length; i++) {
|
|
||||||
testFile.append(dirs[i]);
|
|
||||||
}
|
|
||||||
return testFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadFile(file) {
|
|
||||||
// Load a file to return it.
|
|
||||||
let testFileStream =
|
|
||||||
Cc["@mozilla.org/network/file-input-stream;1"]
|
|
||||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
|
||||||
testFileStream.init(file, -1, 0, 0);
|
|
||||||
return NetUtil.readInputStreamToString(testFileStream,
|
|
||||||
testFileStream.available());
|
|
||||||
}
|
|
||||||
|
|
||||||
function appendToFile(aFile, content) {
|
|
||||||
try {
|
|
||||||
let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_APPEND |
|
|
||||||
FileUtils.MODE_WRONLY);
|
|
||||||
file.write(content, content.length);
|
|
||||||
file.close();
|
|
||||||
} catch (e) {
|
|
||||||
dump(">>> Error in appendToFile "+e);
|
|
||||||
return "Error";
|
|
||||||
}
|
|
||||||
return "Done";
|
|
||||||
}
|
|
||||||
|
|
||||||
function truncateFile(aFile, length) {
|
|
||||||
let fileIn = loadFile(aFile);
|
|
||||||
fileIn = fileIn.slice(0, -length);
|
|
||||||
|
|
||||||
try {
|
|
||||||
let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_WRONLY |
|
|
||||||
FileUtils.MODE_TRUNCATE);
|
|
||||||
file.write(fileIn, fileIn.length);
|
|
||||||
file.close();
|
|
||||||
} catch (e) {
|
|
||||||
dump(">>> Error in truncateFile "+e);
|
|
||||||
return "Error";
|
|
||||||
}
|
|
||||||
return "Done";
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanupTestFiles() {
|
|
||||||
for (let fileName of tempFileNames) {
|
|
||||||
let tempFile = FileUtils.getDir("TmpD", [], true);
|
|
||||||
tempFile.append(fileName);
|
|
||||||
tempFile.remove(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* handle requests of the following form:
|
|
||||||
* sig=good&key=good&file=good&header=good&cached=no to serve pages with
|
|
||||||
* content signatures
|
|
||||||
*
|
|
||||||
* it further handles invalidateFile=yep and validateFile=yep to change the
|
|
||||||
* served file
|
|
||||||
*/
|
|
||||||
function handleRequest(request, response) {
|
|
||||||
let params = new URLSearchParams(request.queryString);
|
|
||||||
let x5uType = params.get("x5u");
|
|
||||||
let signatureType = params.get("sig");
|
|
||||||
let fileType = params.get("file");
|
|
||||||
let headerType = params.get("header");
|
|
||||||
let cached = params.get("cached");
|
|
||||||
let invalidateFile = params.get("invalidateFile");
|
|
||||||
let validateFile = params.get("validateFile");
|
|
||||||
let resource = params.get("resource");
|
|
||||||
let x5uParam = params.get("x5u");
|
|
||||||
|
|
||||||
if (params.get("cleanup")) {
|
|
||||||
cleanupTestFiles();
|
|
||||||
response.setHeader("Content-Type", "text/html", false);
|
|
||||||
response.write("Done");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource) {
|
|
||||||
if (resource == "script") {
|
|
||||||
response.setHeader("Content-Type", "application/javascript", false);
|
|
||||||
response.write(loadFile(getFileName(scriptFileName, "TmpD")));
|
|
||||||
} else { // resource == "css1" || resource == "css2"
|
|
||||||
response.setHeader("Content-Type", "text/css", false);
|
|
||||||
response.write(loadFile(getFileName(cssFileName, "TmpD")));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if invalidateFile is set, this doesn't actually return a newtab page
|
|
||||||
// but changes the served file to invalidate the signature
|
|
||||||
// NOTE: make sure to make the file valid again afterwards!
|
|
||||||
if (invalidateFile) {
|
|
||||||
let r = "Done";
|
|
||||||
for (let fileName of tempFileNames) {
|
|
||||||
if (appendToFile(getFileName(fileName, "TmpD"), "!") != "Done") {
|
|
||||||
r = "Error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response.setHeader("Content-Type", "text/html", false);
|
|
||||||
response.write(r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if validateFile is set, this doesn't actually return a newtab page
|
|
||||||
// but changes the served file to make the signature valid again
|
|
||||||
if (validateFile) {
|
|
||||||
let r = "Done";
|
|
||||||
for (let fileName of tempFileNames) {
|
|
||||||
if (truncateFile(getFileName(fileName, "TmpD"), 1) != "Done") {
|
|
||||||
r = "Error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response.setHeader("Content-Type", "text/html", false);
|
|
||||||
response.write(r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have to return the certificate chain on request for the x5u parameter
|
|
||||||
if (x5uParam && x5uParam == "default") {
|
|
||||||
response.setHeader("Cache-Control", "max-age=216000", false);
|
|
||||||
response.setHeader("Content-Type", "text/plain", false);
|
|
||||||
response.write(loadFile(getFileName(goodCertChainPath, "CurWorkD")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// avoid confusing cache behaviours
|
|
||||||
if (!cached) {
|
|
||||||
response.setHeader("Cache-Control", "no-cache", false);
|
|
||||||
} else {
|
|
||||||
response.setHeader("Cache-Control", "max-age=3600", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// send HTML to test allowed/blocked behaviours
|
|
||||||
response.setHeader("Content-Type", "text/html", false);
|
|
||||||
|
|
||||||
// set signature header and key for Content-Signature header
|
|
||||||
/* By default a good content-signature header is returned. Any broken return
|
|
||||||
* value has to be indicated in the url.
|
|
||||||
*/
|
|
||||||
let csHeader = "";
|
|
||||||
let x5uString = goodX5UString;
|
|
||||||
let signature = goodSignature;
|
|
||||||
let file = goodFile;
|
|
||||||
if (x5uType == "bad") {
|
|
||||||
x5uString = badX5UString;
|
|
||||||
} else if (x5uType == "http") {
|
|
||||||
x5uString = httpX5UString;
|
|
||||||
}
|
|
||||||
if (signatureType == "bad") {
|
|
||||||
signature = badSignature;
|
|
||||||
} else if (signatureType == "broken") {
|
|
||||||
signature = brokenSignature;
|
|
||||||
} else if (signatureType == "sri") {
|
|
||||||
signature = sriSignature;
|
|
||||||
} else if (signatureType == "bad-csp") {
|
|
||||||
signature = badCspSignature;
|
|
||||||
}
|
|
||||||
if (fileType == "bad") {
|
|
||||||
file = getFileName(badFile, "CurWorkD");
|
|
||||||
} else if (fileType == "sri") {
|
|
||||||
file = getFileName(sriFile, "CurWorkD");
|
|
||||||
} else if (fileType == "bad-csp") {
|
|
||||||
file = getFileName(badCspFile, "CurWorkD");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (headerType == "good") {
|
|
||||||
// a valid content-signature header
|
|
||||||
csHeader = "x5u=" + x5uString + ";p384ecdsa=" +
|
|
||||||
loadFile(getFileName(signature, "CurWorkD"));
|
|
||||||
} else if (headerType == "error") {
|
|
||||||
// this content-signature header is missing ; before p384ecdsa
|
|
||||||
csHeader = "x5u=" + x5uString + "p384ecdsa=" +
|
|
||||||
loadFile(getFileName(signature, "CurWorkD"));
|
|
||||||
} else if (headerType == "errorInX5U") {
|
|
||||||
// this content-signature header is missing the keyid directive
|
|
||||||
csHeader = "x6u=" + x5uString + ";p384ecdsa=" +
|
|
||||||
loadFile(getFileName(signature, "CurWorkD"));
|
|
||||||
} else if (headerType == "errorInSignature") {
|
|
||||||
// this content-signature header is missing the p384ecdsa directive
|
|
||||||
csHeader = "x5u=" + x5uString + ";p385ecdsa=" +
|
|
||||||
loadFile(getFileName(signature, "CurWorkD"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (csHeader) {
|
|
||||||
response.setHeader("Content-Signature", csHeader, false);
|
|
||||||
}
|
|
||||||
let result = loadFile(file);
|
|
||||||
|
|
||||||
response.write(result);
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICUzCCAT2gAwIBAgIUJ1BtYqWRwUsVaZCGPp9eTHIC04QwCwYJKoZIhvcNAQEL
|
|
||||||
MBExDzANBgNVBAMMBmludC1DQTAiGA8yMDE1MTEyODAwMDAwMFoYDzIwMTgwMjA1
|
|
||||||
MDAwMDAwWjAUMRIwEAYDVQQDDAllZS1pbnQtQ0EwdjAQBgcqhkjOPQIBBgUrgQQA
|
|
||||||
IgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05q
|
|
||||||
nAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyD
|
|
||||||
dKpuqc6jTjBMMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDUGA1UdEQQuMCyCKnJlbW90
|
|
||||||
ZW5ld3RhYi5jb250ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzALBgkqhkiG9w0B
|
|
||||||
AQsDggEBALiLck6k50ok9ahVq45P3feY1PeUXcIYZkJd8aPDYM+0kfg5+JyJBykA
|
|
||||||
mtHWPE1QQjs7VRMfaLfu04E4UJMI2V1AON1qtgR9BQLctW85KFACg2omfiCKwJh0
|
|
||||||
5Q8cxBFx9BpNMayqLJwHttB6oluxZFTB8CL/hfpbYpHz1bMEDCVSRP588YBrc8mV
|
|
||||||
OLqzQK+k3ewwGvfD6SvXmTny37MxqwxdTPFJNnpqzKAsQIvz8Skic9BkA1NFk0Oq
|
|
||||||
lsKKoiibbOCmwS9XY/laAkBaC3winuhciYAC0ImAopZ4PBCU0AOHGrNbhZXWYQxt
|
|
||||||
uHBj34FqvIRCqgM06JCEwN0ULgix4kI=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIC0TCCAbugAwIBAgIUPcKbBQpKwTzrrlqzM+d3z5DWiNUwCwYJKoZIhvcNAQEL
|
|
||||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
|
||||||
MDBaMBExDzANBgNVBAMMBmludC1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
|
||||||
AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x
|
|
||||||
nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM
|
|
||||||
wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF
|
|
||||||
4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20
|
|
||||||
yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx
|
|
||||||
j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMlMCMwDAYDVR0TBAUwAwEB/zAT
|
|
||||||
BgNVHSUEDDAKBggrBgEFBQcDAzALBgkqhkiG9w0BAQsDggEBADDPjITgz8joxLRW
|
|
||||||
wpLxELKSgO/KQ6iAXztjMHq9ovT7Fy0fqBnQ1mMVFr+sBXLgtUCM45aip6PjhUXc
|
|
||||||
zs5Dq5STg+kz7qtmAjEQvOPcyictbgdu/K7+uMhXQhlzhOgyW88Uk5vrAezNTc/e
|
|
||||||
TvSmWp1FcgVAfaeMN/90nzD1KIHoUt7zqZIz9ub8jXPVzQNZq4vh33smZhmbdTdV
|
|
||||||
DaHUyef5cR1VTEGB+L1qzUIQqpHmD4UkMNP1nYedWfauiQhRt6Ql3rJSCRuEvsOA
|
|
||||||
iBTJlwai/EFwfyfHkOV2GNgv+A5wHHEjBtF5c4PCxQEL5Vw+mfZHLsDVqF3279ZY
|
|
||||||
lQ6jQ9g=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIICzTCCAbegAwIBAgIUKRLJoCmk0A6PHrNc8CxFn//4BYcwCwYJKoZIhvcNAQEL
|
|
||||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw
|
|
||||||
MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
|
||||||
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
|
|
||||||
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
|
|
||||||
7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf
|
|
||||||
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
|
|
||||||
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
|
|
||||||
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/MBMGA1Ud
|
|
||||||
JQQMMAoGCCsGAQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAABgMK6EyVIXTjD5qaxPO
|
|
||||||
DWz6yREACmAQBcowKWvfhwgi27DPSXyFGDbzTPEo+7RrIcXJkVAhLouGT51fCwTZ
|
|
||||||
zb6Sgf6ztX7VSppY9AT4utvlZKP1xQ5WhIYsMtdHCHLHIkRjeWyoBEfUx50UXNLK
|
|
||||||
Snl+A02GKYWiX+TLLg2DPN2s7v/mm8NLMQNgUlL7KakB2FHFyPa8otPpL4llg7UJ
|
|
||||||
iBTVQ0c3JoiVbwZaY1Z8QinfMXUrTK9egUC4BAcId1dE8glzA5RRlw1fTLWpGApt
|
|
||||||
hUmbDnl9N2a9NhGX323ypNzIATexafipzWe7bc4u/+bFdrUqnKUoEka73pZBdHdA
|
|
||||||
FQ==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,208 +0,0 @@
|
||||||
/*
|
|
||||||
* Test Content-Signature for remote about:newtab
|
|
||||||
* - Bug 1226928 - allow about:newtab to load remote content
|
|
||||||
*
|
|
||||||
* This tests content-signature verification on remote about:newtab in the
|
|
||||||
* following cases (see TESTS, all failed loads display about:blank fallback):
|
|
||||||
* - good case (signature should verify and correct page is displayed)
|
|
||||||
* - reload of newtab when the siganture was invalidated after the last correct
|
|
||||||
* load
|
|
||||||
* - malformed content-signature header
|
|
||||||
* - malformed keyid directive
|
|
||||||
* - malformed p384ecdsa directive
|
|
||||||
* - wrong signature (this is not a siganture for the delivered document)
|
|
||||||
* - invalid signature (this is not even a signature)
|
|
||||||
* - loading a file that doesn't fit the key or signature
|
|
||||||
* - cache poisoning (load a malicious remote page not in newtab, subsequent
|
|
||||||
* newtab load has to load the fallback)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const ABOUT_NEWTAB_URI = "about:newtab";
|
|
||||||
|
|
||||||
const BASE = "https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?";
|
|
||||||
const URI_GOOD = BASE + "sig=good&x5u=good&file=good&header=good";
|
|
||||||
|
|
||||||
const INVALIDATE_FILE = BASE + "invalidateFile=yep";
|
|
||||||
const VALIDATE_FILE = BASE + "validateFile=yep";
|
|
||||||
|
|
||||||
const URI_HEADER_BASE = BASE + "sig=good&x5u=good&file=good&header=";
|
|
||||||
const URI_ERROR_HEADER = URI_HEADER_BASE + "error";
|
|
||||||
const URI_KEYERROR_HEADER = URI_HEADER_BASE + "errorInX5U";
|
|
||||||
const URI_SIGERROR_HEADER = URI_HEADER_BASE + "errorInSignature";
|
|
||||||
const URI_NO_HEADER = URI_HEADER_BASE + "noHeader";
|
|
||||||
|
|
||||||
const URI_BAD_SIG = BASE + "sig=bad&x5u=good&file=good&header=good";
|
|
||||||
const URI_BROKEN_SIG = BASE + "sig=broken&x5u=good&file=good&header=good";
|
|
||||||
const URI_BAD_X5U = BASE + "sig=good&x5u=bad&file=good&header=good";
|
|
||||||
const URI_HTTP_X5U = BASE + "sig=good&x5u=http&file=good&header=good";
|
|
||||||
const URI_BAD_FILE = BASE + "sig=good&x5u=good&file=bad&header=good";
|
|
||||||
const URI_BAD_ALL = BASE + "sig=bad&x5u=bad&file=bad&header=bad";
|
|
||||||
const URI_BAD_CSP = BASE + "sig=bad-csp&x5u=good&file=bad-csp&header=good";
|
|
||||||
|
|
||||||
const URI_BAD_FILE_CACHED = BASE + "sig=good&x5u=good&file=bad&header=good&cached=true";
|
|
||||||
|
|
||||||
const GOOD_ABOUT_STRING = "Just a fully good testpage for Bug 1226928";
|
|
||||||
const BAD_ABOUT_STRING = "Just a bad testpage for Bug 1226928";
|
|
||||||
const ABOUT_BLANK = "<head></head><body></body>";
|
|
||||||
|
|
||||||
const URI_CLEANUP = BASE + "cleanup=true";
|
|
||||||
const CLEANUP_DONE = "Done";
|
|
||||||
|
|
||||||
const URI_SRI = BASE + "sig=sri&x5u=good&file=sri&header=good";
|
|
||||||
const STYLESHEET_WITHOUT_SRI_BLOCKED = "Stylesheet without SRI blocked";
|
|
||||||
const STYLESHEET_WITH_SRI_BLOCKED = "Stylesheet with SRI blocked";
|
|
||||||
const STYLESHEET_WITH_SRI_LOADED = "Stylesheet with SRI loaded";
|
|
||||||
const SCRIPT_WITHOUT_SRI_BLOCKED = "Script without SRI blocked";
|
|
||||||
const SCRIPT_WITH_SRI_BLOCKED = "Script with SRI blocked";
|
|
||||||
const SCRIPT_WITH_SRI_LOADED = "Script with SRI loaded";
|
|
||||||
|
|
||||||
const CSP_TEST_SUCCESS_STRING = "CSP violation test succeeded.";
|
|
||||||
|
|
||||||
// Needs to sync with pref "security.signed_content.CSP.default".
|
|
||||||
const SIGNED_CONTENT_CSP = `{"csp-policies":[{"report-only":false,"script-src":["https://example.com","'unsafe-inline'"],"style-src":["https://example.com"]}]}`;
|
|
||||||
|
|
||||||
var browser = null;
|
|
||||||
var aboutNewTabService = Cc["@mozilla.org/browser/aboutnewtab-service;1"]
|
|
||||||
.getService(Ci.nsIAboutNewTabService);
|
|
||||||
|
|
||||||
function pushPrefs(...aPrefs) {
|
|
||||||
return SpecialPowers.pushPrefEnv({"set": aPrefs});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* run tests with input from TESTS
|
|
||||||
*/
|
|
||||||
async function doTest(aExpectedStrings, reload, aUrl, aNewTabPref) {
|
|
||||||
// set about:newtab location for this test if it's a newtab test
|
|
||||||
if (aNewTabPref) {
|
|
||||||
aboutNewTabService.newTabURL = aNewTabPref;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set prefs
|
|
||||||
await pushPrefs(
|
|
||||||
["browser.newtabpage.remote.content-signing-test", true],
|
|
||||||
["browser.newtabpage.remote", true],
|
|
||||||
["security.content.signature.root_hash",
|
|
||||||
"CC:BE:04:87:74:B2:98:24:4A:C6:7A:71:BC:6F:DB:D6:C0:48:17:29:57:51:96:47:38:CC:24:C8:E4:F9:DD:CB"]);
|
|
||||||
|
|
||||||
if (aNewTabPref === URI_BAD_CSP) {
|
|
||||||
// Use stricter CSP to test CSP violation.
|
|
||||||
await pushPrefs(["security.signed_content.CSP.default", "script-src 'self'; style-src 'self'"]);
|
|
||||||
} else {
|
|
||||||
// Use weaker CSP to test normal content.
|
|
||||||
await pushPrefs(["security.signed_content.CSP.default", "script-src 'self' 'unsafe-inline'; style-src 'self'"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the test
|
|
||||||
await BrowserTestUtils.withNewTab({
|
|
||||||
gBrowser,
|
|
||||||
url: aUrl,
|
|
||||||
},
|
|
||||||
async function(browser) {
|
|
||||||
// check if everything's set correct for testing
|
|
||||||
ok(Services.prefs.getBoolPref(
|
|
||||||
"browser.newtabpage.remote.content-signing-test"),
|
|
||||||
"sanity check: remote newtab signing test should be used");
|
|
||||||
ok(Services.prefs.getBoolPref("browser.newtabpage.remote"),
|
|
||||||
"sanity check: remote newtab should be used");
|
|
||||||
// we only check this if we really do a newtab test
|
|
||||||
if (aNewTabPref) {
|
|
||||||
ok(aboutNewTabService.overridden,
|
|
||||||
"sanity check: default URL for about:newtab should be overriden");
|
|
||||||
is(aboutNewTabService.newTabURL, aNewTabPref,
|
|
||||||
"sanity check: default URL for about:newtab should return the new URL");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Every valid remote newtab page must have built-in CSP.
|
|
||||||
let shouldHaveCSP = ((aUrl === ABOUT_NEWTAB_URI) &&
|
|
||||||
(aNewTabPref === URI_GOOD || aNewTabPref === URI_SRI));
|
|
||||||
|
|
||||||
if (shouldHaveCSP) {
|
|
||||||
is(browser.contentDocument.nodePrincipal.cspJSON, SIGNED_CONTENT_CSP,
|
|
||||||
"Valid remote newtab page must have built-in CSP.");
|
|
||||||
}
|
|
||||||
|
|
||||||
await ContentTask.spawn(
|
|
||||||
browser, aExpectedStrings, async function(aExpectedStrings) {
|
|
||||||
for (let expectedString of aExpectedStrings) {
|
|
||||||
ok(content.document.documentElement.innerHTML.includes(expectedString),
|
|
||||||
"Expect the following value in the result\n" + expectedString +
|
|
||||||
"\nand got " + content.document.documentElement.innerHTML);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// for good test cases we check if a reload fails if the remote page
|
|
||||||
// changed from valid to invalid in the meantime
|
|
||||||
if (reload) {
|
|
||||||
await BrowserTestUtils.withNewTab({
|
|
||||||
gBrowser,
|
|
||||||
url: INVALIDATE_FILE,
|
|
||||||
},
|
|
||||||
async function(browser2) {
|
|
||||||
await ContentTask.spawn(browser2, null, async function() {
|
|
||||||
ok(content.document.documentElement.innerHTML.includes("Done"),
|
|
||||||
"Expect the following value in the result\n" + "Done" +
|
|
||||||
"\nand got " + content.document.documentElement.innerHTML);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
browser.reload();
|
|
||||||
await BrowserTestUtils.browserLoaded(browser);
|
|
||||||
|
|
||||||
let expectedStrings = [ABOUT_BLANK];
|
|
||||||
if (aNewTabPref == URI_SRI) {
|
|
||||||
expectedStrings = [
|
|
||||||
STYLESHEET_WITHOUT_SRI_BLOCKED,
|
|
||||||
STYLESHEET_WITH_SRI_BLOCKED,
|
|
||||||
SCRIPT_WITHOUT_SRI_BLOCKED,
|
|
||||||
SCRIPT_WITH_SRI_BLOCKED
|
|
||||||
];
|
|
||||||
}
|
|
||||||
await ContentTask.spawn(browser, expectedStrings,
|
|
||||||
async function(expectedStrings) {
|
|
||||||
for (let expectedString of expectedStrings) {
|
|
||||||
ok(content.document.documentElement.innerHTML.includes(expectedString),
|
|
||||||
"Expect the following value in the result\n" + expectedString +
|
|
||||||
"\nand got " + content.document.documentElement.innerHTML);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab({
|
|
||||||
gBrowser,
|
|
||||||
url: VALIDATE_FILE,
|
|
||||||
},
|
|
||||||
async function(browser2) {
|
|
||||||
await ContentTask.spawn(browser2, null, async function() {
|
|
||||||
ok(content.document.documentElement.innerHTML.includes("Done"),
|
|
||||||
"Expect the following value in the result\n" + "Done" +
|
|
||||||
"\nand got " + content.document.documentElement.innerHTML);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runTests() {
|
|
||||||
// run tests from TESTS
|
|
||||||
for (let i = 0; i < TESTS.length; i++) {
|
|
||||||
let testCase = TESTS[i];
|
|
||||||
let url = "", aNewTabPref = "";
|
|
||||||
let reload = false;
|
|
||||||
var aExpectedStrings = testCase.testStrings;
|
|
||||||
if (testCase.aboutURI) {
|
|
||||||
url = ABOUT_NEWTAB_URI;
|
|
||||||
aNewTabPref = testCase.aboutURI;
|
|
||||||
if (aNewTabPref == URI_GOOD || aNewTabPref == URI_SRI) {
|
|
||||||
reload = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
url = testCase.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
await doTest(aExpectedStrings, reload, url, aNewTabPref);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
var load=true;
|
|
Двоичные данные
dom/security/test/contentverifier/signature.der
Двоичные данные
dom/security/test/contentverifier/signature.der
Двоичный файл не отображается.
|
@ -1,9 +0,0 @@
|
||||||
-----BEGIN EC PARAMETERS-----
|
|
||||||
BgUrgQQAIg==
|
|
||||||
-----END EC PARAMETERS-----
|
|
||||||
-----BEGIN EC PRIVATE KEY-----
|
|
||||||
MIGkAgEBBDAzX2TrGOr0WE92AbAl+nqnpqh25pKCLYNMTV2hJHztrkVPWOp8w0mh
|
|
||||||
scIodK8RMpagBwYFK4EEACKhZANiAATiTcWYbt0Wg63dO7OXvpptNG0ryxv+v+Js
|
|
||||||
JJ5Upr3pFus5fZyKxzP9NPzB+oFhL/xw3jMx7X5/vBGaQ2sJSiNlHVkqZgzYF6JQ
|
|
||||||
4yUyiqTY7v67CyfUPA1BJg/nxOS9m3o=
|
|
||||||
-----END EC PRIVATE KEY-----
|
|
|
@ -1,3 +0,0 @@
|
||||||
#red-text {
|
|
||||||
color: red;
|
|
||||||
}
|
|
Загрузка…
Ссылка в новой задаче