merge mozilla-inbound to mozilla-central + UPGRADE_NSS_RELEASE a=merge

--HG--
rename : toolkit/components/extensions/test/xpcshell/xpcshell.ini => toolkit/components/extensions/test/xpcshell/xpcshell-common.ini
extra : amend_source : 458fd54fe8070ca3034ac441267ff7025adb5251
This commit is contained in:
Carsten "Tomcat" Book 2017-05-30 11:37:46 +02:00
commit b318c7dca7
123 changed files with 2197 additions and 970 deletions

View file

@ -103,7 +103,7 @@ add_task(async function test() {
let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey", let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey",
[{ [{
initDataTypes: [aKeyInfo.initDataType], initDataTypes: [aKeyInfo.initDataType],
videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}], videoCapabilities: [{contentType: "video/webm"}],
sessionTypes: ["persistent-license"], sessionTypes: ["persistent-license"],
persistentState: "required", persistentState: "required",
}]); }]);
@ -156,7 +156,7 @@ add_task(async function test() {
let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey", let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey",
[{ [{
initDataTypes: [aKeyInfo.initDataType], initDataTypes: [aKeyInfo.initDataType],
videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}], videoCapabilities: [{contentType: "video/webm"}],
sessionTypes: ["persistent-license"], sessionTypes: ["persistent-license"],
persistentState: "required", persistentState: "required",
}]); }]);

View file

@ -98,7 +98,7 @@ async function setupEMEKey(browser) {
let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey", let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey",
[{ [{
initDataTypes: [aKeyInfo.initDataType], initDataTypes: [aKeyInfo.initDataType],
videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}], videoCapabilities: [{contentType: "video/webm"}],
sessionTypes: ["persistent-license"], sessionTypes: ["persistent-license"],
persistentState: "required", persistentState: "required",
}]); }]);
@ -153,7 +153,7 @@ async function checkEMEKey(browser, emeSessionId) {
let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey", let access = await content.navigator.requestMediaKeySystemAccess("org.w3.clearkey",
[{ [{
initDataTypes: [aKeyInfo.initDataType], initDataTypes: [aKeyInfo.initDataType],
videoCapabilities: [{contentType: 'video/webm; codecs="vp9"'}], videoCapabilities: [{contentType: "video/webm"}],
sessionTypes: ["persistent-license"], sessionTypes: ["persistent-license"],
persistentState: "required", persistentState: "required",
}]); }]);

View file

@ -27,4 +27,12 @@ BROWSER_CHROME_MANIFESTS += [
] ]
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini'] MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
if CONFIG['OS_ARCH'] != 'Darwin':
XPCSHELL_TESTS_MANIFESTS += [
'test/xpcshell/xpcshell-remote.ini',
]
XPCSHELL_TESTS_MANIFESTS += [
'test/xpcshell/xpcshell.ini',
]

View file

@ -37,6 +37,7 @@ support-files =
[browser_ext_browserAction_pageAction_icon_permissions.js] [browser_ext_browserAction_pageAction_icon_permissions.js]
[browser_ext_browserAction_popup.js] [browser_ext_browserAction_popup.js]
[browser_ext_browserAction_popup_preload.js] [browser_ext_browserAction_popup_preload.js]
skip-if = (os == 'win' && !debug) # bug 1352668
[browser_ext_browserAction_popup_resize.js] [browser_ext_browserAction_popup_resize.js]
[browser_ext_browserAction_simple.js] [browser_ext_browserAction_simple.js]
[browser_ext_browsingData_formData.js] [browser_ext_browsingData_formData.js]

View file

@ -41,6 +41,7 @@ const {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {})
if (gTestPath.includes("test-oop-extensions")) { if (gTestPath.includes("test-oop-extensions")) {
SpecialPowers.pushPrefEnv({set: [ SpecialPowers.pushPrefEnv({set: [
["extensions.webextensions.remote", true], ["extensions.webextensions.remote", true],
["layers.popups.compositing.enabled", true],
]}); ]});
// We don't want to reset this at the end of the test, so that we don't have // We don't want to reset this at the end of the test, so that we don't have
// to spawn a new extension child process for each test unit. // to spawn a new extension child process for each test unit.

View file

@ -4,6 +4,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
/* exported createHttpServer, promiseConsoleOutput */ /* exported createHttpServer, promiseConsoleOutput */
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants", XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
@ -24,11 +25,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm"); "resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Schemas", XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
"resource://gre/modules/Schemas.jsm"); "resource://gre/modules/Schemas.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TestUtils", XPCOMUtils.defineLazyModuleGetter(this, "TestUtils",
"resource://testing-common/TestUtils.jsm"); "resource://testing-common/TestUtils.jsm");
Services.prefs.setBoolPref("extensions.webextensions.remote", false);
ExtensionTestUtils.init(this); ExtensionTestUtils.init(this);

View file

@ -0,0 +1,4 @@
"use strict";
Services.prefs.setBoolPref("extensions.webextensions.remote", true);
Services.prefs.setIntPref("dom.ipc.keepProcessesAlive.extension", 1);

View file

@ -0,0 +1,8 @@
[test_ext_bookmarks.js]
[test_ext_browsingData.js]
[test_ext_browsingData_cookies_cache.js]
[test_ext_browsingData_downloads.js]
[test_ext_browsingData_passwords.js]
[test_ext_browsingData_settings.js]
[test_ext_history.js]
[test_ext_geckoProfiler_control.js]

View file

@ -0,0 +1,7 @@
[DEFAULT]
head = head.js head_remote.js
firefox-appdir = browser
tags = webextensions remote-webextensions
dupe-manifest =
[include:xpcshell-common.ini]

View file

@ -1,16 +1,23 @@
[DEFAULT] [DEFAULT]
head = head.js head = head.js
firefox-appdir = browser firefox-appdir = browser
tags = webextensions tags = webextensions in-process-webextensions
dupe-manifest =
# This file contains tests which are not affected by multi-process
# configuration, or do not support out-of-process content or extensions
# for one reason or another.
#
# Tests which are affected by remote content or remote extensions should
# go in one of:
#
# - xpcshell-common.ini
# For tests which should run in all configurations.
# - xpcshell-remote.ini
# For tests which should only run with both remote extensions and remote content.
[test_ext_bookmarks.js]
[test_ext_browsingData.js]
[test_ext_browsingData_cookies_cache.js]
[test_ext_browsingData_downloads.js]
[test_ext_browsingData_passwords.js]
[test_ext_browsingData_settings.js]
[test_ext_history.js]
[test_ext_manifest_commands.js] [test_ext_manifest_commands.js]
[test_ext_manifest_omnibox.js] [test_ext_manifest_omnibox.js]
[test_ext_manifest_permissions.js] [test_ext_manifest_permissions.js]
[test_ext_geckoProfiler_control.js]
[include:xpcshell-common.ini]

View file

@ -127,16 +127,19 @@ BoxModel.prototype = {
} }
let lastRequest = Task.spawn((function* () { let lastRequest = Task.spawn((function* () {
if (!(this.isPanelVisible() && if (!this.inspector ||
this.inspector.selection.isConnected() && !this.isPanelVisible() ||
this.inspector.selection.isElementNode())) { !this.inspector.selection.isConnected() ||
!this.inspector.selection.isElementNode()) {
return null; return null;
} }
let node = this.inspector.selection.nodeFront; let node = this.inspector.selection.nodeFront;
let layout = yield this.inspector.pageStyle.getLayout(node, { let layout = yield this.inspector.pageStyle.getLayout(node, {
autoMargins: true, autoMargins: true,
}); });
let styleEntries = yield this.inspector.pageStyle.getApplied(node, { let styleEntries = yield this.inspector.pageStyle.getApplied(node, {
// We don't need styles applied to pseudo elements of the current node. // We don't need styles applied to pseudo elements of the current node.
skipPseudo: true skipPseudo: true
@ -146,12 +149,13 @@ BoxModel.prototype = {
// Update the layout properties with whether or not the element's position is // Update the layout properties with whether or not the element's position is
// editable with the geometry editor. // editable with the geometry editor.
let isPositionEditable = yield this.inspector.pageStyle.isPositionEditable(node); let isPositionEditable = yield this.inspector.pageStyle.isPositionEditable(node);
layout = Object.assign({}, layout, { layout = Object.assign({}, layout, {
isPositionEditable, isPositionEditable,
}); });
const actorCanGetOffSetParent const actorCanGetOffSetParent =
= yield this.inspector.target.actorHasMethod("domwalker", "getOffsetParent"); yield this.inspector.target.actorHasMethod("domwalker", "getOffsetParent");
if (actorCanGetOffSetParent) { if (actorCanGetOffSetParent) {
// Update the redux store with the latest offset parent DOM node // Update the redux store with the latest offset parent DOM node

View file

@ -63,6 +63,7 @@ module.exports = createClass({
{}, {},
dom.input( dom.input(
{ {
id: "grid-setting-extend-grid-lines",
type: "checkbox", type: "checkbox",
checked: highlighterSettings.showInfiniteLines, checked: highlighterSettings.showInfiniteLines,
onChange: this.onShowInfiniteLinesCheckboxClick, onChange: this.onShowInfiniteLinesCheckboxClick,
@ -79,6 +80,7 @@ module.exports = createClass({
{}, {},
dom.input( dom.input(
{ {
id: "grid-setting-show-grid-line-numbers",
type: "checkbox", type: "checkbox",
checked: highlighterSettings.showGridLineNumbers, checked: highlighterSettings.showGridLineNumbers,
onChange: this.onShowGridLineNumbersCheckboxClick, onChange: this.onShowGridLineNumbersCheckboxClick,

View file

@ -48,7 +48,9 @@ module.exports = createClass({
getStr("layout.overlayGrid") getStr("layout.overlayGrid")
), ),
dom.ul( dom.ul(
{}, {
id: "grid-list",
},
grids.map(grid => GridItem({ grids.map(grid => GridItem({
key: grid.id, key: grid.id,
getSwatchColorPickerTooltip, getSwatchColorPickerTooltip,

View file

@ -253,13 +253,27 @@ GridInspector.prototype = {
// Get all the GridFront from the server if no gridFronts were provided. // Get all the GridFront from the server if no gridFronts were provided.
if (!gridFronts) { if (!gridFronts) {
gridFronts = yield this.layoutInspector.getAllGrids(this.walker.rootNode); try {
gridFronts = yield this.layoutInspector.getAllGrids(this.walker.rootNode);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
} }
let grids = []; let grids = [];
for (let i = 0; i < gridFronts.length; i++) { for (let i = 0; i < gridFronts.length; i++) {
let grid = gridFronts[i]; let grid = gridFronts[i];
let nodeFront = yield this.walker.getNodeFromActor(grid.actorID, ["containerEl"]);
let nodeFront;
try {
nodeFront = yield this.walker.getNodeFromActor(grid.actorID, ["containerEl"]);
} catch (e) {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
let fallbackColor = GRID_COLORS[i % GRID_COLORS.length]; let fallbackColor = GRID_COLORS[i % GRID_COLORS.length];
let color = this.getInitialGridColor(nodeFront, fallbackColor); let color = this.getInitialGridColor(nodeFront, fallbackColor);
@ -300,7 +314,7 @@ GridInspector.prototype = {
* @param {Object} options * @param {Object} options
* The highlighter options used for the highlighter being shown/hidden. * The highlighter options used for the highlighter being shown/hidden.
*/ */
onHighlighterChange(event, nodeFront, options) { onHighlighterChange(event, nodeFront, options = {}) {
let highlighted = event === "grid-highlighter-shown"; let highlighted = event === "grid-highlighter-shown";
let { color } = options; let { color } = options;

View file

@ -15,3 +15,5 @@ DevToolsModules(
'grid-inspector.js', 'grid-inspector.js',
'types.js', 'types.js',
) )
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']

View file

@ -17,7 +17,7 @@ let reducers = {
[UPDATE_GRID_COLOR](grids, { nodeFront, color }) { [UPDATE_GRID_COLOR](grids, { nodeFront, color }) {
let newGrids = grids.map(g => { let newGrids = grids.map(g => {
if (g.nodeFront == nodeFront) { if (g.nodeFront == nodeFront) {
g.color = color; g = Object.assign({}, g, { color });
} }
return g; return g;

View file

@ -0,0 +1,9 @@
"use strict";
module.exports = {
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../../.eslintrc.mochitests.js",
"globals": {
"waitUntilState": true
}
};

View file

@ -0,0 +1,23 @@
[DEFAULT]
tags = devtools
subsuite = devtools
support-files =
head.js
!/devtools/client/commandline/test/helpers.js
!/devtools/client/framework/test/shared-head.js
!/devtools/client/inspector/test/head.js
!/devtools/client/inspector/test/shared-head.js
!/devtools/client/shared/test/test-actor.js
!/devtools/client/shared/test/test-actor-registry.js
!/devtools/client/framework/test/shared-redux-head.js
[browser_grids_display-setting-extend-grid-lines.js]
[browser_grids_display-setting-show-grid-line-numbers.js]
[browser_grids_grid-list-color-picker-on-ESC.js]
[browser_grids_grid-list-color-picker-on-RETURN.js]
[browser_grids_grid-list-element-rep.js]
[browser_grids_grid-list-no-grids.js]
[browser_grids_grid-list-on-mutation-element-added.js]
[browser_grids_grid-list-on-mutation-element-removed.js]
[browser_grids_grid-list-toggle-multiple-grids.js]
[browser_grids_grid-list-toggle-single-grid.js]

View file

@ -0,0 +1,51 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the 'Extend grid lines infinitely' grid highlighter setting will update
// the redux store and pref setting.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { store } = inspector;
yield selectNode("#grid", inspector);
let checkbox = doc.getElementById("grid-setting-extend-grid-lines");
ok(!Services.prefs.getBoolPref(SHOW_INFINITE_LINES_PREF),
"'Extend grid lines infinitely' is pref off by default.");
info("Toggling ON the 'Extend grid lines infinitely' setting.");
let onCheckboxChange = waitUntilState(store, state =>
state.highlighterSettings.showInfiniteLines);
checkbox.click();
yield onCheckboxChange;
info("Toggling OFF the 'Extend grid lines infinitely' setting.");
onCheckboxChange = waitUntilState(store, state =>
!state.highlighterSettings.showInfiniteLines);
checkbox.click();
yield onCheckboxChange;
ok(!Services.prefs.getBoolPref(SHOW_INFINITE_LINES_PREF),
"'Extend grid lines infinitely' is pref off.");
Services.prefs.clearUserPref(SHOW_INFINITE_LINES_PREF);
});

View file

@ -0,0 +1,55 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the 'Display numbers on lines' grid highlighter setting will update
// the redux store and pref setting.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { store } = inspector;
yield selectNode("#grid", inspector);
let checkbox = doc.getElementById("grid-setting-show-grid-line-numbers");
info("Checking the initial state of the CSS grid highlighter setting.");
ok(!Services.prefs.getBoolPref(SHOW_GRID_LINE_NUMBERS),
"'Display numbers on lines' is pref off by default.");
info("Toggling ON the 'Display numbers on lines' setting.");
let onCheckboxChange = waitUntilState(store, state =>
state.highlighterSettings.showGridLineNumbers);
checkbox.click();
yield onCheckboxChange;
ok(Services.prefs.getBoolPref(SHOW_GRID_LINE_NUMBERS),
"'Display numbers on lines' is pref on.");
info("Toggling OFF the 'Display numbers on lines' setting.");
onCheckboxChange = waitUntilState(store, state =>
!state.highlighterSettings.showGridLineNumbers);
checkbox.click();
yield onCheckboxChange;
ok(!Services.prefs.getBoolPref(SHOW_GRID_LINE_NUMBERS),
"'Display numbers on lines' is pref off.");
Services.prefs.clearUserPref(SHOW_GRID_LINE_NUMBERS);
});

View file

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid item's color change in the colorpicker is reverted when ESCAPE is
// pressed.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { store } = inspector;
let cPicker = gridInspector.getSwatchColorPickerTooltip();
let spectrum = cPicker.spectrum;
let swatch = doc.querySelector(".grid-color-swatch");
info("Checking the initial state of the Grid Inspector.");
is(swatch.style.backgroundColor, "rgb(75, 0, 130)",
"The color swatch's background is correct.");
is(store.getState().grids[0].color, "#4B0082", "The grid color state is correct.");
info("Scrolling into view of the #grid color swatch.");
swatch.scrollIntoView();
info("Opening the color picker by clicking on the #grid color swatch.");
let onColorPickerReady = cPicker.once("ready");
swatch.click();
yield onColorPickerReady;
yield simulateColorPickerChange(cPicker, [0, 255, 0, .5]);
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
"The color swatch's background was updated.");
info("Pressing ESCAPE to close the tooltip.");
let onGridColorUpdate = waitUntilState(store, state =>
state.grids[0].color === "#4B0082");
let onColorPickerHidden = cPicker.tooltip.once("hidden");
focusAndSendKey(spectrum.element.ownerDocument.defaultView, "ESCAPE");
yield onColorPickerHidden;
yield onGridColorUpdate;
is(swatch.style.backgroundColor, "rgb(75, 0, 130)",
"The color swatch's background was reverted after ESCAPE.");
});

View file

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid item's color change in the colorpicker is committed when RETURN is
// pressed.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { store } = inspector;
let cPicker = gridInspector.getSwatchColorPickerTooltip();
let spectrum = cPicker.spectrum;
let swatch = doc.querySelector(".grid-color-swatch");
info("Checking the initial state of the Grid Inspector.");
is(swatch.style.backgroundColor, "rgb(75, 0, 130)",
"The color swatch's background is correct.");
is(store.getState().grids[0].color, "#4B0082", "The grid color state is correct.");
info("Scrolling into view of the #grid color swatch.");
swatch.scrollIntoView();
info("Opening the color picker by clicking on the #grid color swatch.");
let onColorPickerReady = cPicker.once("ready");
swatch.click();
yield onColorPickerReady;
yield simulateColorPickerChange(cPicker, [0, 255, 0, .5]);
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
"The color swatch's background was updated.");
info("Pressing RETURN to commit the color change.");
let onGridColorUpdate = waitUntilState(store, state =>
state.grids[0].color === "#00FF0080");
let onColorPickerHidden = cPicker.tooltip.once("hidden");
focusAndSendKey(spectrum.element.ownerDocument.defaultView, "RETURN");
yield onColorPickerHidden;
yield onGridColorUpdate;
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
"The color swatch's background was kept after RETURN.");
});

View file

@ -0,0 +1,49 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid item's element rep will display the box model higlighter on hover
// and select the node on click.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector, toolbox } = yield openLayoutView();
let { document: doc } = gridInspector;
let { store } = inspector;
let gridList = doc.querySelector("#grid-list");
let elementRep = gridList.children[0].querySelector(".open-inspector");
info("Scrolling into the view the #grid element node rep.");
elementRep.scrollIntoView();
info("Listen to node-highlight event and mouse over the widget");
let onHighlight = toolbox.once("node-highlight");
EventUtils.synthesizeMouse(elementRep, 10, 5, {type: "mouseover"}, doc.defaultView);
let nodeFront = yield onHighlight;
ok(nodeFront, "nodeFront was returned from highlighting the node.");
is(nodeFront.tagName, "DIV", "The highlighted node has the correct tagName.");
is(nodeFront.attributes[0].name, "id",
"The highlighted node has the correct attributes.");
is(nodeFront.attributes[0].value, "grid", "The highlighted node has the correct id.");
let onSelection = inspector.selection.once("new-node-front");
EventUtils.sendMouseEvent({type: "click"}, elementRep, doc.defaultView);
yield onSelection;
is(inspector.selection.nodeFront, store.getState().grids[0].nodeFront,
"The selected node is the one stored on the grid item's state.");
});

View file

@ -0,0 +1,34 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that no grid list items and a "no grids available" message is displayed when
// there are no grid containers on the page.
const TEST_URI = `
<style type='text/css'>
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { highlighters } = inspector;
yield selectNode("#grid", inspector);
let noGridList = doc.querySelector(".layout-no-grids");
let gridList = doc.querySelector("#grid-list");
info("Checking the initial state of the Grid Inspector.");
ok(noGridList, "The message no grid containers is displayed.");
ok(!gridList, "No grid containers are listed.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
});

View file

@ -0,0 +1,93 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid list updates when a new grid container is added to the page.
const TEST_URI = `
<style type='text/css'>
.grid {
display: grid;
}
</style>
<div id="grid1" class="grid">
<div class="cell1">cell1</div>
<div class="cell2">cell2</div>
</div>
<div id="grid2">
<div class="cell1">cell1</div>
<div class="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector, testActor } = yield openLayoutView();
let { document: doc } = gridInspector;
let { highlighters, store } = inspector;
yield selectNode("#grid", inspector);
let gridList = doc.querySelector("#grid-list");
let checkbox1 = gridList.children[0].querySelector("input");
info("Checking the initial state of the Grid Inspector.");
is(gridList.childNodes.length, 1, "One grid container is listed.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter from the layout panel.");
let onHighlighterShown = highlighters.once("grid-highlighter-shown");
checkbox1.click();
yield onHighlighterShown;
info("Checking the CSS grid highlighter is created.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
info("Adding the #grid2 container in the content page.");
let onGridListUpdate = waitUntilState(store, state =>
state.grids.length == 2 &&
state.grids[0].highlighted &&
!state.grids[1].highlighted);
testActor.eval(`
content.document.getElementById("grid2").classList.add("grid");
`);
yield onGridListUpdate;
info("Checking the new Grid Inspector state.");
is(gridList.childNodes.length, 2, "Two grid containers are listed.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
let checkbox2 = gridList.children[1].querySelector("input");
info("Toggling ON the CSS grid highlighter for #grid2.");
onHighlighterShown = highlighters.once("grid-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 2 &&
!state.grids[0].highlighted &&
state.grids[1].highlighted);
checkbox2.click();
yield onHighlighterShown;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is still shown.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
info("Toggling OFF the CSS grid highlighter from the layout panel.");
let onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 2 &&
!state.grids[0].highlighted &&
!state.grids[1].highlighted);
checkbox2.click();
yield onHighlighterHidden;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is not shown.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
});

View file

@ -0,0 +1,63 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the grid item is removed from the grid list when the grid container is
// removed from the page.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector, testActor } = yield openLayoutView();
let { document: doc } = gridInspector;
let { highlighters, store } = inspector;
yield selectNode("#grid", inspector);
let gridList = doc.querySelector("#grid-list");
let checkbox = gridList.children[0].querySelector("input");
info("Checking the initial state of the Grid Inspector.");
is(gridList.childNodes.length, 1, "One grid container is listed.");
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter from the layout panel.");
let onHighlighterShown = highlighters.once("grid-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 1 && state.grids[0].highlighted);
checkbox.click();
yield onHighlighterShown;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is created.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
info("Removing the #grid container in the content page.");
let onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state => state.grids.length == 0);
testActor.eval(`
content.document.getElementById("grid").remove();
`);
yield onHighlighterHidden;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is not shown.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
let noGridList = doc.querySelector(".layout-no-grids");
ok(noGridList, "The message no grid containers is displayed.");
});

View file

@ -0,0 +1,84 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test toggling the grid highlighter in the grid inspector panel with multiple grids in
// the page.
const TEST_URI = `
<style type='text/css'>
.grid {
display: grid;
}
</style>
<div id="grid1" class="grid">
<div class="cell1">cell1</div>
<div class="cell2">cell2</div>
</div>
<div id="grid2" class="grid">
<div class="cell1">cell1</div>
<div class="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { inspector, gridInspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { highlighters, store } = inspector;
yield selectNode("#grid1", inspector);
let gridList = doc.querySelector("#grid-list");
let checkbox1 = gridList.children[0].querySelector("input");
let checkbox2 = gridList.children[1].querySelector("input");
info("Checking the initial state of the Grid Inspector.");
is(gridList.childNodes.length, 2, "2 grid containers are listed.");
ok(!checkbox1.checked, `Grid item ${checkbox1.value} is unchecked in the grid list.`);
ok(!checkbox2.checked, `Grid item ${checkbox2.value} is unchecked in the grid list.`);
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter for #grid1.");
let onHighlighterShown = highlighters.once("grid-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 2 &&
state.grids[0].highlighted &&
!state.grids[1].highlighted);
checkbox1.click();
yield onHighlighterShown;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is created.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter for #grid2.");
onHighlighterShown = highlighters.once("grid-highlighter-shown");
onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 2 &&
!state.grids[0].highlighted &&
state.grids[1].highlighted);
checkbox2.click();
yield onHighlighterShown;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is still shown.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
info("Toggling OFF the CSS grid highlighter from the layout panel.");
let onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 2 &&
!state.grids[0].highlighted &&
!state.grids[1].highlighted);
checkbox2.click();
yield onHighlighterHidden;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is not shown.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
});

View file

@ -0,0 +1,62 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests toggling ON/OFF the grid highlighter from the grid ispector panel.
const TEST_URI = `
<style type='text/css'>
#grid {
display: grid;
}
</style>
<div id="grid">
<div id="cell1">cell1</div>
<div id="cell2">cell2</div>
</div>
`;
add_task(function* () {
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
let { gridInspector, inspector } = yield openLayoutView();
let { document: doc } = gridInspector;
let { highlighters, store } = inspector;
yield selectNode("#grid", inspector);
let gridList = doc.querySelector("#grid-list");
let checkbox = gridList.children[0].querySelector("input");
info("Checking the initial state of the Grid Inspector.");
is(gridList.childNodes.length, 1, "One grid container is listed.");
ok(!checkbox.checked, `Grid item ${checkbox.value} is unchecked in the grid list.`);
ok(!highlighters.highlighters[HIGHLIGHTER_TYPE],
"No CSS grid highlighter exists in the highlighters overlay.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
info("Toggling ON the CSS grid highlighter from the layout panel.");
let onHighlighterShown = highlighters.once("grid-highlighter-shown");
let onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 1 &&
state.grids[0].highlighted);
checkbox.click();
yield onHighlighterShown;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is created.");
ok(highlighters.highlighters[HIGHLIGHTER_TYPE],
"CSS grid highlighter is created in the highlighters overlay.");
ok(highlighters.gridHighlighterShown, "CSS grid highlighter is shown.");
info("Toggling OFF the CSS grid highlighter from the layout panel.");
let onHighlighterHidden = highlighters.once("grid-highlighter-hidden");
onCheckboxChange = waitUntilState(store, state =>
state.grids.length == 1 &&
!state.grids[0].highlighted);
checkbox.click();
yield onHighlighterHidden;
yield onCheckboxChange;
info("Checking the CSS grid highlighter is not shown.");
ok(!highlighters.gridHighlighterShown, "No CSS grid highlighter is shown.");
});

View file

@ -0,0 +1,74 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint no-unused-vars: [2, {"vars": "local"}] */
/* import-globals-from ../../../framework/test/shared-head.js */
/* import-globals-from ../../test/head.js */
"use strict";
// Import the inspector's head.js first (which itself imports shared-head.js).
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
this);
// Load the shared Redux helpers into this compartment.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-redux-head.js",
this);
Services.prefs.setBoolPref("devtools.layoutview.enabled", true);
Services.prefs.setIntPref("devtools.toolbox.footer.height", 350);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.layoutview.enabled");
Services.prefs.clearUserPref("devtools.toolbox.footer.height");
});
const HIGHLIGHTER_TYPE = "CssGridHighlighter";
/**
* Open the toolbox, with the inspector tool visible, and the layout view
* sidebar tab selected to display the box model view with properties.
*
* @return {Promise} a promise that resolves when the inspector is ready and the box model
* view is visible and ready.
*/
function openLayoutView() {
return openInspectorSidebarTab("layoutview").then(data => {
// The actual highligher show/hide methods are mocked in box model tests.
// The highlighter is tested in devtools/inspector/test.
function mockHighlighter({highlighter}) {
highlighter.showBoxModel = function () {
return promise.resolve();
};
highlighter.hideBoxModel = function () {
return promise.resolve();
};
}
mockHighlighter(data.toolbox);
return {
toolbox: data.toolbox,
inspector: data.inspector,
gridInspector: data.inspector.gridInspector,
testActor: data.testActor
};
});
}
/**
* Simulate a color change in a given color picker tooltip.
*
* @param {Spectrum|ColorWidget} colorPicker
* The color picker widget.
* @param {Array} newRgba
* Array of the new rgba values to be set in the color widget.
*/
var simulateColorPickerChange = Task.async(function* (colorPicker, newRgba) {
info("Getting the spectrum colorpicker object");
let spectrum = yield colorPicker.spectrum;
info("Setting the new color");
spectrum.rgb = newRgba;
info("Applying the change");
spectrum.updateUI();
spectrum.onChange();
});

View file

@ -497,16 +497,6 @@ function* clickSelectorIcon(icon, view) {
yield onToggled; yield onToggled;
} }
/**
* Make sure window is properly focused before sending a key event.
* @param {Window} win
* @param {Event} key
*/
function focusAndSendKey(win, key) {
win.document.documentElement.focus();
EventUtils.sendKey(key, win);
}
/** /**
* Toggle one of the checkboxes inside the class-panel. Resolved after the DOM mutation * Toggle one of the checkboxes inside the class-panel. Resolved after the DOM mutation
* has been recorded. * has been recorded.

View file

@ -6,7 +6,6 @@
"use strict"; "use strict";
const promise = require("promise");
const {Task} = require("devtools/shared/task"); const {Task} = require("devtools/shared/task");
const EventEmitter = require("devtools/shared/event-emitter"); const EventEmitter = require("devtools/shared/event-emitter");
const { VIEW_NODE_VALUE_TYPE } = require("devtools/client/inspector/shared/node-types"); const { VIEW_NODE_VALUE_TYPE } = require("devtools/client/inspector/shared/node-types");
@ -267,18 +266,26 @@ HighlightersOverlay.prototype = {
* The highlighter type. One of this.highlighters. * The highlighter type. One of this.highlighters.
* @return {Promise} that resolves to the highlighter * @return {Promise} that resolves to the highlighter
*/ */
_getHighlighter: function (type) { _getHighlighter: Task.async(function* (type) {
let utils = this.highlighterUtils; let utils = this.highlighterUtils;
if (this.highlighters[type]) { if (this.highlighters[type]) {
return promise.resolve(this.highlighters[type]); return this.highlighters[type];
} }
return utils.getHighlighterByType(type).then(highlighter => { let highlighter;
this.highlighters[type] = highlighter;
return highlighter; try {
}); highlighter = yield utils.getHighlighterByType(type);
}, } catch (e) {}
if (!highlighter) {
return null;
}
this.highlighters[type] = highlighter;
return highlighter;
}),
_handleRejection: function (error) { _handleRejection: function (error) {
if (!this.destroyed) { if (!this.destroyed) {

View file

@ -643,6 +643,19 @@ function synthesizeKeys(input, win) {
} }
} }
/**
* Make sure window is properly focused before sending a key event.
*
* @param {Window} win
* The window containing the panel
* @param {String} key
* The string value to input
*/
function focusAndSendKey(win, key) {
win.document.documentElement.focus();
EventUtils.sendKey(key, win);
}
/** /**
* Given a Tooltip instance, fake a mouse event on the `target` DOM Element * Given a Tooltip instance, fake a mouse event on the `target` DOM Element
* and assert that the `tooltip` is correctly displayed. * and assert that the `tooltip` is correctly displayed.

View file

@ -62,6 +62,7 @@ function ensureElementRemoval(aElement) {
}); });
} }
SimpleTest.expectAssertions(0, 1); // bug 1332970
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
var omtaEnabled = isOMTAEnabled(); var omtaEnabled = isOMTAEnabled();

View file

@ -10010,9 +10010,9 @@ nsIDocument::RegisterPendingLinkUpdate(Link* aLink)
if (!mHasLinksToUpdateRunnable) { if (!mHasLinksToUpdateRunnable) {
nsCOMPtr<nsIRunnable> event = nsCOMPtr<nsIRunnable> event =
NewRunnableMethod(this, &nsIDocument::FlushPendingLinkUpdatesFromRunnable); NewRunnableMethod(this, &nsIDocument::FlushPendingLinkUpdatesFromRunnable);
// Do this work in a second in the worst case.
nsresult rv = nsresult rv =
Dispatch("nsIDocument::FlushPendingLinkUpdatesFromRunnable", NS_IdleDispatchToCurrentThread(event.forget(), 1000);
TaskCategory::Other, event.forget());
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
// If during shutdown posting a runnable doesn't succeed, we probably // If during shutdown posting a runnable doesn't succeed, we probably
// don't need to update link states. // don't need to update link states.

View file

@ -867,7 +867,11 @@ nsGlobalWindow::ExecuteIdleRequest(TimeStamp aDeadline)
mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit(); mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
nsresult result = RunIdleRequest(request, deadline, false); nsresult result = RunIdleRequest(request, deadline, false);
mIdleRequestExecutor->MaybeDispatch(); // Running the idle callback could've suspended the window, in which
// case mIdleRequestExecutor will be null.
if (mIdleRequestExecutor) {
mIdleRequestExecutor->MaybeDispatch();
}
return result; return result;
} }

View file

@ -146,6 +146,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
, mRv(NS_OK) , mRv(NS_OK)
, mSkip(false) , mSkip(false)
, mCoerceToString(false) , mCoerceToString(false)
, mEncodeBytecode(false)
#ifdef DEBUG #ifdef DEBUG
, mWantsReturnValue(false) , mWantsReturnValue(false)
, mExpectScopeChain(false) , mExpectScopeChain(false)
@ -204,7 +205,19 @@ nsJSUtils::ExecutionContext::JoinAndExec(void **aOffThreadToken,
MOZ_ASSERT(!mExpectScopeChain); MOZ_ASSERT(!mExpectScopeChain);
aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken)); aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
*aOffThreadToken = nullptr; // Mark the token as having been finished. *aOffThreadToken = nullptr; // Mark the token as having been finished.
if (!aScript || !JS_ExecuteScript(mCx, mScopeChain, aScript)) { if (!aScript) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) {
mSkip = true; mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx); mRv = EvaluationExceptionToNSResult(mCx);
return mRv; return mRv;
@ -215,7 +228,8 @@ nsJSUtils::ExecutionContext::JoinAndExec(void **aOffThreadToken,
nsresult nsresult
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions, nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
JS::SourceBufferHolder& aSrcBuf) JS::SourceBufferHolder& aSrcBuf,
JS::MutableHandle<JSScript*> aScript)
{ {
if (mSkip) { if (mSkip) {
return mRv; return mRv;
@ -228,8 +242,29 @@ nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
#ifdef DEBUG #ifdef DEBUG
mWantsReturnValue = !aCompileOptions.noScriptRval; mWantsReturnValue = !aCompileOptions.noScriptRval;
#endif #endif
bool compiled = true;
if (mScopeChain.length() == 0) {
compiled = JS::Compile(mCx, aCompileOptions, aSrcBuf, aScript);
} else {
compiled = JS::CompileForNonSyntacticScope(mCx, aCompileOptions, aSrcBuf, aScript);
}
MOZ_ASSERT_IF(compiled, aScript);
if (!compiled) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
MOZ_ASSERT(!mCoerceToString || mWantsReturnValue); MOZ_ASSERT(!mCoerceToString || mWantsReturnValue);
if (!JS::Evaluate(mCx, mScopeChain, aCompileOptions, aSrcBuf, &mRetValue)) { if (!JS_ExecuteScript(mCx, mScopeChain, aScript, &mRetValue)) {
mSkip = true; mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx); mRv = EvaluationExceptionToNSResult(mCx);
return mRv; return mRv;
@ -242,6 +277,7 @@ nsresult
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions, nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
const nsAString& aScript) const nsAString& aScript)
{ {
MOZ_ASSERT(!mEncodeBytecode, "A JSScript is needed for calling FinishIncrementalEncoding");
if (mSkip) { if (mSkip) {
return mRv; return mRv;
} }
@ -249,7 +285,8 @@ nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript); const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(), JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
JS::SourceBufferHolder::NoOwnership); JS::SourceBufferHolder::NoOwnership);
return CompileAndExec(aCompileOptions, srcBuf); JS::Rooted<JSScript*> script(mCx);
return CompileAndExec(aCompileOptions, srcBuf, &script);
} }
nsresult nsresult
@ -257,6 +294,7 @@ nsJSUtils::ExecutionContext::DecodeAndExec(JS::CompileOptions& aCompileOptions,
mozilla::Vector<uint8_t>& aBytecodeBuf, mozilla::Vector<uint8_t>& aBytecodeBuf,
size_t aBytecodeIndex) size_t aBytecodeIndex)
{ {
MOZ_ASSERT(!mEncodeBytecode, "A JSScript is needed for calling FinishIncrementalEncoding");
if (mSkip) { if (mSkip) {
return mRv; return mRv;
} }
@ -305,34 +343,6 @@ nsJSUtils::ExecutionContext::DecodeJoinAndExec(void **aOffThreadToken)
return NS_OK; return NS_OK;
} }
nsresult
nsJSUtils::ExecutionContext::JoinEncodeAndExec(void **aOffThreadToken,
JS::MutableHandle<JSScript*> aScript)
{
MOZ_ASSERT_IF(aOffThreadToken, !mWantsReturnValue);
aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
*aOffThreadToken = nullptr; // Mark the token as having been finished.
if (!aScript) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (!StartIncrementalEncoding(mCx, aScript)) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) {
mSkip = true;
mRv = EvaluationExceptionToNSResult(mCx);
return mRv;
}
return mRv;
}
nsresult nsresult
nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue) nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue)
{ {

View file

@ -95,6 +95,9 @@ public:
// Should the result be serialized before being returned. // Should the result be serialized before being returned.
bool mCoerceToString; bool mCoerceToString;
// Encode the bytecode before it is being executed.
bool mEncodeBytecode;
#ifdef DEBUG #ifdef DEBUG
// Should we set the return value. // Should we set the return value.
bool mWantsReturnValue; bool mWantsReturnValue;
@ -124,6 +127,15 @@ public:
return *this; return *this;
} }
// When set, this flag records and encodes the bytecode as soon as it is
// being compiled, and before it is being executed. The bytecode can then be
// requested by using |JS::FinishIncrementalEncoding| with the mutable
// handle |aScript| argument of |CompileAndExec| or |JoinAndExec|.
ExecutionContext& SetEncodeBytecode(bool aEncodeBytecode) {
mEncodeBytecode = aEncodeBytecode;
return *this;
}
// Set the scope chain in which the code should be executed. // Set the scope chain in which the code should be executed.
void SetScopeChain(const JS::AutoObjectVector& aScopeChain); void SetScopeChain(const JS::AutoObjectVector& aScopeChain);
@ -149,7 +161,8 @@ public:
// Compile a script contained in a SourceBuffer, and execute it. // Compile a script contained in a SourceBuffer, and execute it.
nsresult CompileAndExec(JS::CompileOptions& aCompileOptions, nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
JS::SourceBufferHolder& aSrcBuf); JS::SourceBufferHolder& aSrcBuf,
JS::MutableHandle<JSScript*> aScript);
// Compile a script contained in a string, and execute it. // Compile a script contained in a string, and execute it.
nsresult CompileAndExec(JS::CompileOptions& aCompileOptions, nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
@ -164,11 +177,6 @@ public:
// function will get the result of the decoder by moving it to the main // function will get the result of the decoder by moving it to the main
// thread before starting the execution of the script. // thread before starting the execution of the script.
MOZ_MUST_USE nsresult DecodeJoinAndExec(void **aOffThreadToken); MOZ_MUST_USE nsresult DecodeJoinAndExec(void **aOffThreadToken);
// Similar to JoinAndExec, except that in addition to fecthing the source,
// we register the fact that we plan to encode its bytecode later.
MOZ_MUST_USE nsresult JoinEncodeAndExec(void **aOffThreadToken,
JS::MutableHandle<JSScript*> aScript);
}; };
static nsresult CompileModule(JSContext* aCx, static nsresult CompileModule(JSContext* aCx,

View file

@ -760,7 +760,6 @@ support-files =
file_js_cache.js file_js_cache.js
file_js_cache_save_after_load.html file_js_cache_save_after_load.html
file_js_cache_save_after_load.js file_js_cache_save_after_load.js
skip-if = (os == 'linux' || toolkit == 'android') # mochitest are executed on a single core
[test_setInterval_uncatchable_exception.html] [test_setInterval_uncatchable_exception.html]
skip-if = debug == false skip-if = debug == false
[test_settimeout_extra_arguments.html] [test_settimeout_extra_arguments.html]

View file

@ -18,22 +18,26 @@
// code path, such that we can assert each code path with a single word. // code path, such that we can assert each code path with a single word.
var scriptLoaderStateMachine = { var scriptLoaderStateMachine = {
"scriptloader_load_source": { "scriptloader_load_source": {
"scriptloader_encode_and_execute": { "scriptloader_execute": {
"scriptloader_bytecode_saved": "bytecode_saved", "scriptloader_encode": {
"scriptloader_bytecode_failed": "bytecode_failed" "scriptloader_bytecode_saved": "bytecode_saved",
}, "scriptloader_bytecode_failed": "bytecode_failed"
"scriptloader_execute": "source_exec" },
"scriptloader_no_encode": "source_exec"
}
}, },
"scriptloader_load_bytecode": { "scriptloader_load_bytecode": {
"scriptloader_fallback": { "scriptloader_fallback": {
// Replicate the top-level state machine without // Replicate the top-level state machine without
// "scriptloader_load_bytecode" transition. // "scriptloader_load_bytecode" transition.
"scriptloader_load_source": { "scriptloader_load_source": {
"scriptloader_encode_and_execute": { "scriptloader_execute": {
"scriptloader_bytecode_saved": "fallback_bytecode_saved", "scriptloader_encode": {
"scriptloader_bytecode_failed": "fallback_bytecode_failed" "scriptloader_bytecode_saved": "fallback_bytecode_saved",
}, "scriptloader_bytecode_failed": "fallback_bytecode_failed"
"scriptloader_execute": "fallback_source_exec" },
"scriptloader_no_encode": "fallback_source_exec"
}
} }
}, },
"scriptloader_execute": "bytecode_exec" "scriptloader_execute": "bytecode_exec"
@ -93,7 +97,8 @@
iwin.addEventListener("scriptloader_load_bytecode", log_event); iwin.addEventListener("scriptloader_load_bytecode", log_event);
iwin.addEventListener("scriptloader_generate_bytecode", log_event); iwin.addEventListener("scriptloader_generate_bytecode", log_event);
iwin.addEventListener("scriptloader_execute", log_event); iwin.addEventListener("scriptloader_execute", log_event);
iwin.addEventListener("scriptloader_encode_and_execute", log_event); iwin.addEventListener("scriptloader_encode", log_event);
iwin.addEventListener("scriptloader_no_encode", log_event);
iwin.addEventListener("scriptloader_bytecode_saved", log_event); iwin.addEventListener("scriptloader_bytecode_saved", log_event);
iwin.addEventListener("scriptloader_bytecode_failed", log_event); iwin.addEventListener("scriptloader_bytecode_failed", log_event);
iwin.addEventListener("scriptloader_fallback", log_event); iwin.addEventListener("scriptloader_fallback", log_event);

View file

@ -667,8 +667,21 @@ GetSupportedCapabilities(const CodecType aCodecType,
if (codecs.IsEmpty()) { if (codecs.IsEmpty()) {
// If container normatively implies a specific set of codecs and codec constraints: // If container normatively implies a specific set of codecs and codec constraints:
// Let parameters be that set. // Let parameters be that set.
if (isMP4) {
if (aCodecType == Audio) {
codecs.AppendElement(EME_CODEC_AAC);
} else if (aCodecType == Video) {
codecs.AppendElement(EME_CODEC_H264);
}
} else if (isWebM) {
if (aCodecType == Audio) {
codecs.AppendElement(EME_CODEC_VORBIS);
} else if (aCodecType == Video) {
codecs.AppendElement(EME_CODEC_VP8);
}
}
// Otherwise: Continue to the next iteration. // Otherwise: Continue to the next iteration.
continue; // (Note: all containers we support have implied codecs, so don't continue here.)
} }
// If container type is not strictly a audio/video type, continue to the next iteration. // If container type is not strictly a audio/video type, continue to the next iteration.
@ -940,13 +953,8 @@ GetSupportedConfig(const KeySystemConfig& aKeySystem,
// If the videoCapabilities and audioCapabilities members in candidate // If the videoCapabilities and audioCapabilities members in candidate
// configuration are both empty, return NotSupported. // configuration are both empty, return NotSupported.
if (aCandidate.mAudioCapabilities.IsEmpty() && // TODO: Most sites using EME still don't pass capabilities, so we
aCandidate.mVideoCapabilities.IsEmpty()) { // can't reject on it yet without breaking them. So add this later.
EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
"no supported audio or video capabilities specified",
NS_ConvertUTF16toUTF8(aCandidate.mLabel).get());
return false;
}
// If the videoCapabilities member in candidate configuration is non-empty: // If the videoCapabilities member in candidate configuration is non-empty:
if (!aCandidate.mVideoCapabilities.IsEmpty()) { if (!aCandidate.mVideoCapabilities.IsEmpty()) {

View file

@ -2,8 +2,8 @@ const CLEARKEY_KEYSYSTEM = "org.w3.clearkey";
const gCencMediaKeySystemConfig = [{ const gCencMediaKeySystemConfig = [{
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"' }], videoCapabilities: [{ contentType: 'video/mp4' }],
audioCapabilities: [{ contentType: 'audio/mp4; codecs="mp4a.40.2"' }], audioCapabilities: [{ contentType: 'audio/mp4' }],
}]; }];
function IsMacOSSnowLeopardOrEarlier() { function IsMacOSSnowLeopardOrEarlier() {

View file

@ -94,7 +94,11 @@ function PrepareInitData(initDataType, initData)
function Test(test) { function Test(test) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
navigator.requestMediaKeySystemAccess('org.w3.clearkey', gCencMediaKeySystemConfig) var configs = [{
initDataTypes: [test.initDataType],
videoCapabilities: [{contentType: 'video/mp4' }],
}];
navigator.requestMediaKeySystemAccess('org.w3.clearkey', configs)
.then((access) => access.createMediaKeys()) .then((access) => access.createMediaKeys())
.then((mediaKeys) => { .then((mediaKeys) => {
var session = mediaKeys.createSession(test.sessionType); var session = mediaKeys.createSession(test.sessionType);

View file

@ -35,8 +35,8 @@
function LoadEME() { function LoadEME() {
var options = [{ var options = [{
initDataTypes: ['cenc'], initDataType: 'cenc',
audioCapabilities: [{ contentType: 'audio/mp4; codecs="mp4a.40.2"' }], audioType: 'audio/mp4; codecs="mp4a.40.2"',
}]; }];
navigator.requestMediaKeySystemAccess("org.w3.clearkey", options) navigator.requestMediaKeySystemAccess("org.w3.clearkey", options)
.then((keySystemAccess) => { .then((keySystemAccess) => {

View file

@ -70,13 +70,6 @@ function Test(test) {
}); });
} }
const AUDIO_WEBM_VORBIS = 'audio/webm; codecs="vorbis"';
const VIDEO_WEBM_VP8 = 'video/webm; codecs="vp8"';
const VIDEO_WEBM_VP9 = 'video/webm; codecs="vp9"';
const AUDIO_MP4_AAC = 'audio/mp4; codecs="mp4a.40.2"';
const VIDEO_MP4_H264 = 'video/mp4; codecs="avc1.42E01E"';
var tests = [ var tests = [
{ {
name: 'Empty keySystem string', name: 'Empty keySystem string',
@ -84,7 +77,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
} }
], ],
shouldPass: false, shouldPass: false,
@ -104,15 +97,15 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -122,7 +115,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
} }
], ],
shouldPass: false, shouldPass: false,
@ -132,7 +125,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['bogus'], initDataTypes: ['bogus'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
} }
], ],
shouldPass: false, shouldPass: false,
@ -143,13 +136,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['bogus', 'invalid', 'cenc'], initDataTypes: ['bogus', 'invalid', 'cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -168,7 +161,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
distinctiveIdentifier: 'bogus', distinctiveIdentifier: 'bogus',
persistentState: 'bogus', persistentState: 'bogus',
} }
@ -180,7 +173,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
distinctiveIdentifier: 'required', distinctiveIdentifier: 'required',
} }
], ],
@ -191,7 +184,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
persistentState: 'bogus', persistentState: 'bogus',
} }
], ],
@ -202,7 +195,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264, robustness: 'very much so'}], videoCapabilities: [{contentType: 'video/mp4', robustness: 'very much so'}],
} }
], ],
shouldPass: false, shouldPass: false,
@ -213,14 +206,14 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
unexpectedEntry: 'this should be ignored', unexpectedEntry: 'this should be ignored',
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -234,13 +227,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -249,7 +242,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
sessionTypes: ['persistent-license'], sessionTypes: ['persistent-license'],
persistentState: 'optional', persistentState: 'optional',
} }
@ -261,7 +254,7 @@ var tests = [
options: [ options: [
{ {
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4'}],
sessionTypes: ['persistent-usage-record'], sessionTypes: ['persistent-usage-record'],
persistentState: 'optional', persistentState: 'optional',
} }
@ -274,13 +267,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -290,13 +283,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -346,13 +339,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -382,15 +375,15 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['cenc'], initDataTypes: ['cenc'],
audioCapabilities: [{contentType: AUDIO_MP4_AAC}], videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
videoCapabilities: [{contentType: VIDEO_MP4_H264}], audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -400,13 +393,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
videoCapabilities: [{contentType: VIDEO_WEBM_VP9}], videoCapabilities: [{contentType: 'video/webm'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
videoCapabilities: [{contentType: VIDEO_WEBM_VP9}], videoCapabilities: [{contentType: 'video/webm'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -416,13 +409,13 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
audioCapabilities: [{contentType: AUDIO_WEBM_VORBIS}], audioCapabilities: [{contentType: 'audio/webm'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
audioCapabilities: [{contentType: AUDIO_WEBM_VORBIS}], audioCapabilities: [{contentType: 'audio/webm'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -432,15 +425,15 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
videoCapabilities: [{contentType: VIDEO_WEBM_VP8}], videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}],
audioCapabilities: [{contentType: AUDIO_WEBM_VORBIS}], audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
videoCapabilities: [{contentType: VIDEO_WEBM_VP8}], videoCapabilities: [{contentType: 'video/webm;codecs="vp8"'}],
audioCapabilities: [{contentType: AUDIO_WEBM_VORBIS}], audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -450,15 +443,15 @@ var tests = [
{ {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
videoCapabilities: [{contentType: VIDEO_WEBM_VP9}], videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}],
audioCapabilities: [{contentType: AUDIO_WEBM_VORBIS}], audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
} }
], ],
expectedConfig: { expectedConfig: {
label: SUPPORTED_LABEL, label: SUPPORTED_LABEL,
initDataTypes: ['webm'], initDataTypes: ['webm'],
videoCapabilities: [{contentType: VIDEO_WEBM_VP9}], videoCapabilities: [{contentType: 'video/webm;codecs="vp9"'}],
audioCapabilities: [{contentType: AUDIO_WEBM_VORBIS}], audioCapabilities: [{contentType: 'audio/webm;codecs="vorbis"'}],
}, },
shouldPass: true, shouldPass: true,
}, },
@ -472,15 +465,6 @@ var tests = [
], ],
shouldPass: false, shouldPass: false,
}, },
{
name: 'Unspecified capabilities',
options: [
{
initDataTypes: ['cenc'],
}
],
shouldPass: false,
},
]; ];
function beginTest() { function beginTest() {

View file

@ -58,8 +58,8 @@
function LoadEME() { function LoadEME() {
var options = [{ var options = [{
initDataTypes: ['cenc'], initDataType: "cenc",
videoCapabilities: [{contentType: test.track.type}], videoType: test.track.type,
}]; }];
return navigator.requestMediaKeySystemAccess("org.w3.clearkey", options) return navigator.requestMediaKeySystemAccess("org.w3.clearkey", options)

View file

@ -1879,13 +1879,6 @@ ScriptLoader::FillCompileOptionsForRequest(const AutoJSAPI&jsapi,
aOptions->setElement(&elementVal.toObject()); aOptions->setElement(&elementVal.toObject());
} }
// At the moment, the bytecode cache is only triggered if a script is large
// enough to be parsed out of the main thread. Thus, for testing purposes, we
// force parsing any script out of the main thread.
if (IsEagerBytecodeCache()) {
aOptions->forceAsync = true;
}
return NS_OK; return NS_OK;
} }
@ -1993,49 +1986,46 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
MOZ_ASSERT(!aRequest->mCacheInfo); MOZ_ASSERT(!aRequest->mCacheInfo);
} else { } else {
MOZ_ASSERT(aRequest->IsSource()); MOZ_ASSERT(aRequest->IsSource());
if (aRequest->mOffThreadToken) { JS::Rooted<JSScript*> script(aes.cx());
// Off-main-thread parsing.
LOG(("ScriptLoadRequest (%p): Join (off-thread parsing) and Execute", bool encodeBytecode = false;
aRequest)); if (aRequest->mCacheInfo) {
{ MOZ_ASSERT(aRequest->mBytecodeOffset ==
nsJSUtils::ExecutionContext exec(aes.cx(), global); aRequest->mScriptBytecode.length());
JS::Rooted<JSScript*> script(aes.cx()); encodeBytecode = IsEagerBytecodeCache(); // Heuristic!
if (!aRequest->mCacheInfo) { }
TRACE_FOR_TEST(aRequest->mElement, "scriptloader_execute");
rv = exec.JoinAndExec(&aRequest->mOffThreadToken, &script); {
LOG(("ScriptLoadRequest (%p): Cannot cache anything (cacheInfo = nullptr)",
aRequest));
} else {
TRACE_FOR_TEST(aRequest->mElement, "scriptloader_encode_and_execute");
MOZ_ASSERT(aRequest->mBytecodeOffset ==
aRequest->mScriptBytecode.length());
rv = exec.JoinEncodeAndExec(&aRequest->mOffThreadToken,
&script);
// Queue the current script load request to later save the bytecode.
if (NS_SUCCEEDED(rv)) {
aRequest->mScript = script;
HoldJSObjects(aRequest);
RegisterForBytecodeEncoding(aRequest);
} else {
LOG(("ScriptLoadRequest (%p): Cannot cache anything (rv = %X, script = %p, cacheInfo = %p)",
aRequest, unsigned(rv), script.get(), aRequest->mCacheInfo.get()));
TRACE_FOR_TEST_NONE(aRequest->mElement, "scriptloader_bytecode_failed");
aRequest->mCacheInfo = nullptr;
}
}
}
} else {
// Main thread parsing (inline and small scripts)
LOG(("ScriptLoadRequest (%p): Compile And Exec", aRequest));
nsJSUtils::ExecutionContext exec(aes.cx(), global); nsJSUtils::ExecutionContext exec(aes.cx(), global);
nsAutoString inlineData; exec.SetEncodeBytecode(encodeBytecode);
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
TRACE_FOR_TEST(aRequest->mElement, "scriptloader_execute"); TRACE_FOR_TEST(aRequest->mElement, "scriptloader_execute");
rv = exec.CompileAndExec(options, srcBuf); if (aRequest->mOffThreadToken) {
// Off-main-thread parsing.
LOG(("ScriptLoadRequest (%p): Join (off-thread parsing) and Execute",
aRequest));
rv = exec.JoinAndExec(&aRequest->mOffThreadToken, &script);
} else {
// Main thread parsing (inline and small scripts)
LOG(("ScriptLoadRequest (%p): Compile And Exec", aRequest));
nsAutoString inlineData;
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
rv = exec.CompileAndExec(options, srcBuf, &script);
}
}
// Queue the current script load request to later save the bytecode.
if (NS_SUCCEEDED(rv) && encodeBytecode) {
aRequest->mScript = script;
HoldJSObjects(aRequest);
TRACE_FOR_TEST(aRequest->mElement, "scriptloader_encode");
RegisterForBytecodeEncoding(aRequest);
} else {
LOG(("ScriptLoadRequest (%p): Cannot cache anything (rv = %X, script = %p, cacheInfo = %p)",
aRequest, unsigned(rv), script.get(), aRequest->mCacheInfo.get()));
TRACE_FOR_TEST_NONE(aRequest->mElement, "scriptloader_no_encode");
aRequest->mCacheInfo = nullptr; aRequest->mCacheInfo = nullptr;
} }
} }
} }
} }

View file

@ -472,7 +472,10 @@ public:
sSurfaceMemoryUsed[size_t(aType)] = sSurfaceMemoryUsed[size_t(aType)] + aBytes; sSurfaceMemoryUsed[size_t(aType)] = sSurfaceMemoryUsed[size_t(aType)] + aBytes;
}; };
NS_DECL_ISUPPORTS // This memory reporter is sometimes allocated on the compositor thread,
// but always released on the main thread, so its refcounting needs to be
// threadsafe.
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD CollectReports(nsIHandleReportCallback *aHandleReport, NS_IMETHOD CollectReports(nsIHandleReportCallback *aHandleReport,
nsISupports *aData, bool aAnonymize) override nsISupports *aData, bool aAnonymize) override

View file

@ -2604,13 +2604,8 @@ gfxFont::GetShapedWord(DrawTarget *aDrawTarget,
} }
gfxShapedWord* sw = entry->mShapedWord.get(); gfxShapedWord* sw = entry->mShapedWord.get();
bool isContent = !mStyle.systemFont;
if (sw) { if (sw) {
sw->ResetAge(); sw->ResetAge();
Telemetry::Accumulate((isContent ? Telemetry::WORD_CACHE_HITS_CONTENT :
Telemetry::WORD_CACHE_HITS_CHROME),
aLength);
#ifndef RELEASE_OR_BETA #ifndef RELEASE_OR_BETA
if (aTextPerf) { if (aTextPerf) {
aTextPerf->current.wordCacheHit++; aTextPerf->current.wordCacheHit++;
@ -2619,9 +2614,6 @@ gfxFont::GetShapedWord(DrawTarget *aDrawTarget,
return sw; return sw;
} }
Telemetry::Accumulate((isContent ? Telemetry::WORD_CACHE_MISSES_CONTENT :
Telemetry::WORD_CACHE_MISSES_CHROME),
aLength);
#ifndef RELEASE_OR_BETA #ifndef RELEASE_OR_BETA
if (aTextPerf) { if (aTextPerf) {
aTextPerf->current.wordCacheMiss++; aTextPerf->current.wordCacheMiss++;

View file

@ -0,0 +1,6 @@
// |jit-test| error:overflow
if (getBuildConfiguration().debug === true)
throw "overflow";
function f(){};
Object.defineProperty(f, "name", {value: "a".repeat((1<<28)-1)});
len = f.bind().name.length;

View file

@ -345,6 +345,11 @@ AtomizeAndCopyChars(JSContext* cx, const CharT* tbchars, size_t length, PinningB
} }
} }
// Validate the length before taking the exclusive access lock, as throwing
// an exception here may reenter this code.
if (MOZ_UNLIKELY(!JSString::validateLength(cx, length)))
return nullptr;
AutoLockForExclusiveAccess lock(cx); AutoLockForExclusiveAccess lock(cx);
AtomSet& atoms = cx->atoms(lock); AtomSet& atoms = cx->atoms(lock);
@ -358,9 +363,6 @@ AtomizeAndCopyChars(JSContext* cx, const CharT* tbchars, size_t length, PinningB
return atom; return atom;
} }
if (!JSString::validateLength(cx, length))
return nullptr;
JSAtom* atom; JSAtom* atom;
{ {
AutoAtomsCompartment ac(cx, lock); AutoAtomsCompartment ac(cx, lock);

View file

@ -47,6 +47,8 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_GetRules, ServoCssRulesStrong,
RawServoStyleSheetBorrowed sheet) RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_Clone, RawServoStyleSheetStrong, SERVO_BINDING_FUNC(Servo_StyleSheet_Clone, RawServoStyleSheetStrong,
RawServoStyleSheetBorrowed sheet) RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_SizeOfIncludingThis, size_t,
mozilla::MallocSizeOf malloc_size_of, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSetOwned, RawGeckoPresContextOwned pres_context) SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSetOwned, RawGeckoPresContextOwned pres_context)
SERVO_BINDING_FUNC(Servo_StyleSet_Clear, void, SERVO_BINDING_FUNC(Servo_StyleSet_Clear, void,
RawServoStyleSetBorrowed set) RawServoStyleSetBorrowed set)

View file

@ -321,6 +321,7 @@ structs-types = [
"mozilla::css::GridTemplateAreasValue", "mozilla::css::GridTemplateAreasValue",
"mozilla::css::ImageValue", "mozilla::css::ImageValue",
"mozilla::css::URLValue", "mozilla::css::URLValue",
"mozilla::MallocSizeOf",
"mozilla::Side", "mozilla::Side",
"RawGeckoAnimationPropertySegment", "RawGeckoAnimationPropertySegment",
"RawGeckoComputedTiming", "RawGeckoComputedTiming",

View file

@ -59,13 +59,13 @@ ServoStyleSheetInner::CloneFor(StyleSheet* aPrimarySheet)
static_cast<ServoStyleSheet*>(aPrimarySheet)); static_cast<ServoStyleSheet*>(aPrimarySheet));
} }
MOZ_DEFINE_MALLOC_SIZE_OF(ServoStyleSheetMallocSizeOf)
size_t size_t
ServoStyleSheetInner::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const ServoStyleSheetInner::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{ {
size_t n = aMallocSizeOf(this); size_t n = aMallocSizeOf(this);
n += Servo_StyleSheet_SizeOfIncludingThis(ServoStyleSheetMallocSizeOf, mSheet);
// XXX: need to measure mSheet
return n; return n;
} }

View file

@ -105,7 +105,7 @@ load 587336-1.html
load 590291-1.svg load 590291-1.svg
load 601999-1.html load 601999-1.html
load 605626-1.svg load 605626-1.svg
asserts(2) load 606914.xhtml # bug 606914, bug 1340561 tracks the stylo bit asserts(2) load 606914.xhtml # bug 606914
load 610594-1.html load 610594-1.html
load 610954-1.html load 610954-1.html
load 612662-1.svg load 612662-1.svg

View file

@ -3,6 +3,6 @@
[browser_bug685470.js] [browser_bug685470.js]
[browser_bug703210.js] [browser_bug703210.js]
[browser_bug706743.js] [browser_bug706743.js]
skip-if = (os == 'linux') # Bug 1157576 skip-if = (os == 'linux') || e10s # Bug 1157576
[browser_bug1163304.js] [browser_bug1163304.js]
skip-if = os != 'linux' && os != 'win' // Due to testing menubar behavior with keyboard skip-if = os != 'linux' && os != 'win' // Due to testing menubar behavior with keyboard

View file

@ -10,7 +10,7 @@ with Files("**"):
DEFINES['ANDROID_SMP'] = 0 DEFINES['ANDROID_SMP'] = 0
DEFINES['LOG_NDEBUG'] = 1 DEFINES['LOG_NDEBUG'] = 1
if CONFIG['OS_TARGET'] != 'WINNT': if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['OS_TARGET'] != 'SunOS':
DEFINES['_GLIBCXX_OS_DEFINES'] = True DEFINES['_GLIBCXX_OS_DEFINES'] = True
if CONFIG['OS_TARGET'] == 'WINNT': if CONFIG['OS_TARGET'] == 'WINNT':

View file

@ -4843,6 +4843,8 @@ pref("extensions.webextensions.themes.enabled", false);
pref("extensions.webextensions.themes.icons.enabled", false); pref("extensions.webextensions.themes.icons.enabled", false);
pref("extensions.webextensions.remote", false); pref("extensions.webextensions.remote", false);
pref("layers.popups.compositing.enabled", false);
// Report Site Issue button // Report Site Issue button
pref("extensions.webcompat-reporter.newIssueEndpoint", "https://webcompat.com/issues/new"); pref("extensions.webcompat-reporter.newIssueEndpoint", "https://webcompat.com/issues/new");
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD

View file

@ -6,6 +6,7 @@
#include "mozilla/net/CookieServiceChild.h" #include "mozilla/net/CookieServiceChild.h"
#include "mozilla/LoadInfo.h" #include "mozilla/LoadInfo.h"
#include "mozilla/BasePrincipal.h" #include "mozilla/BasePrincipal.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/ipc/URIUtils.h" #include "mozilla/ipc/URIUtils.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
#include "nsIChannel.h" #include "nsIChannel.h"
@ -47,6 +48,12 @@ CookieServiceChild::CookieServiceChild()
{ {
NS_ASSERTION(IsNeckoChild(), "not a child process"); NS_ASSERTION(IsNeckoChild(), "not a child process");
mozilla::dom::ContentChild* cc =
static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
if (cc->IsShuttingDown()) {
return;
}
// This corresponds to Release() in DeallocPCookieService. // This corresponds to Release() in DeallocPCookieService.
NS_ADDREF_THIS(); NS_ADDREF_THIS();

View file

@ -4,6 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ContentChild.h"
#include "mozilla/net/ChildDNSService.h" #include "mozilla/net/ChildDNSService.h"
#include "mozilla/net/DNSRequestChild.h" #include "mozilla/net/DNSRequestChild.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
@ -223,6 +224,12 @@ DNSRequestChild::StartRequest()
gNeckoChild->SetEventTargetForActor(this, systemGroupEventTarget); gNeckoChild->SetEventTargetForActor(this, systemGroupEventTarget);
mozilla::dom::ContentChild* cc =
static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
if (cc->IsShuttingDown()) {
return;
}
// Send request to Parent process. // Send request to Parent process.
gNeckoChild->SendPDNSRequestConstructor(this, mHost, mOriginAttributes, gNeckoChild->SendPDNSRequestConstructor(this, mHost, mOriginAttributes,
mFlags, mNetworkInterface); mFlags, mNetworkInterface);

View file

@ -66,6 +66,9 @@ void NeckoChild::InitNeckoChild()
mozilla::dom::ContentChild * cpc = mozilla::dom::ContentChild * cpc =
mozilla::dom::ContentChild::GetSingleton(); mozilla::dom::ContentChild::GetSingleton();
NS_ASSERTION(cpc, "Content Protocol is NULL!"); NS_ASSERTION(cpc, "Content Protocol is NULL!");
if (NS_WARN_IF(cpc->IsShuttingDown())) {
return;
}
gNeckoChild = cpc->SendPNeckoConstructor(); gNeckoChild = cpc->SendPNeckoConstructor();
NS_ASSERTION(gNeckoChild, "PNecko Protocol init failed!"); NS_ASSERTION(gNeckoChild, "PNecko Protocol init failed!");
} }

View file

@ -7,6 +7,7 @@
#include "DataChannelChild.h" #include "DataChannelChild.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
namespace mozilla { namespace mozilla {
@ -27,6 +28,12 @@ DataChannelChild::~DataChannelChild()
NS_IMETHODIMP NS_IMETHODIMP
DataChannelChild::ConnectParent(uint32_t aId) DataChannelChild::ConnectParent(uint32_t aId)
{ {
mozilla::dom::ContentChild* cc =
static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
if (cc->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
if (!gNeckoChild->SendPDataChannelConstructor(this, aId)) { if (!gNeckoChild->SendPDataChannelConstructor(this, aId)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

View file

@ -7,6 +7,7 @@
#include "FileChannelChild.h" #include "FileChannelChild.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
namespace mozilla { namespace mozilla {
@ -23,6 +24,12 @@ FileChannelChild::FileChannelChild(nsIURI *uri)
NS_IMETHODIMP NS_IMETHODIMP
FileChannelChild::ConnectParent(uint32_t id) FileChannelChild::ConnectParent(uint32_t id)
{ {
mozilla::dom::ContentChild* cc =
static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
if (cc->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
if (!gNeckoChild->SendPFileChannelConstructor(this, id)) { if (!gNeckoChild->SendPFileChannelConstructor(this, id)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

View file

@ -24,6 +24,7 @@
#include "mozilla/ipc/BackgroundUtils.h" #include "mozilla/ipc/BackgroundUtils.h"
#include "nsIPrompt.h" #include "nsIPrompt.h"
using mozilla::dom::ContentChild;
using namespace mozilla::ipc; using namespace mozilla::ipc;
#undef LOG #undef LOG
@ -153,6 +154,8 @@ FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext)
LOG(("FTPChannelChild::AsyncOpen [this=%p]\n", this)); LOG(("FTPChannelChild::AsyncOpen [this=%p]\n", this));
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE); NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(!static_cast<ContentChild*>(gNeckoChild->Manager())->
IsShuttingDown(), NS_ERROR_FAILURE);
NS_ENSURE_ARG_POINTER(listener); NS_ENSURE_ARG_POINTER(listener);
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
@ -188,7 +191,7 @@ FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext)
mozilla::ipc::AutoIPCStream autoStream; mozilla::ipc::AutoIPCStream autoStream;
autoStream.Serialize(mUploadStream, autoStream.Serialize(mUploadStream,
static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager())); static_cast<ContentChild*>(gNeckoChild->Manager()));
FTPChannelOpenArgs openArgs; FTPChannelOpenArgs openArgs;
SerializeURI(nsBaseChannel::URI(), openArgs.uri()); SerializeURI(nsBaseChannel::URI(), openArgs.uri());
@ -873,6 +876,10 @@ FTPChannelChild::Resume()
NS_IMETHODIMP NS_IMETHODIMP
FTPChannelChild::ConnectParent(uint32_t id) FTPChannelChild::ConnectParent(uint32_t id)
{ {
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
NS_ENSURE_TRUE(!static_cast<ContentChild*>(gNeckoChild->Manager())->
IsShuttingDown(), NS_ERROR_FAILURE);
LOG(("FTPChannelChild::ConnectParent [this=%p]\n", this)); LOG(("FTPChannelChild::ConnectParent [this=%p]\n", this));
mozilla::dom::TabChild* tabChild = nullptr; mozilla::dom::TabChild* tabChild = nullptr;
@ -936,6 +943,8 @@ FTPChannelChild::DivertToParent(ChannelDiverterChild **aChild)
MOZ_RELEASE_ASSERT(aChild); MOZ_RELEASE_ASSERT(aChild);
MOZ_RELEASE_ASSERT(gNeckoChild); MOZ_RELEASE_ASSERT(gNeckoChild);
MOZ_RELEASE_ASSERT(!mDivertingToParent); MOZ_RELEASE_ASSERT(!mDivertingToParent);
NS_ENSURE_TRUE(!static_cast<ContentChild*>(gNeckoChild->Manager())->
IsShuttingDown(), NS_ERROR_FAILURE);
LOG(("FTPChannelChild::DivertToParent [this=%p]\n", this)); LOG(("FTPChannelChild::DivertToParent [this=%p]\n", this));

View file

@ -1823,6 +1823,11 @@ HttpChannelChild::ConnectParent(uint32_t registrarId)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
ContentChild* cc = static_cast<ContentChild*>(gNeckoChild->Manager());
if (cc->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
HttpBaseChannel::SetDocshellUserAgentOverride(); HttpBaseChannel::SetDocshellUserAgentOverride();
// The socket transport in the chrome process now holds a logical ref to us // The socket transport in the chrome process now holds a logical ref to us
@ -2665,6 +2670,9 @@ HttpChannelChild::OpenAlternativeOutputStream(const nsACString & aType, nsIOutpu
if (!mIPCOpen) { if (!mIPCOpen) {
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
} }
if (static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<AltDataOutputStreamChild> stream = RefPtr<AltDataOutputStreamChild> stream =
static_cast<AltDataOutputStreamChild*>(gNeckoChild->SendPAltDataOutputStreamConstructor(nsCString(aType), this)); static_cast<AltDataOutputStreamChild*>(gNeckoChild->SendPAltDataOutputStreamConstructor(nsCString(aType), this));
@ -2996,6 +3004,9 @@ HttpChannelChild::DivertToParent(ChannelDiverterChild **aChild)
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
if (static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
HttpChannelDiverterArgs args; HttpChannelDiverterArgs args;
args.mChannelChild() = this; args.mChannelChild() = this;

View file

@ -1 +1 @@
57e38a8407b3 29290a4a9bd0

View file

@ -0,0 +1,12 @@
Functions changes summary: 0 Removed, 0 Changed, 6 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
6 Added functions:
'function SECStatus CERT_GetCertIsPerm(const CERTCertificate*, PRBool*)' {CERT_GetCertIsPerm@@NSS_3.31}
'function SECStatus CERT_GetCertIsTemp(const CERTCertificate*, PRBool*)' {CERT_GetCertIsTemp@@NSS_3.31}
'function CERTCertificate* PK11_FindCertFromURI(const char*, void*)' {PK11_FindCertFromURI@@NSS_3.31}
'function CERTCertList* PK11_FindCertsFromURI(const char*, void*)' {PK11_FindCertsFromURI@@NSS_3.31}
'function char* PK11_GetModuleURI(SECMODModule*)' {PK11_GetModuleURI@@NSS_3.31}
'function char* PK11_GetTokenURI()' {PK11_GetTokenURI@@NSS_3.31}

View file

@ -0,0 +1,12 @@
Functions changes summary: 0 Removed, 0 Changed, 6 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
6 Added functions:
'function void PK11URI_CreateURI(size_t, size_t)' {PK11URI_CreateURI@@NSSUTIL_3.31}
'function void PK11URI_DestroyURI()' {PK11URI_DestroyURI@@NSSUTIL_3.31}
'function char* PK11URI_FormatURI()' {PK11URI_FormatURI@@NSSUTIL_3.31}
'function const char* PK11URI_GetPathAttribute(const char*)' {PK11URI_GetPathAttribute@@NSSUTIL_3.31}
'function const char* PK11URI_GetQueryAttribute(const char*)' {PK11URI_GetQueryAttribute@@NSSUTIL_3.31}
'function void PK11URI_ParseURI(const char*)' {PK11URI_ParseURI@@NSSUTIL_3.31}

View file

@ -0,0 +1,14 @@
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C]'function SECStatus SSL_GetPreliminaryChannelInfo(SSLPreliminaryChannelInfo*, PRUintn)' at sslinfo.c:115:1 has some indirect sub-type changes:
parameter 1 of type 'SSLPreliminaryChannelInfo*' has sub-type changes:
in pointed to type 'typedef SSLPreliminaryChannelInfo' at sslt.h:318:1:
underlying type 'struct SSLPreliminaryChannelInfoStr' at sslt.h:287:1 changed:
type size changed from 128 to 160 bits
1 data member insertion:
'PRUint32 SSLPreliminaryChannelInfoStr::maxEarlyDataSize', at offset 128 (in bits) at sslt.h:314:1

View file

@ -0,0 +1 @@
NSS_3_30_BRANCH

View file

@ -19,6 +19,9 @@ proc_args()
"--test-nss") "--test-nss")
TEST_NSS=1 TEST_NSS=1
;; ;;
"--check-abi")
CHECK_ABI=1
;;
"--build-jss") "--build-jss")
BUILD_JSS=1 BUILD_JSS=1
;; ;;
@ -40,6 +43,7 @@ proc_args()
echo " --build-jss" echo " --build-jss"
echo " --test-nss" echo " --test-nss"
echo " --test-jss" echo " --test-jss"
echo " --check-abi"
exit 1 exit 1
;; ;;
esac esac
@ -215,6 +219,65 @@ test_nss()
return ${RET} return ${RET}
} }
check_abi()
{
print_log "######## NSS ABI CHECK - ${BITS} bits - ${OPT} ########"
print_log "######## creating temporary HG clones ########"
rm -rf ${HGDIR}/baseline
mkdir ${HGDIR}/baseline
BASE_NSS=`cat ${HGDIR}/nss/automation/abi-check/previous-nss-release`
hg clone -u "${BASE_NSS}" "${HGDIR}/nss" "${HGDIR}/baseline/nss"
if [ $? -ne 0 ]; then
echo "invalid tag in automation/abi-check/previous-nss-release"
return 1
fi
BASE_NSPR=NSPR_$(head -1 ${HGDIR}/baseline/nss/automation/release/nspr-version.txt | cut -d . -f 1-2 | tr . _)_BRANCH
hg clone -u "${BASE_NSPR}" "${HGDIR}/nspr" "${HGDIR}/baseline/nspr"
if [ $? -ne 0 ]; then
echo "invalid tag ${BASE_NSPR} derived from ${BASE_NSS} automation/release/nspr-version.txt"
return 1
fi
print_log "######## building older NSPR/NSS ########"
pushd ${HGDIR}/baseline/nss
print_log "$ ${MAKE} ${NSS_BUILD_TARGET}"
${MAKE} ${NSS_BUILD_TARGET} 2>&1 | tee -a ${LOG_ALL}
RET=$?
print_result "NSS - build - ${BITS} bits - ${OPT}" ${RET} 0
if [ ${RET} -ne 0 ]; then
tail -100 ${LOG_ALL}
return ${RET}
fi
popd
ABI_REPORT=${OUTPUTDIR}/abi-diff.txt
rm -f ${ABI_REPORT}
PREVDIST=${HGDIR}/baseline/dist
NEWDIST=${HGDIR}/dist
ALL_SOs="libfreebl3.so libfreeblpriv3.so libnspr4.so libnss3.so libnssckbi.so libnssdbm3.so libnsssysinit.so libnssutil3.so libplc4.so libplds4.so libsmime3.so libsoftokn3.so libssl3.so"
for SO in ${ALL_SOs}; do
if [ ! -f nss/automation/abi-check/expected-report-$SO.txt ]; then
touch nss/automation/abi-check/expected-report-$SO.txt
fi
abidiff --hd1 $PREVDIST/public/ --hd2 $NEWDIST/public \
$PREVDIST/*/lib/$SO $NEWDIST/*/lib/$SO \
> nss/automation/abi-check/new-report-$SO.txt
diff -u nss/automation/abi-check/expected-report-$SO.txt \
nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT}
done
if [ -s ${ABI_REPORT} ]; then
print_log "FAILED: there are new unexpected ABI changes"
cat ${ABI_REPORT}
return 1
fi
return 0
}
test_jss() test_jss()
{ {
print_log "######## JSS - tests - ${BITS} bits - ${OPT} ########" print_log "######## JSS - tests - ${BITS} bits - ${OPT} ########"
@ -288,6 +351,11 @@ build_and_test()
[ $? -eq 0 ] || return 1 [ $? -eq 0 ] || return 1
fi fi
if [ -n "${CHECK_ABI}" ]; then
check_abi
[ $? -eq 0 ] || return 1
fi
if [ -n "${BUILD_JSS}" ]; then if [ -n "${BUILD_JSS}" ]; then
create_objdir_dist_link create_objdir_dist_link
build_jss build_jss
@ -360,6 +428,7 @@ main()
{ {
VALID=0 VALID=0
RET=1 RET=1
FAIL=0
for BITS in 32 64; do for BITS in 32 64; do
echo ${RUN_BITS} | grep ${BITS} > /dev/null echo ${RUN_BITS} | grep ${BITS} > /dev/null
@ -372,7 +441,10 @@ main()
set_env set_env
run_all run_all
RET=$? RET=$?
print_log "### result of run_all is ${RET}" print_log "### result of run_all is ${RET}"
if [ ${RET} -ne 0 ]; then
FAIL=${RET}
fi
done done
done done
@ -381,7 +453,7 @@ main()
return 1 return 1
fi fi
return ${RET} return ${FAIL}
} }
#function killallsub() #function killallsub()
@ -409,6 +481,8 @@ echo "tinderbox args: $0 $@"
proc_args "$@" proc_args "$@"
main main
#RET=$? RET=$?
print_log "### result of main is ${RET}"
#rm $IS_RUNNING_FILE #rm $IS_RUNNING_FILE
#exit ${RET} exit ${RET}

View file

@ -0,0 +1,10 @@
4.15
# The first line of this file must contain the human readable NSPR
# version number, which is the minimum required version of NSPR
# that is supported by this version of NSS.
#
# This information is used by release automation,
# when creating an NSS source archive.
#
# All other lines in this file are ignored.

View file

@ -171,11 +171,13 @@ def set_4_digit_release_number():
set_all_lib_versions(version, major, minor, patch, build) set_all_lib_versions(version, major, minor, patch, build)
def create_nss_release_archive(): def create_nss_release_archive():
ensure_arguments_after_action(4, "nss_release_version nss_hg_release_tag nspr_release_version path_to_stage_directory") ensure_arguments_after_action(3, "nss_release_version nss_hg_release_tag path_to_stage_directory")
nssrel = args[1].strip() #e.g. 3.19.3 nssrel = args[1].strip() #e.g. 3.19.3
nssreltag = args[2].strip() #e.g. NSS_3_19_3_RTM nssreltag = args[2].strip() #e.g. NSS_3_19_3_RTM
nsprrel = args[3].strip() #e.g. 4.10.8 stagedir = args[3].strip() #e.g. ../stage
stagedir = args[4].strip() #e.g. ../stage
with open('automation/release/nspr-version.txt') as nspr_version_file:
nsprrel = next(nspr_version_file).strip()
nspr_tar = "nspr-" + nsprrel + ".tar.gz" nspr_tar = "nspr-" + nsprrel + ".tar.gz"
nsprtar_with_path= stagedir + "/v" + nsprrel + "/src/" + nspr_tar nsprtar_with_path= stagedir + "/v" + nsprrel + "/src/" + nspr_tar

View file

@ -22,6 +22,10 @@ apt_packages+=('ninja-build')
apt_packages+=('pkg-config') apt_packages+=('pkg-config')
apt_packages+=('zlib1g-dev') apt_packages+=('zlib1g-dev')
# 32-bit builds
apt_packages+=('gcc-multilib')
apt_packages+=('g++-multilib')
# Latest Mercurial. # Latest Mercurial.
apt_packages+=('mercurial') apt_packages+=('mercurial')
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE
@ -31,6 +35,11 @@ echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" >
apt-get -y update apt-get -y update
apt-get install -y --no-install-recommends ${apt_packages[@]} apt-get install -y --no-install-recommends ${apt_packages[@]}
# 32-bit builds
dpkg --add-architecture i386
apt-get -y update
apt-get install -y --no-install-recommends libssl-dev:i386
# Install LLVM/clang-4.0. # Install LLVM/clang-4.0.
mkdir clang-tmp mkdir clang-tmp
git clone -n --depth 1 https://chromium.googlesource.com/chromium/src/tools/clang clang-tmp/clang git clone -n --depth 1 https://chromium.googlesource.com/chromium/src/tools/clang clang-tmp/clang

View file

@ -63,11 +63,6 @@ queue.filter(task => {
if (task.collection == "make") { if (task.collection == "make") {
return false; return false;
} }
// Disable mpi tests for now on 32-bit builds (bug 1362392)
if (task.platform == "linux32") {
return false;
}
} }
@ -168,6 +163,7 @@ export default async function main() {
}); });
await scheduleFuzzing(); await scheduleFuzzing();
await scheduleFuzzing32();
await scheduleTools(); await scheduleTools();
@ -415,6 +411,110 @@ async function scheduleFuzzing() {
return queue.submit(); return queue.submit();
} }
async function scheduleFuzzing32() {
let base = {
env: {
ASAN_OPTIONS: "allocator_may_return_null=1:detect_stack_use_after_return=1",
UBSAN_OPTIONS: "print_stacktrace=1",
NSS_DISABLE_ARENA_FREE_LIST: "1",
NSS_DISABLE_UNLOAD: "1",
CC: "clang",
CCC: "clang++"
},
features: ["allowPtrace"],
platform: "linux32",
collection: "fuzz",
image: FUZZ_IMAGE
};
// Build base definition.
let build_base = merge({
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && " +
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz -m32"
],
artifacts: {
public: {
expires: 24 * 7,
type: "directory",
path: "/home/worker/artifacts"
}
},
kind: "build",
symbol: "B"
}, base);
// The task that builds NSPR+NSS.
let task_build = queue.scheduleTask(merge(build_base, {
name: "Linux 32 (debug, fuzz)"
}));
// The task that builds NSPR+NSS (TLS fuzzing mode).
let task_build_tls = queue.scheduleTask(merge(build_base, {
name: "Linux 32 (debug, TLS fuzz)",
symbol: "B",
group: "TLS",
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && " +
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz=tls -m32"
],
}));
// Schedule tests.
queue.scheduleTask(merge(base, {
parent: task_build_tls,
name: "Gtests",
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh"
],
env: {GTESTFILTER: "*Fuzz*"},
tests: "ssl_gtests gtests",
cycle: "standard",
symbol: "Gtest",
kind: "test"
}));
// Schedule fuzzing runs.
let run_base = merge(base, {parent: task_build, kind: "test"});
scheduleFuzzingRun(run_base, "CertDN", "certDN", 4096);
scheduleFuzzingRun(run_base, "QuickDER", "quickder", 10000);
// Schedule MPI fuzzing runs.
let mpi_base = merge(run_base, {group: "MPI"});
let mpi_names = ["add", "addmod", "div", "expmod", "mod", "mulmod", "sqr",
"sqrmod", "sub", "submod"];
for (let name of mpi_names) {
scheduleFuzzingRun(mpi_base, `MPI (${name})`, `mpi-${name}`, 4096, name);
}
scheduleFuzzingRun(mpi_base, `MPI (invmod)`, `mpi-invmod`, 256, "invmod");
// Schedule TLS fuzzing runs (non-fuzzing mode).
let tls_base = merge(run_base, {group: "TLS"});
scheduleFuzzingRun(tls_base, "TLS Client", "tls-client", 20000, "client-nfm",
"tls-client-no_fuzzer_mode");
scheduleFuzzingRun(tls_base, "TLS Server", "tls-server", 20000, "server-nfm",
"tls-server-no_fuzzer_mode");
scheduleFuzzingRun(tls_base, "DTLS Client", "dtls-client", 20000,
"dtls-client-nfm", "dtls-client-no_fuzzer_mode");
scheduleFuzzingRun(tls_base, "DTLS Server", "dtls-server", 20000,
"dtls-server-nfm", "dtls-server-no_fuzzer_mode");
// Schedule TLS fuzzing runs (fuzzing mode).
let tls_fm_base = merge(tls_base, {parent: task_build_tls});
scheduleFuzzingRun(tls_fm_base, "TLS Client", "tls-client", 20000, "client");
scheduleFuzzingRun(tls_fm_base, "TLS Server", "tls-server", 20000, "server");
scheduleFuzzingRun(tls_fm_base, "DTLS Client", "dtls-client", 20000, "dtls-client");
scheduleFuzzingRun(tls_fm_base, "DTLS Server", "dtls-server", 20000, "dtls-server");
return queue.submit();
}
/*****************************************************************************/ /*****************************************************************************/
async function scheduleTestBuilds(base, args = "") { async function scheduleTestBuilds(base, args = "") {

View file

@ -23,7 +23,7 @@ function parseOptions(opts) {
// Parse platforms. // Parse platforms.
let allPlatforms = ["linux", "linux64", "linux64-asan", "win64", let allPlatforms = ["linux", "linux64", "linux64-asan", "win64",
"linux64-make", "linux-make", "linux64-fuzz", "aarch64"]; "linux64-make", "linux-make", "linux-fuzz", "linux64-fuzz", "aarch64"];
let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms); let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms);
// If the given value is nonsense or "none" default to all platforms. // If the given value is nonsense or "none" default to all platforms.
@ -104,6 +104,7 @@ function filter(opts) {
let found = opts.platforms.some(platform => { let found = opts.platforms.some(platform => {
let aliases = { let aliases = {
"linux": "linux32", "linux": "linux32",
"linux-fuzz": "linux32",
"linux64-asan": "linux64", "linux64-asan": "linux64",
"linux64-fuzz": "linux64", "linux64-fuzz": "linux64",
"linux64-make": "linux64", "linux64-make": "linux64",
@ -119,7 +120,7 @@ function filter(opts) {
keep &= coll("asan"); keep &= coll("asan");
} else if (platform == "linux64-make" || platform == "linux-make") { } else if (platform == "linux64-make" || platform == "linux-make") {
keep &= coll("make"); keep &= coll("make");
} else if (platform == "linux64-fuzz") { } else if (platform == "linux64-fuzz" || platform == "linux-fuzz") {
keep &= coll("fuzz"); keep &= coll("fuzz");
} else { } else {
keep &= coll("opt") || coll("debug"); keep &= coll("opt") || coll("debug");

View file

@ -1261,11 +1261,13 @@ DoChallengeResponse(SECKEYPrivateKey *privKey,
return 908; return 908;
} }
keyID = PK11_MakeIDFromPubKey(publicValue); keyID = PK11_MakeIDFromPubKey(publicValue);
SECITEM_FreeItem(publicValue, PR_TRUE);
if (keyID == NULL) { if (keyID == NULL) {
printf("Could not make the keyID from the public value\n"); printf("Could not make the keyID from the public value\n");
return 909; return 909;
} }
foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot, keyID, &pwdata); foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot, keyID, &pwdata);
SECITEM_FreeItem(keyID, PR_TRUE);
if (foundPrivKey == NULL) { if (foundPrivKey == NULL) {
printf("Could not find the private key corresponding to the public" printf("Could not find the private key corresponding to the public"
" value.\n"); " value.\n");

View file

@ -31,7 +31,18 @@
'include_dirs': [ 'include_dirs': [
'<(DEPTH)/lib/freebl/mpi', '<(DEPTH)/lib/freebl/mpi',
'<(DEPTH)/lib/util', '<(DEPTH)/lib/util',
] ],
# This uses test builds and has to set defines for MPI.
'conditions': [
[ 'target_arch=="ia32"', {
'defines': [
'MP_USE_UINT_DIGIT',
'MP_ASSEMBLY_MULTIPLY',
'MP_ASSEMBLY_SQUARE',
'MP_ASSEMBLY_DIV_2DX1D',
],
}],
],
}, },
'variables': { 'variables': {
'module': 'nss' 'module': 'nss'

View file

@ -10,4 +10,3 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

View file

@ -24,7 +24,10 @@ if [ "$fuzz_oss" = 1 ]; then
gyp_params+=(-Dno_zdefs=1 -Dfuzz_oss=1) gyp_params+=(-Dno_zdefs=1 -Dfuzz_oss=1)
else else
enable_sanitizer asan enable_sanitizer asan
enable_ubsan # Ubsan doesn't build on 32-bit at the moment. Disable it.
if [ "$build_64" = 1 ]; then
enable_ubsan
fi
enable_sancov enable_sancov
fi fi

View file

@ -88,6 +88,15 @@
'-lcrypto', '-lcrypto',
], ],
}], }],
# For test builds we have to set MPI defines.
[ 'target_arch=="ia32"', {
'defines': [
'MP_USE_UINT_DIGIT',
'MP_ASSEMBLY_MULTIPLY',
'MP_ASSEMBLY_SQUARE',
'MP_ASSEMBLY_DIV_2DX1D',
],
}],
], ],
}, },
}, },

View file

@ -29,13 +29,6 @@
'<(DEPTH)/lib/pki/pki.gyp:nsspki', '<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl', '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
], ],
'conditions': [
[ 'ct_verif==1', {
'defines': [
'CT_VERIF',
],
}],
],
}, },
{ {
'target_name': 'prng_gtest', 'target_name': 'prng_gtest',
@ -57,12 +50,38 @@
'<(DEPTH)/lib/pki/pki.gyp:nsspki', '<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl', '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
], ],
'conditions': [
[ 'OS=="win"', {
'libraries': [
'advapi32.lib',
],
}],
],
'defines': [
'NSS_USE_STATIC_LIBS'
],
}, },
], ],
'target_defaults': { 'target_defaults': {
'include_dirs': [ 'include_dirs': [
'<(DEPTH)/lib/freebl/mpi', '<(DEPTH)/lib/freebl/mpi',
] ],
# For test builds we have to set MPI defines.
'conditions': [
[ 'ct_verif==1', {
'defines': [
'CT_VERIF',
],
}],
[ 'target_arch=="ia32"', {
'defines': [
'MP_USE_UINT_DIGIT',
'MP_ASSEMBLY_MULTIPLY',
'MP_ASSEMBLY_SQUARE',
'MP_ASSEMBLY_DIV_2DX1D',
],
}],
],
}, },
'variables': { 'variables': {
'module': 'nss' 'module': 'nss'

View file

@ -53,13 +53,39 @@ class MPITest : public ::testing::Test {
mp_clear(&a); mp_clear(&a);
mp_clear(&b); mp_clear(&b);
} }
void TestDiv(const std::string a_string, const std::string b_string,
const std::string result) {
mp_int a, b, c;
MP_DIGITS(&a) = 0;
MP_DIGITS(&b) = 0;
MP_DIGITS(&c) = 0;
ASSERT_EQ(MP_OKAY, mp_init(&a));
ASSERT_EQ(MP_OKAY, mp_init(&b));
ASSERT_EQ(MP_OKAY, mp_init(&c));
mp_read_radix(&a, a_string.c_str(), 16);
mp_read_radix(&b, b_string.c_str(), 16);
mp_read_radix(&c, result.c_str(), 16);
EXPECT_EQ(MP_OKAY, mp_div(&a, &b, &a, &b));
EXPECT_EQ(0, mp_cmp(&a, &c));
mp_clear(&a);
mp_clear(&b);
mp_clear(&c);
}
}; };
TEST_F(MPITest, MpiCmp01Test) { TestCmp("0", "1", -1); } TEST_F(MPITest, MpiCmp01Test) { TestCmp("0", "1", -1); }
TEST_F(MPITest, MpiCmp10Test) { TestCmp("1", "0", 1); } TEST_F(MPITest, MpiCmp10Test) { TestCmp("1", "0", 1); }
TEST_F(MPITest, MpiCmp00Test) { TestCmp("0", "0", 0); } TEST_F(MPITest, MpiCmp00Test) { TestCmp("0", "0", 0); }
TEST_F(MPITest, MpiCmp11Test) { TestCmp("1", "1", 0); } TEST_F(MPITest, MpiCmp11Test) { TestCmp("1", "1", 0); }
TEST_F(MPITest, MpiDiv32ErrorTest) {
TestDiv("FFFF00FFFFFFFF000000000000", "FFFF00FFFFFFFFFF", "FFFFFFFFFF");
}
#ifdef NSS_X64
// This tests assumes 64-bit mp_digits.
TEST_F(MPITest, MpiCmpUnalignedTest) { TEST_F(MPITest, MpiCmpUnalignedTest) {
mp_int a, b, c; mp_int a, b, c;
MP_DIGITS(&a) = 0; MP_DIGITS(&a) = 0;
@ -90,6 +116,7 @@ TEST_F(MPITest, MpiCmpUnalignedTest) {
mp_clear(&b); mp_clear(&b);
mp_clear(&c); mp_clear(&c);
} }
#endif
// This test is slow. Disable it by default so we can run these tests on CI. // This test is slow. Disable it by default so we can run these tests on CI.
class DISABLED_MPITest : public ::testing::Test {}; class DISABLED_MPITest : public ::testing::Test {};

View file

@ -13,7 +13,7 @@
'sources': [ 'sources': [
'util_utf8_unittest.cc', 'util_utf8_unittest.cc',
'util_b64_unittest.cc', 'util_b64_unittest.cc',
'util_pkcs11uri_unittest.cc', 'util_pkcs11uri_unittest.cc',
'<(DEPTH)/gtests/common/gtests.cc', '<(DEPTH)/gtests/common/gtests.cc',
], ],
'dependencies': [ 'dependencies': [
@ -29,7 +29,17 @@
'<(DEPTH)/lib/dev/dev.gyp:nssdev', '<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/pki/pki.gyp:nsspki', '<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl', '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
] ],
'conditions': [
[ 'OS=="win"', {
'libraries': [
'advapi32.lib',
],
}],
],
'defines': [
'NSS_USE_STATIC_LIBS'
],
} }
], ],
'target_defaults': { 'target_defaults': {

View file

@ -31,13 +31,17 @@ class PK11URITest : public ::testing::Test {
size_t i; size_t i;
for (i = 0; i < num_pattrs; i++) { for (i = 0; i < num_pattrs; i++) {
const char *value = PK11URI_GetPathAttribute(tmp.get(), pattrs[i].name); const char *value = PK11URI_GetPathAttribute(tmp.get(), pattrs[i].name);
ASSERT_TRUE(value); EXPECT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(pattrs[i].value)); if (value) {
EXPECT_EQ(std::string(value), std::string(pattrs[i].value));
}
} }
for (i = 0; i < num_qattrs; i++) { for (i = 0; i < num_qattrs; i++) {
const char *value = PK11URI_GetQueryAttribute(tmp.get(), qattrs[i].name); const char *value = PK11URI_GetQueryAttribute(tmp.get(), qattrs[i].name);
ASSERT_TRUE(value); EXPECT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(qattrs[i].value)); if (value) {
EXPECT_EQ(std::string(value), std::string(qattrs[i].value));
}
} }
} }
@ -48,8 +52,10 @@ class PK11URITest : public ::testing::Test {
PK11URI_CreateURI(pattrs, num_pattrs, qattrs, num_qattrs)); PK11URI_CreateURI(pattrs, num_pattrs, qattrs, num_qattrs));
ASSERT_TRUE(tmp); ASSERT_TRUE(tmp);
char *out = PK11URI_FormatURI(nullptr, tmp.get()); char *out = PK11URI_FormatURI(nullptr, tmp.get());
ASSERT_TRUE(out); EXPECT_TRUE(out);
ASSERT_EQ(std::string(out), formatted); if (out) {
EXPECT_EQ(std::string(out), formatted);
}
PORT_Free(out); PORT_Free(out);
} }
@ -67,13 +73,17 @@ class PK11URITest : public ::testing::Test {
size_t i; size_t i;
for (i = 0; i < num_pattrs; i++) { for (i = 0; i < num_pattrs; i++) {
const char *value = PK11URI_GetPathAttribute(tmp.get(), pattrs[i].name); const char *value = PK11URI_GetPathAttribute(tmp.get(), pattrs[i].name);
ASSERT_TRUE(value); EXPECT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(pattrs[i].value)); if (value) {
EXPECT_EQ(std::string(value), std::string(pattrs[i].value));
}
} }
for (i = 0; i < num_qattrs; i++) { for (i = 0; i < num_qattrs; i++) {
const char *value = PK11URI_GetQueryAttribute(tmp.get(), qattrs[i].name); const char *value = PK11URI_GetQueryAttribute(tmp.get(), qattrs[i].name);
ASSERT_TRUE(value); EXPECT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(qattrs[i].value)); if (value) {
EXPECT_EQ(std::string(value), std::string(qattrs[i].value));
}
} }
} }
@ -81,9 +91,11 @@ class PK11URITest : public ::testing::Test {
ScopedPK11URI tmp(PK11URI_ParseURI(str.c_str())); ScopedPK11URI tmp(PK11URI_ParseURI(str.c_str()));
ASSERT_TRUE(tmp); ASSERT_TRUE(tmp);
char *out = PK11URI_FormatURI(nullptr, tmp.get()); char *out = PK11URI_FormatURI(nullptr, tmp.get());
ASSERT_TRUE(out); EXPECT_TRUE(out);
ASSERT_EQ(std::string(out), formatted); if (out) {
PORT_Free(out); EXPECT_EQ(std::string(out), formatted);
PORT_Free(out);
}
} }
protected: protected:

View file

@ -2859,6 +2859,9 @@ void
s_mp_exch(mp_int *a, mp_int *b) s_mp_exch(mp_int *a, mp_int *b)
{ {
mp_int tmp; mp_int tmp;
if (!a || !b) {
return;
}
tmp = *a; tmp = *a;
*a = *b; *a = *b;
@ -4086,7 +4089,7 @@ s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
} }
#endif #endif
#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) && !defined(MP_ASSEMBLY_DIV_2DX1D) #if !defined(MP_ASSEMBLY_DIV_2DX1D)
/* /*
** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized ** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
** so its high bit is 1. This code is from NSPR. ** so its high bit is 1. This code is from NSPR.
@ -4164,11 +4167,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
mp_int *quot) /* i: 0; o: quotient */ mp_int *quot) /* i: 0; o: quotient */
{ {
mp_int part, t; mp_int part, t;
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
mp_word q_msd;
#else
mp_digit q_msd; mp_digit q_msd;
#endif
mp_err res; mp_err res;
mp_digit d; mp_digit d;
mp_digit div_msd; mp_digit div_msd;
@ -4213,7 +4212,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
MP_USED(&part) = MP_USED(div); MP_USED(&part) = MP_USED(div);
/* We have now truncated the part of the remainder to the same length as /* We have now truncated the part of the remainder to the same length as
* the divisor. If part is smaller than div, extend part by one digit. */ * the divisor. If part is smaller than div, extend part by one digit. */
if (s_mp_cmp(&part, div) < 0) { if (s_mp_cmp(&part, div) < 0) {
--unusedRem; --unusedRem;
#if MP_ARGCHK == 2 #if MP_ARGCHK == 2
@ -4230,18 +4229,12 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
div_msd = MP_DIGIT(div, MP_USED(div) - 1); div_msd = MP_DIGIT(div, MP_USED(div) - 1);
if (!partExtended) { if (!partExtended) {
/* In this case, q_msd /= div_msd is always 1. First, since div_msd is /* In this case, q_msd /= div_msd is always 1. First, since div_msd is
* normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since
* we didn't extend part, q_msd >= div_msd. Therefore we know that * we didn't extend part, q_msd >= div_msd. Therefore we know that
* div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we
* get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */
q_msd = 1; q_msd = 1;
} else { } else {
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
q_msd /= div_msd;
if (q_msd == RADIX)
--q_msd;
#else
if (q_msd == div_msd) { if (q_msd == div_msd) {
q_msd = MP_DIGIT_MAX; q_msd = MP_DIGIT_MAX;
} else { } else {
@ -4249,7 +4242,6 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
MP_CHECKOK(s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), MP_CHECKOK(s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
div_msd, &q_msd, &r)); div_msd, &q_msd, &r));
} }
#endif
} }
#if MP_ARGCHK == 2 #if MP_ARGCHK == 2
assert(q_msd > 0); /* This case should never occur any more. */ assert(q_msd > 0); /* This case should never occur any more. */
@ -4259,15 +4251,15 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
/* See what that multiplies out to */ /* See what that multiplies out to */
mp_copy(div, &t); mp_copy(div, &t);
MP_CHECKOK(s_mp_mul_d(&t, (mp_digit)q_msd)); MP_CHECKOK(s_mp_mul_d(&t, q_msd));
/* /*
If it's too big, back it off. We should not have to do this If it's too big, back it off. We should not have to do this
more than once, or, in rare cases, twice. Knuth describes a more than once, or, in rare cases, twice. Knuth describes a
method by which this could be reduced to a maximum of once, but method by which this could be reduced to a maximum of once, but
I didn't implement that here. I didn't implement that here.
* When using s_mpv_div_2dx1d, we may have to do this 3 times. When using s_mpv_div_2dx1d, we may have to do this 3 times.
*/ */
for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) { for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
--q_msd; --q_msd;
MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */ MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */
@ -4282,11 +4274,11 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
s_mp_clamp(rem); s_mp_clamp(rem);
/* /*
Include the digit in the quotient. We allocated enough memory Include the digit in the quotient. We allocated enough memory
for any quotient we could ever possibly get, so we should not for any quotient we could ever possibly get, so we should not
have to check for failures here have to check for failures here
*/ */
MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd; MP_DIGIT(quot, unusedRem) = q_msd;
} }
/* Denormalize remainder */ /* Denormalize remainder */

View file

@ -765,7 +765,12 @@ find_certs_from_nickname(const char *nickname, void *wincx)
*delimit = ':'; *delimit = ':';
} else { } else {
slot = PK11_GetInternalKeySlot(); slot = PK11_GetInternalKeySlot();
token = nssToken_AddRef(PK11Slot_GetNSSToken(slot)); token = PK11Slot_GetNSSToken(slot);
if (token) {
nssToken_AddRef(token);
} else {
PORT_SetError(SEC_ERROR_NO_TOKEN);
}
} }
if (token) { if (token) {
nssList *certList; nssList *certList;

View file

@ -38,13 +38,6 @@
#include "zlib.h" #include "zlib.h"
#endif #endif
#ifndef PK11_SETATTRS
#define PK11_SETATTRS(x, id, v, l) \
(x)->type = (id); \
(x)->pValue = (v); \
(x)->ulValueLen = (l);
#endif
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo *serverKeySlot); PK11SlotInfo *serverKeySlot);
static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);

View file

@ -31,13 +31,6 @@
#include <stdio.h> #include <stdio.h>
#ifndef PK11_SETATTRS
#define PK11_SETATTRS(x, id, v, l) \
(x)->type = (id); \
(x)->pValue = (v); \
(x)->ulValueLen = (l);
#endif
SECStatus SECStatus
ssl_NamedGroup2ECParams(PLArenaPool *arena, const sslNamedGroupDef *ecGroup, ssl_NamedGroup2ECParams(PLArenaPool *arena, const sslNamedGroupDef *ecGroup,
SECKEYECParams *params) SECKEYECParams *params)

File diff suppressed because it is too large Load diff

View file

@ -305,13 +305,6 @@ typedef enum {
CLIENT_AUTH_CERTIFICATE = 1 CLIENT_AUTH_CERTIFICATE = 1
} ClientAuthenticationType; } ClientAuthenticationType;
typedef struct {
ClientAuthenticationType client_auth_type;
union {
SSL3Opaque *certificate_list;
} identity;
} ClientIdentity;
#define SESS_TICKET_KEY_NAME_LEN 16 #define SESS_TICKET_KEY_NAME_LEN 16
#define SESS_TICKET_KEY_NAME_PREFIX "NSS!" #define SESS_TICKET_KEY_NAME_PREFIX "NSS!"
#define SESS_TICKET_KEY_NAME_PREFIX_LEN 4 #define SESS_TICKET_KEY_NAME_PREFIX_LEN 4
@ -324,8 +317,4 @@ typedef struct {
unsigned char *mac; unsigned char *mac;
} EncryptedSessionTicket; } EncryptedSessionTicket;
#define TLS_EX_SESS_TICKET_MAC_LENGTH 32
#define TLS_STE_NO_SERVER_NAME -1
#endif /* __ssl3proto_h_ */ #endif /* __ssl3proto_h_ */

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