diff -Nru firefox-50.0.2+build1/addon-sdk/source/lib/sdk/event/chrome.js firefox-50.1.0+build2/addon-sdk/source/lib/sdk/event/chrome.js
--- firefox-50.0.2+build1/addon-sdk/source/lib/sdk/event/chrome.js 2016-11-30 08:51:00.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/lib/sdk/event/chrome.js 2016-12-09 08:27:44.000000000 +0000
@@ -57,7 +57,7 @@
// We need to remove any observer added once the add-on is unloaded;
// otherwise we'll get a "dead object" exception.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1001833
- unload(() => removeObserver(observerChannel, topic), { weak: true });
+ unload(() => removeObserver(observerChannel, topic));
return observerChannel;
}
diff -Nru firefox-50.0.2+build1/addon-sdk/source/lib/sdk/ui/frame/view.html firefox-50.1.0+build2/addon-sdk/source/lib/sdk/ui/frame/view.html
--- firefox-50.0.2+build1/addon-sdk/source/lib/sdk/ui/frame/view.html 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/lib/sdk/ui/frame/view.html 2016-12-09 08:27:44.000000000 +0000
@@ -1,18 +1,18 @@
-
+
+
+
+
+
+
+
diff -Nru firefox-50.0.2+build1/addon-sdk/source/lib/sdk/ui/frame/view.js firefox-50.1.0+build2/addon-sdk/source/lib/sdk/ui/frame/view.js
--- firefox-50.0.2+build1/addon-sdk/source/lib/sdk/ui/frame/view.js 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/lib/sdk/ui/frame/view.js 2016-12-09 08:27:44.000000000 +0000
@@ -63,20 +63,8 @@
view.setAttribute("id", id);
view.setAttribute("flex", 2);
- let innerFrame = document.createElementNS(HTML_NS, "iframe");
- innerFrame.setAttribute("id", id);
- innerFrame.setAttribute("src", url);
- innerFrame.setAttribute("seamless", "seamless");
- innerFrame.setAttribute("sandbox", "allow-scripts");
- innerFrame.setAttribute("scrolling", "no");
- innerFrame.setAttribute("data-is-sdk-inner-frame", true);
- innerFrame.setAttribute("style", [ "border:none",
- "position:absolute", "width:100%", "top: 0",
- "left: 0", "overflow: hidden"].join(";"));
-
let outerFrame = document.createElementNS(XUL_NS, "iframe");
- outerFrame.setAttribute("src", OUTER_FRAME_URI + "#" +
- encode(innerFrame.outerHTML));
+ outerFrame.setAttribute("src", OUTER_FRAME_URI);
outerFrame.setAttribute("id", "outer-" + id);
outerFrame.setAttribute("data-is-sdk-outer-frame", true);
outerFrame.setAttribute("type", "content");
@@ -86,6 +74,24 @@
outerFrame.setAttribute("scrolling", "no");
outerFrame.setAttribute("disablehistory", true);
outerFrame.setAttribute("seamless", "seamless");
+ outerFrame.addEventListener("load", function onload() {
+ outerFrame.removeEventListener("load", onload, true);
+
+ let doc = outerFrame.contentDocument;
+
+ let innerFrame = doc.createElementNS(HTML_NS, "iframe");
+ innerFrame.setAttribute("id", id);
+ innerFrame.setAttribute("src", url);
+ innerFrame.setAttribute("seamless", "seamless");
+ innerFrame.setAttribute("sandbox", "allow-scripts");
+ innerFrame.setAttribute("scrolling", "no");
+ innerFrame.setAttribute("data-is-sdk-inner-frame", true);
+ innerFrame.setAttribute("style", [ "border:none",
+ "position:absolute", "width:100%", "top: 0",
+ "left: 0", "overflow: hidden"].join(";"));
+
+ doc.body.appendChild(innerFrame);
+ }, true);
view.appendChild(outerFrame);
diff -Nru firefox-50.0.2+build1/addon-sdk/source/test/addons/jetpack-addon.ini firefox-50.1.0+build2/addon-sdk/source/test/addons/jetpack-addon.ini
--- firefox-50.0.2+build1/addon-sdk/source/test/addons/jetpack-addon.ini 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/test/addons/jetpack-addon.ini 2016-12-09 08:27:44.000000000 +0000
@@ -28,6 +28,7 @@
[page-mod-debugger-post.xpi]
[page-mod-debugger-pre.xpi]
[page-worker.xpi]
+skip-if = true # Bug 1288619 and Bug 1288708
[places.xpi]
[predefined-id-with-at.xpi]
[preferences-branch.xpi]
diff -Nru firefox-50.0.2+build1/addon-sdk/source/test/leak/jetpack-package.ini firefox-50.1.0+build2/addon-sdk/source/test/leak/jetpack-package.ini
--- firefox-50.0.2+build1/addon-sdk/source/test/leak/jetpack-package.ini 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/test/leak/jetpack-package.ini 2016-12-09 08:27:44.000000000 +0000
@@ -5,4 +5,3 @@
[test-leak-window-events.js]
[test-leak-event-dom-closed-window.js]
[test-leak-tab-events.js]
-[test-leak-event-chrome.js]
diff -Nru firefox-50.0.2+build1/addon-sdk/source/test/leak/leak-utils.js firefox-50.1.0+build2/addon-sdk/source/test/leak/leak-utils.js
--- firefox-50.0.2+build1/addon-sdk/source/test/leak/leak-utils.js 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/test/leak/leak-utils.js 2016-12-09 08:27:44.000000000 +0000
@@ -31,7 +31,6 @@
Cu.schedulePreciseGC(genGCCallback());
});
}
-exports.gc = gc;
// Execute the given test function and verify that we did not leak windows
// in the process. The test function must return a promise or be a generator.
diff -Nru firefox-50.0.2+build1/addon-sdk/source/test/leak/test-leak-event-chrome.js firefox-50.1.0+build2/addon-sdk/source/test/leak/test-leak-event-chrome.js
--- firefox-50.0.2+build1/addon-sdk/source/test/leak/test-leak-event-chrome.js 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/addon-sdk/source/test/leak/test-leak-event-chrome.js 1970-01-01 00:00:00.000000000 +0000
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { gc } = require("./leak-utils");
-const { Loader } = require("sdk/test/loader");
-const { Cu } = require("chrome");
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-
-exports["test sdk/event/chrome does not leak when not referenced"] = function*(assert) {
- let loader = Loader(module);
- let { observe } = loader.require("sdk/event/chrome");
- let { on } = loader.require("sdk/event/core");
-
- let gotFooEvent = false;
- on(observe("test-foo"), "data", function(evt) {
- gotFooEvent = true;
- });
-
- let bar = observe("test-bar");
- let barPromise = new Promise(resolve => {
- on(bar, "data", function(evt) {
- assert.ok(!gotFooEvent, "should not have gotten test-foo event");
- resolve();
- });
- });
-
- // This should clear the test-foo observer channel because we are not
- // holding a reference to it above.
- yield gc();
-
- Services.obs.notifyObservers(null, "test-foo", null);
- Services.obs.notifyObservers(null, "test-bar", null);
-
- yield barPromise;
-
- loader.unload();
-}
-
-require("sdk/test").run(exports);
diff -Nru firefox-50.0.2+build1/browser/app/blocklist.xml firefox-50.1.0+build2/browser/app/blocklist.xml
--- firefox-50.0.2+build1/browser/app/blocklist.xml 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/browser/app/blocklist.xml 2016-12-09 08:27:44.000000000 +0000
@@ -1,5 +1,5 @@
-
+
@@ -21,6 +21,13 @@
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
@@ -29,13 +36,6 @@
-
-
- browser.startup.homepage
- browser.search.defaultenginename
-
-
-
@@ -88,18 +88,18 @@
-
+
-
+
-
+
-
+
@@ -137,22 +137,14 @@
-
-
-
-
-
+
-
-
-
-
@@ -161,11 +153,15 @@
-
+
-
+
+
+
+
+
@@ -173,6 +169,10 @@
+
+
+
+
@@ -207,14 +207,14 @@
-
-
-
-
+
+
+
+
@@ -283,17 +283,17 @@
-
+
-
+
-
+
-
+
@@ -303,6 +303,10 @@
+
+
+
+
@@ -311,10 +315,6 @@
-
-
-
-
@@ -323,11 +323,15 @@
+
+
+
+
-
+
@@ -335,14 +339,18 @@
-
-
-
-
+
+
+
+
+
+
+
+
@@ -351,28 +359,20 @@
-
+
-
-
-
-
-
-
-
-
-
+
-
+
@@ -400,11 +400,11 @@
-
+
-
+
@@ -416,14 +416,14 @@
-
-
-
-
+
+
+
+
@@ -444,6 +444,10 @@
+
+
+
+
@@ -452,10 +456,6 @@
-
-
-
-
@@ -479,11 +479,11 @@
-
+
-
+
@@ -529,15 +529,15 @@
-
+
-
+
-
+
-
+
@@ -545,9 +545,9 @@
-
+
-
+
@@ -630,14 +630,14 @@
-
-
-
-
+
+
+
+
@@ -662,19 +662,23 @@
-
+
-
+
+
+
+
+
-
+
@@ -686,10 +690,6 @@
-
-
-
-
@@ -702,23 +702,23 @@
-
-
-
-
+
+
+
+
-
+
-
+
@@ -730,14 +730,14 @@
-
-
-
-
+
+
+
+
@@ -750,26 +750,26 @@
-
-
-
-
-
+
-
+
-
+
+
+
+
+
@@ -787,6 +787,10 @@
+
+
+
+
browser.startup.homepage
@@ -794,10 +798,6 @@
-
-
-
-
@@ -814,6 +814,10 @@
+
+
+
+
@@ -822,10 +826,6 @@
-
-
-
-
@@ -844,6 +844,10 @@
+
+
+
+
browser.startup.homepage
@@ -855,7 +859,16 @@
-
+
+
+ browser.startup.homepage
+
+
+
+
+
+
+
@@ -867,47 +880,34 @@
-
-
- browser.startup.homepage
-
-
-
-
+
-
+
-
+
+
-
-
-
-
-
+
-
+
-
+
-
+
-
-
-
-
@@ -929,6 +929,10 @@
+
+
+
+
@@ -937,10 +941,14 @@
-
+
+
+
+
+
browser.startup.homepage
@@ -948,37 +956,29 @@
-
+
-
+
+
+
+
+
-
+
-
+
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
@@ -987,6 +987,10 @@
+
+
+
+
browser.startup.homepage
@@ -994,18 +998,14 @@
-
+
-
+
-
-
-
-
@@ -1037,15 +1037,15 @@
-
+
-
+
-
+
@@ -1069,16 +1069,19 @@
-
+
+
-
+
+
+
+
-
@@ -1088,9 +1091,6 @@
-
-
-
@@ -1138,7 +1138,18 @@
-
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
@@ -1149,21 +1160,13 @@
-
+
browser.startup.homepage
browser.search.defaultenginename
-
-
-
-
-
-
-
-
@@ -1173,22 +1176,23 @@
-
-
- browser.startup.homepage
- browser.search.defaultenginename
-
+
+
+
+
+
+
-
+
@@ -1200,10 +1204,6 @@
-
-
-
-
@@ -1212,14 +1212,6 @@
-
-
-
-
-
-
-
-
browser.startup.homepage
@@ -1231,6 +1223,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1239,10 +1243,6 @@
-
-
-
-
@@ -1289,19 +1289,15 @@
-
-
-
-
-
+
-
+
-
+
@@ -1313,6 +1309,14 @@
+
+
+
+
+
+
+
+
browser.startup.homepage
@@ -1320,10 +1324,6 @@
-
-
-
-
@@ -1364,6 +1364,14 @@
+
+
+
+
+
+
+
+
@@ -1372,18 +1380,10 @@
-
-
-
-
-
-
-
-
@@ -1392,11 +1392,11 @@
-
+
-
+
@@ -1423,12 +1423,12 @@
-
+
-
-
+
+
@@ -1450,6 +1450,10 @@
+
+
+
+
@@ -1458,10 +1462,6 @@
-
-
-
-
@@ -1536,14 +1536,14 @@
-
-
-
-
+
+
+
+
@@ -1572,14 +1572,14 @@
-
-
-
-
+
+
+
+
@@ -1592,17 +1592,17 @@
-
+
-
+
-
+
-
+
@@ -1616,11 +1616,11 @@
-
+
-
+
@@ -1643,10 +1643,6 @@
-
-
-
-
browser.startup.homepage
@@ -1654,6 +1650,10 @@
+
+
+
+
@@ -1687,11 +1687,15 @@
+
+
+
+
-
+
@@ -1699,17 +1703,17 @@
-
+
-
+
-
+
-
+
@@ -1717,7 +1721,7 @@
-
+
@@ -1725,10 +1729,6 @@
-
-
-
-
@@ -1745,6 +1745,14 @@
+
+
+
+
+
+
+
+
@@ -1753,22 +1761,14 @@
-
-
-
-
-
+
-
+
-
-
-
-
@@ -1801,6 +1801,10 @@
+
+
+
+
@@ -1813,10 +1817,6 @@
-
-
-
-
@@ -1865,14 +1865,14 @@
-
-
-
-
+
+
+
+
@@ -1881,6 +1881,10 @@
+
+
+
+
@@ -1889,29 +1893,25 @@
-
-
-
-
-
+
-
+
+
+
+
+
-
+
-
+
-
+
-
-
-
-
-
+
@@ -1948,10 +1948,6 @@
-
-
-
-
@@ -1960,15 +1956,19 @@
+
+
+
+
-
+
-
+
@@ -2102,6 +2102,11 @@
https://get.adobe.com/flashplayer/
+
+
+ https://get.adobe.com/flashplayer/
+
+
@@ -2151,6 +2156,11 @@
+
+
+ https://get.adobe.com/flashplayer/
+
+
@@ -3417,9 +3427,6 @@
-
- Os2rnHWYhryvdOXfgan06A==
-
d8AtKymQwkOPDBj+hjPzFg==
@@ -3699,9 +3706,6 @@
Cfk9lw==
-
- U3t2Vk8pfxTcaUPpIq0seQ==
-
EqthLKdUgwI=
@@ -3714,9 +3718,6 @@
M64Z5ufZzDRVTHkJR1uXzw==
-
- RurwlgVMxeP6Zepun0LGZA==
-
BAAAAAABGMGjftY=
diff -Nru firefox-50.0.2+build1/browser/base/content/test/general/browser_web_channel.js firefox-50.1.0+build2/browser/base/content/test/general/browser_web_channel.js
--- firefox-50.0.2+build1/browser/base/content/test/general/browser_web_channel.js 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/browser/base/content/test/general/browser_web_channel.js 2016-12-09 08:27:44.000000000 +0000
@@ -37,6 +37,26 @@
}
},
{
+ desc: "WebChannel generic message in a private window.",
+ run: function* () {
+ let promiseTestDone = new Promise(function(resolve, reject) {
+ let channel = new WebChannel("generic", Services.io.newURI(HTTP_PATH, null, null));
+ channel.listen(function(id, message, target) {
+ is(id, "generic");
+ is(message.something.nested, "hello");
+ channel.stopListening();
+ resolve();
+ });
+ });
+
+ const url = HTTP_PATH + HTTP_ENDPOINT + "?generic";
+ let privateWindow = yield BrowserTestUtils.openNewBrowserWindow({private: true});
+ yield BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, url);
+ yield promiseTestDone;
+ yield BrowserTestUtils.closeWindow(privateWindow);
+ }
+ },
+ {
desc: "WebChannel two way communication",
run: function* () {
return new Promise(function(resolve, reject) {
diff -Nru firefox-50.0.2+build1/browser/config/version_display.txt firefox-50.1.0+build2/browser/config/version_display.txt
--- firefox-50.0.2+build1/browser/config/version_display.txt 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/browser/config/version_display.txt 2016-12-09 08:27:45.000000000 +0000
@@ -1 +1 @@
-50.0.2
+50.1.0
diff -Nru firefox-50.0.2+build1/browser/config/version.txt firefox-50.1.0+build2/browser/config/version.txt
--- firefox-50.0.2+build1/browser/config/version.txt 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/browser/config/version.txt 2016-12-09 08:27:45.000000000 +0000
@@ -1 +1 @@
-50.0.2
+50.1.0
diff -Nru firefox-50.0.2+build1/browser/extensions/pocket/content/main.js firefox-50.1.0+build2/browser/extensions/pocket/content/main.js
--- firefox-50.0.2+build1/browser/extensions/pocket/content/main.js 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/browser/extensions/pocket/content/main.js 2016-12-09 08:27:46.000000000 +0000
@@ -366,14 +366,19 @@
// send our own "show" event to the panel's script, so the
// script can prepare the panel for display.
var _showMessageId = "show";
- pktUIMessaging.addMessageListener(_showMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _showMessageId, function(panelId, data) {
// Let panel know that it is ready
pktUIMessaging.sendMessageToPanel(panelId, _showMessageId);
});
// Open a new tab with a given url and activate if
var _openTabWithUrlMessageId = "openTabWithUrl";
- pktUIMessaging.addMessageListener(_openTabWithUrlMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _openTabWithUrlMessageId, function(panelId, data, contentPrincipal) {
+ try {
+ urlSecurityCheck(data.url, contentPrincipal, Services.scriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
+ } catch (ex) {
+ return;
+ }
// Check if the tab should become active after opening
var activate = true;
@@ -388,39 +393,39 @@
// Close the panel
var _closeMessageId = "close";
- pktUIMessaging.addMessageListener(_closeMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _closeMessageId, function(panelId, data) {
getPanel().hidePopup();
});
// Send the current url to the panel
var _getCurrentURLMessageId = "getCurrentURL";
- pktUIMessaging.addMessageListener(_getCurrentURLMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _getCurrentURLMessageId, function(panelId, data) {
pktUIMessaging.sendResponseMessageToPanel(panelId, _getCurrentURLMessageId, getCurrentUrl());
});
var _resizePanelMessageId = "resizePanel";
- pktUIMessaging.addMessageListener(_resizePanelMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _resizePanelMessageId, function(panelId, data) {
resizePanel(data);
});
// Callback post initialization to tell background script that panel is "ready" for communication.
- pktUIMessaging.addMessageListener("listenerReady", function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, "listenerReady", function(panelId, data) {
});
- pktUIMessaging.addMessageListener("collapseSavePanel", function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, "collapseSavePanel", function(panelId, data) {
if (!pktApi.isPremiumUser() && !isInOverflowMenu())
resizePanel({width:savePanelWidth, height:savePanelHeights.collapsed});
});
- pktUIMessaging.addMessageListener("expandSavePanel", function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, "expandSavePanel", function(panelId, data) {
if (!isInOverflowMenu())
resizePanel({width:savePanelWidth, height:savePanelHeights.expanded});
});
// Ask for recently accessed/used tags for auto complete
var _getTagsMessageId = "getTags";
- pktUIMessaging.addMessageListener(_getTagsMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _getTagsMessageId, function(panelId, data) {
pktApi.getTags(function(tags, usedTags) {
pktUIMessaging.sendResponseMessageToPanel(panelId, _getTagsMessageId, {
tags: tags,
@@ -431,7 +436,7 @@
// Ask for suggested tags based on passed url
var _getSuggestedTagsMessageId = "getSuggestedTags";
- pktUIMessaging.addMessageListener(_getSuggestedTagsMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _getSuggestedTagsMessageId, function(panelId, data) {
pktApi.getSuggestedTagsForURL(data.url, {
success: function(data, response) {
var suggestedTags = data.suggested_tags;
@@ -451,7 +456,7 @@
// Pass url and array list of tags, add to existing save item accordingly
var _addTagsMessageId = "addTags";
- pktUIMessaging.addMessageListener(_addTagsMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _addTagsMessageId, function(panelId, data) {
pktApi.addTagsToURL(data.url, data.tags, {
success: function(data, response) {
var successResponse = {status: "success"};
@@ -465,7 +470,7 @@
// Based on clicking "remove page" CTA, and passed unique item id, remove the item
var _deleteItemMessageId = "deleteItem";
- pktUIMessaging.addMessageListener(_deleteItemMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _deleteItemMessageId, function(panelId, data) {
pktApi.deleteItem(data.itemId, {
success: function(data, response) {
var successResponse = {status: "success"};
@@ -478,7 +483,7 @@
});
var _initL10NMessageId = "initL10N";
- pktUIMessaging.addMessageListener(_initL10NMessageId, function(panelId, data) {
+ pktUIMessaging.addMessageListener(iframe, _initL10NMessageId, function(panelId, data) {
var strings = {};
var bundle = Services.strings.createBundle("chrome://pocket/locale/pocket.properties");
var e = bundle.getSimpleEnumeration();
@@ -627,10 +632,11 @@
/**
* Register a listener and callback for a specific messageId
*/
- function addMessageListener(messageId, callback) {
- document.addEventListener(prefixedMessageId(messageId), function(e) {
+ function addMessageListener(iframe, messageId, callback) {
+ iframe.addEventListener(prefixedMessageId(messageId), function(e) {
+ var nodePrincipal = e.target.nodePrincipal;
// ignore to ensure we do not pick up other events in the browser
- if (e.target.tagName !== 'PKTMESSAGEFROMPANELELEMENT') {
+ if (!nodePrincipal || !nodePrincipal.URI || !nodePrincipal.URI.spec.startsWith("about:pocket")) {
return;
}
@@ -638,7 +644,7 @@
var payload = JSON.parse(e.target.getAttribute("payload"))[0];
var panelId = payload.panelId;
var data = payload.data;
- callback(panelId, data);
+ callback(panelId, data, nodePrincipal);
// Cleanup the element
e.target.parentNode.removeChild(e.target);
@@ -647,14 +653,6 @@
}
/**
- * Remove a message listener
- */
- function removeMessageListener(messageId, callback) {
- document.removeEventListener(prefixedMessageId(messageId), callback);
- }
-
-
- /**
* Send a message to the panel's iframe
*/
function sendMessageToPanel(panelId, messageId, payload) {
@@ -751,7 +749,6 @@
*/
return {
addMessageListener: addMessageListener,
- removeMessageListener: removeMessageListener,
sendMessageToPanel: sendMessageToPanel,
sendResponseMessageToPanel: sendResponseMessageToPanel,
sendErrorMessageToPanel: sendErrorMessageToPanel,
diff -Nru firefox-50.0.2+build1/browser/extensions/pocket/content/panels/js/saved.js firefox-50.1.0+build2/browser/extensions/pocket/content/panels/js/saved.js
--- firefox-50.0.2+build1/browser/extensions/pocket/content/panels/js/saved.js 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/browser/extensions/pocket/content/panels/js/saved.js 2016-12-09 08:27:46.000000000 +0000
@@ -31,7 +31,9 @@
var newtagleft = 0;
container.children().remove();
for (var i = 0; i < tags.length; i++) {
- var newtag = $('' + tags[i] + '');
+ var newtag = $('');
+ newtag.find('a').text(tags[i]);
+ newtag.addClass(tagclass);
container.append(newtag);
var templeft = newtag.position().left;
this.cxt_suggested_available++;
diff -Nru firefox-50.0.2+build1/browser/extensions/pocket/content/panels/js/vendor/jquery.tokeninput.min.js firefox-50.1.0+build2/browser/extensions/pocket/content/panels/js/vendor/jquery.tokeninput.min.js
--- firefox-50.0.2+build1/browser/extensions/pocket/content/panels/js/vendor/jquery.tokeninput.min.js 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/browser/extensions/pocket/content/panels/js/vendor/jquery.tokeninput.min.js 2016-12-09 08:27:46.000000000 +0000
@@ -49,8 +49,18 @@
idPrefix: "token-input-",
// Formatters
- resultsFormatter: function(item){ return "" + item[this.propertyToSearch]+ "" },
- tokenFormatter: function(item) { return "" + item[this.propertyToSearch] + "
" },
+ resultsFormatter: function(item) {
+ let listItem = document.createElement("li");
+ listItem.textContent = item[this.propertyToSearch];
+ return listItem.outerHTML;
+ },
+ tokenFormatter: function(item) {
+ let listItem = document.createElement("li");
+ let p = document.createElement("p");
+ p.textContent = item[this.propertyToSearch];
+ listItem.appendChild(p);
+ return listItem.outerHTML;
+ },
// Validations
validateItem: null,
diff -Nru firefox-50.0.2+build1/browser/installer/package-manifest.in firefox-50.1.0+build2/browser/installer/package-manifest.in
--- firefox-50.0.2+build1/browser/installer/package-manifest.in 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/browser/installer/package-manifest.in 2016-12-09 08:27:46.000000000 +0000
@@ -409,6 +409,8 @@
@RESPATH@/components/NetworkGeolocationProvider.manifest
@RESPATH@/components/NetworkGeolocationProvider.js
@RESPATH@/components/extensions.manifest
+@RESPATH@/components/EditorUtils.manifest
+@RESPATH@/components/EditorUtils.js
@RESPATH@/components/addonManager.js
@RESPATH@/components/amContentHandler.js
@RESPATH@/components/amInstallTrigger.js
diff -Nru firefox-50.0.2+build1/config/milestone.txt firefox-50.1.0+build2/config/milestone.txt
--- firefox-50.0.2+build1/config/milestone.txt 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/config/milestone.txt 2016-12-09 08:27:46.000000000 +0000
@@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
-50.0.2
+50.1.0
diff -Nru firefox-50.0.2+build1/debian/changelog firefox-50.1.0+build2/debian/changelog
--- firefox-50.0.2+build1/debian/changelog 2016-11-30 09:25:16.000000000 +0000
+++ firefox-50.1.0+build2/debian/changelog 2016-12-09 09:20:10.000000000 +0000
@@ -1,3 +1,10 @@
+firefox (50.1.0+build2-0ubuntu0.12.04.1) precise-security; urgency=medium
+
+ * New upstream stable release (50.1.0build2)
+ - see USN-3155-1
+
+ -- Chris Coulson Thu, 08 Dec 2016 20:50:24 +0000
+
firefox (50.0.2+build1-0ubuntu0.12.04.1) precise-security; urgency=medium
* New upstream stable release (50.0.2build1)
diff -Nru firefox-50.0.2+build1/devtools/client/netmonitor/netmonitor.css firefox-50.1.0+build2/devtools/client/netmonitor/netmonitor.css
--- firefox-50.0.2+build1/devtools/client/netmonitor/netmonitor.css 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/devtools/client/netmonitor/netmonitor.css 2016-12-09 08:27:47.000000000 +0000
@@ -44,6 +44,7 @@
@media (max-width: 700px) {
#toolbar-spacer,
#details-pane-toggle,
+ #details-pane.pane-collapsed,
.requests-menu-waterfall,
#requests-menu-network-summary-button > .toolbarbutton-text {
display: none;
diff -Nru firefox-50.0.2+build1/docshell/base/nsDocShell.cpp firefox-50.1.0+build2/docshell/base/nsDocShell.cpp
--- firefox-50.0.2+build1/docshell/base/nsDocShell.cpp 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/docshell/base/nsDocShell.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -8938,6 +8938,8 @@
nsSubDocumentFrame* subDocFrame =
do_QueryFrame(container->GetPrimaryFrame());
rootViewParent = subDocFrame ? subDocFrame->EnsureInnerView() : nullptr;
+ } else {
+ rootViewParent = nullptr;
}
if (sibling &&
sibling->GetShell() &&
diff -Nru firefox-50.0.2+build1/dom/base/Navigator.cpp firefox-50.1.0+build2/dom/base/Navigator.cpp
--- firefox-50.0.2+build1/dom/base/Navigator.cpp 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/dom/base/Navigator.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -2050,9 +2050,10 @@
return nullptr;
}
- // We pass ourself to RefreshVRDevices, so NotifyVRDevicesUpdated will
+ // We pass mWindow's id to RefreshVRDevices, so NotifyVRDevicesUpdated will
// be called asynchronously, resolving the promises in mVRGetDevicesPromises.
- if (!VRDevice::RefreshVRDevices(this)) {
+ nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
+ if (!VRDevice::RefreshVRDevices(win->WindowID())) {
p->MaybeReject(NS_ERROR_FAILURE);
return p.forget();
}
diff -Nru firefox-50.0.2+build1/dom/base/nsDataDocumentContentPolicy.cpp firefox-50.1.0+build2/dom/base/nsDataDocumentContentPolicy.cpp
--- firefox-50.0.2+build1/dom/base/nsDataDocumentContentPolicy.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/dom/base/nsDataDocumentContentPolicy.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -75,7 +75,12 @@
}
}
- if (doc->IsBeingUsedAsImage()) {
+ nsIDocument* docToCheckForImage = doc->GetDisplayDocument();
+ if (!docToCheckForImage) {
+ docToCheckForImage = doc;
+ }
+
+ if (docToCheckForImage->IsBeingUsedAsImage()) {
// We only allow SVG images to load content from URIs that are local and
// also satisfy one of the following conditions:
// - URI inherits security context, e.g. data URIs
diff -Nru firefox-50.0.2+build1/dom/base/nsDocument.cpp firefox-50.1.0+build2/dom/base/nsDocument.cpp
--- firefox-50.0.2+build1/dom/base/nsDocument.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/dom/base/nsDocument.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -13016,6 +13016,24 @@
return mSandboxFlags & SANDBOXED_SCRIPTS;
}
+bool
+nsIDocument::InlineScriptAllowedByCSP()
+{
+ nsCOMPtr csp;
+ nsresult rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
+ NS_ENSURE_SUCCESS(rv, true);
+ bool allowsInlineScript = true;
+ if (csp) {
+ nsresult rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
+ EmptyString(), // aNonce
+ EmptyString(), // FIXME get script sample (bug 1314567)
+ 0, // aLineNumber
+ &allowsInlineScript);
+ NS_ENSURE_SUCCESS(rv, true);
+ }
+ return allowsInlineScript;
+}
+
static bool
MightBeAboutOrChromeScheme(nsIURI* aURI)
{
diff -Nru firefox-50.0.2+build1/dom/base/nsIDocument.h firefox-50.1.0+build2/dom/base/nsIDocument.h
--- firefox-50.0.2+build1/dom/base/nsIDocument.h 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/dom/base/nsIDocument.h 2016-12-09 08:27:48.000000000 +0000
@@ -2791,6 +2791,8 @@
bool HasScriptsBlockedBySandbox();
+ bool InlineScriptAllowedByCSP();
+
void ReportHasScrollLinkedEffect();
bool HasScrollLinkedEffect() const
{
diff -Nru firefox-50.0.2+build1/dom/base/nsNodeUtils.cpp firefox-50.1.0+build2/dom/base/nsNodeUtils.cpp
--- firefox-50.0.2+build1/dom/base/nsNodeUtils.cpp 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/dom/base/nsNodeUtils.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -570,8 +570,13 @@
JSAutoCompartment ac(cx, wrapper);
rv = ReparentWrapper(cx, wrapper);
if (NS_FAILED(rv)) {
+ if (wasRegistered) {
+ aNode->OwnerDoc()->UnregisterActivityObserver(aNode->AsElement());
+ }
aNode->mNodeInfo.swap(newNodeInfo);
-
+ if (wasRegistered) {
+ aNode->OwnerDoc()->RegisterActivityObserver(aNode->AsElement());
+ }
return rv;
}
}
diff -Nru firefox-50.0.2+build1/dom/bindings/BindingUtils.h firefox-50.1.0+build2/dom/bindings/BindingUtils.h
--- firefox-50.0.2+build1/dom/bindings/BindingUtils.h 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/dom/bindings/BindingUtils.h 2016-12-09 08:27:49.000000000 +0000
@@ -2314,6 +2314,22 @@
AtomizeAndPinJSString(cx, *(vector[vector.length() - 1]).address(), name);
}
+// We use one constructor JSNative to represent all DOM interface objects (so
+// we can easily detect when we need to wrap them in an Xray wrapper). We store
+// the real JSNative in the mNative member of a JSNativeHolder in the
+// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a
+// specific interface object. We also store the NativeProperties in the
+// JSNativeHolder.
+// Note that some interface objects are not yet a JSFunction but a normal
+// JSObject with a DOMJSClass, those do not use these slots.
+
+enum {
+ CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0
+};
+
+bool
+Constructor(JSContext* cx, unsigned argc, JS::Value* vp);
+
// Implementation of the bits that XrayWrapper needs
/**
@@ -2387,6 +2403,9 @@
} else {
protop.set(JS::GetRealmObjectPrototype(cx));
}
+ } else if (JS_ObjectIsFunction(cx, obj)) {
+ MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
+ protop.set(JS::GetRealmFunctionPrototype(cx));
} else {
const js::Class* clasp = js::GetObjectClass(obj);
MOZ_ASSERT(IsDOMIfaceAndProtoClass(clasp));
@@ -2405,22 +2424,6 @@
extern const js::ObjectOps sInterfaceObjectClassObjectOps;
-// We use one constructor JSNative to represent all DOM interface objects (so
-// we can easily detect when we need to wrap them in an Xray wrapper). We store
-// the real JSNative in the mNative member of a JSNativeHolder in the
-// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a
-// specific interface object. We also store the NativeProperties in the
-// JSNativeHolder.
-// Note that some interface objects are not yet a JSFunction but a normal
-// JSObject with a DOMJSClass, those do not use these slots.
-
-enum {
- CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0
-};
-
-bool
-Constructor(JSContext* cx, unsigned argc, JS::Value* vp);
-
inline bool
UseDOMXray(JSObject* obj)
{
@@ -2437,7 +2440,7 @@
return JS_IsNativeFunction(obj, Constructor) ||
js::GetObjectClass(obj)->getConstruct();
}
- #endif
+#endif
// Helpers for creating a const version of a type.
template
diff -Nru firefox-50.0.2+build1/dom/bindings/test/chrome.ini firefox-50.1.0+build2/dom/bindings/test/chrome.ini
--- firefox-50.0.2+build1/dom/bindings/test/chrome.ini 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/dom/bindings/test/chrome.ini 2016-12-09 08:27:49.000000000 +0000
@@ -24,3 +24,4 @@
skip-if = e10s # prerendering doesn't work in e10s yet
[test_bug1123516_maplikesetlikechrome.xul]
skip-if = debug == false
+[test_bug1287912.html]
diff -Nru firefox-50.0.2+build1/dom/bindings/test/test_bug1287912.html firefox-50.1.0+build2/dom/bindings/test/test_bug1287912.html
--- firefox-50.0.2+build1/dom/bindings/test/test_bug1287912.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/dom/bindings/test/test_bug1287912.html 2016-12-09 08:27:49.000000000 +0000
@@ -0,0 +1,37 @@
+
+
+
+
+
+ Test for Bug 1287912
+
+
+
+
+Mozilla Bug 1287912
+
+
+
+
+
+
+
+
+
diff -Nru firefox-50.0.2+build1/dom/filesystem/tests/mochitest.ini firefox-50.1.0+build2/dom/filesystem/tests/mochitest.ini
--- firefox-50.0.2+build1/dom/filesystem/tests/mochitest.ini 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/dom/filesystem/tests/mochitest.ini 2016-12-09 08:27:45.000000000 +0000
@@ -7,3 +7,4 @@
[test_basic.html]
[test_webkitdirectory.html]
[test_worker_basic.html]
+[test_bug1319088.html]
diff -Nru firefox-50.0.2+build1/dom/filesystem/tests/test_bug1319088.html firefox-50.1.0+build2/dom/filesystem/tests/test_bug1319088.html
--- firefox-50.0.2+build1/dom/filesystem/tests/test_bug1319088.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/dom/filesystem/tests/test_bug1319088.html 2016-12-09 08:27:45.000000000 +0000
@@ -0,0 +1,66 @@
+
+
+
+ Test for bug 1319088
+
+
+
+
+
+
+
+
+
+
diff -Nru firefox-50.0.2+build1/dom/html/HTMLInputElement.cpp firefox-50.1.0+build2/dom/html/HTMLInputElement.cpp
--- firefox-50.0.2+build1/dom/html/HTMLInputElement.cpp 2016-11-30 08:51:02.000000000 +0000
+++ firefox-50.1.0+build2/dom/html/HTMLInputElement.cpp 2016-12-09 08:27:45.000000000 +0000
@@ -347,18 +347,7 @@
if (aArray[i].IsFile()) {
BlobImplOrDirectoryPath* data = mBlobImplsOrDirectoryPaths.AppendElement();
- RefPtr file = aArray[i].GetAsFile();
-
- nsAutoString name;
- file->GetName(name);
-
- nsAutoString path;
- path.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
- path.Append(name);
-
- file->SetPath(path);
-
- data->mBlobImpl = file->Impl();
+ data->mBlobImpl = aArray[i].GetAsFile()->Impl();
data->mType = BlobImplOrDirectoryPath::eBlobImpl;
} else {
MOZ_ASSERT(aArray[i].IsDirectory());
diff -Nru firefox-50.0.2+build1/dom/media/MediaDecoderReader.cpp firefox-50.1.0+build2/dom/media/MediaDecoderReader.cpp
--- firefox-50.0.2+build1/dom/media/MediaDecoderReader.cpp 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/MediaDecoderReader.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -237,9 +237,14 @@
}
ReaderQueue::Instance().Add(this);
+}
+nsresult
+MediaDecoderReader::Init()
+{
// Dispatch initialization that needs to happen on that task queue.
mTaskQueue->Dispatch(NewRunnableMethod(this, &MediaDecoderReader::InitializationTask));
+ return InitInternal();
}
void
diff -Nru firefox-50.0.2+build1/dom/media/MediaDecoderReader.h firefox-50.1.0+build2/dom/media/MediaDecoderReader.h
--- firefox-50.0.2+build1/dom/media/MediaDecoderReader.h 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/MediaDecoderReader.h 2016-12-09 08:27:46.000000000 +0000
@@ -100,7 +100,7 @@
// Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
// on failure.
- virtual nsresult Init() { return NS_OK; }
+ nsresult Init();
// Release media resources they should be released in dormant state
// The reader can be made usable again by calling ReadMetadata().
@@ -411,6 +411,8 @@
MediaEventProducer mOnMediaNotSeekable;
private:
+ virtual nsresult InitInternal() { return NS_OK; }
+
// Does any spinup that needs to happen on this task queue. This runs on a
// different thread than Init, and there should not be ordering dependencies
// between the two (even though in practice, Init will always run first right
diff -Nru firefox-50.0.2+build1/dom/media/MediaFormatReader.cpp firefox-50.1.0+build2/dom/media/MediaFormatReader.cpp
--- firefox-50.0.2+build1/dom/media/MediaFormatReader.cpp 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/MediaFormatReader.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -171,7 +171,7 @@
}
nsresult
-MediaFormatReader::Init()
+MediaFormatReader::InitInternal()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
diff -Nru firefox-50.0.2+build1/dom/media/MediaFormatReader.h firefox-50.1.0+build2/dom/media/MediaFormatReader.h
--- firefox-50.0.2+build1/dom/media/MediaFormatReader.h 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/MediaFormatReader.h 2016-12-09 08:27:46.000000000 +0000
@@ -34,8 +34,6 @@
virtual ~MediaFormatReader();
- nsresult Init() override;
-
size_t SizeOfVideoQueueInFrames() override;
size_t SizeOfAudioQueueInFrames() override;
@@ -103,6 +101,7 @@
void GetMozDebugReaderData(nsAString& aString);
private:
+ nsresult InitInternal() override;
bool HasVideo() const { return mVideo.mTrackDemuxer; }
bool HasAudio() const { return mAudio.mTrackDemuxer; }
diff -Nru firefox-50.0.2+build1/dom/media/MediaRecorder.cpp firefox-50.1.0+build2/dom/media/MediaRecorder.cpp
--- firefox-50.0.2+build1/dom/media/MediaRecorder.cpp 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/MediaRecorder.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -111,8 +111,22 @@
};
NS_IMPL_ISUPPORTS(MediaRecorderReporter, nsIMemoryReporter);
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaRecorder, DOMEventTargetHelper,
- mDOMStream, mAudioNode)
+NS_IMPL_CYCLE_COLLECTION_CLASS(MediaRecorder)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaRecorder,
+ DOMEventTargetHelper)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStream)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioNode)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaRecorder,
+ DOMEventTargetHelper)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStream)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioNode)
+ tmp->UnRegisterActivityObserver();
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaRecorder)
NS_INTERFACE_MAP_ENTRY(nsIDocumentActivity)
@@ -1011,9 +1025,9 @@
MediaRecorder::RegisterActivityObserver()
{
if (nsPIDOMWindowInner* window = GetOwner()) {
- nsIDocument* doc = window->GetExtantDoc();
- if (doc) {
- doc->RegisterActivityObserver(
+ mDocument = window->GetExtantDoc();
+ if (mDocument) {
+ mDocument->RegisterActivityObserver(
NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
}
}
@@ -1022,12 +1036,9 @@
void
MediaRecorder::UnRegisterActivityObserver()
{
- if (nsPIDOMWindowInner* window = GetOwner()) {
- nsIDocument* doc = window->GetExtantDoc();
- if (doc) {
- doc->UnregisterActivityObserver(
- NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
- }
+ if (mDocument) {
+ mDocument->UnregisterActivityObserver(
+ NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
}
}
diff -Nru firefox-50.0.2+build1/dom/media/MediaRecorder.h firefox-50.1.0+build2/dom/media/MediaRecorder.h
--- firefox-50.0.2+build1/dom/media/MediaRecorder.h 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/MediaRecorder.h 2016-12-09 08:27:46.000000000 +0000
@@ -148,6 +148,9 @@
// Hold the sessions reference and clean it when the DestroyRunnable for a
// session is running.
nsTArray > mSessions;
+
+ nsCOMPtr mDocument;
+
// It specifies the container format as well as the audio and video capture formats.
nsString mMimeType;
diff -Nru firefox-50.0.2+build1/dom/media/ogg/OggReader.cpp firefox-50.1.0+build2/dom/media/ogg/OggReader.cpp
--- firefox-50.0.2+build1/dom/media/ogg/OggReader.cpp 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/ogg/OggReader.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -164,7 +164,7 @@
}
}
-nsresult OggReader::Init() {
+nsresult OggReader::InitInternal() {
int ret = ogg_sync_init(&mOggState);
NS_ENSURE_TRUE(ret == 0, NS_ERROR_FAILURE);
return NS_OK;
diff -Nru firefox-50.0.2+build1/dom/media/ogg/OggReader.h firefox-50.1.0+build2/dom/media/ogg/OggReader.h
--- firefox-50.0.2+build1/dom/media/ogg/OggReader.h 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/ogg/OggReader.h 2016-12-09 08:27:46.000000000 +0000
@@ -32,7 +32,6 @@
~OggReader();
public:
- nsresult Init() override;
nsresult ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
TrackInfo::kVideoTrack)) override;
bool DecodeAudioData() override;
@@ -47,6 +46,8 @@
media::TimeIntervals GetBuffered() override;
private:
+ nsresult InitInternal() override;
+
bool HasAudio() {
return (mVorbisState != 0 && mVorbisState->mActive) ||
(mOpusState != 0 && mOpusState->mActive);
diff -Nru firefox-50.0.2+build1/dom/media/platforms/agnostic/VorbisDecoder.cpp firefox-50.1.0+build2/dom/media/platforms/agnostic/VorbisDecoder.cpp
--- firefox-50.0.2+build1/dom/media/platforms/agnostic/VorbisDecoder.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/platforms/agnostic/VorbisDecoder.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -156,7 +156,7 @@
const unsigned char* aData = aSample->Data();
size_t aLength = aSample->Size();
int64_t aOffset = aSample->mOffset;
- uint64_t aTstampUsecs = aSample->mTime;
+ int64_t aTstampUsecs = aSample->mTime;
int64_t aTotalFrames = 0;
MOZ_ASSERT(mPacketCount >= 3);
diff -Nru firefox-50.0.2+build1/dom/media/webrtc/MediaEngineWebRTCAudio.cpp firefox-50.1.0+build2/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
--- firefox-50.0.2+build1/dom/media/webrtc/MediaEngineWebRTCAudio.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/dom/media/webrtc/MediaEngineWebRTCAudio.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -820,16 +820,10 @@
while (mRegisteredHandles.Length()) {
MOZ_ASSERT(mState == kAllocated || mState == kStopped);
- Deallocate(nullptr); // XXX Extend concurrent constraints code to mics.
- }
-
- if (mState != kReleased) {
- FreeChannel();
- MOZ_ASSERT(sChannelsOpen > 0);
- if (--sChannelsOpen == 0) {
- DeInitEngine();
- }
+ // on last Deallocate(), FreeChannel()s and DeInit()s if all channels are released
+ Deallocate(mRegisteredHandles[0].get());
}
+ MOZ_ASSERT(mState == kReleased);
mAudioInput = nullptr;
}
diff -Nru firefox-50.0.2+build1/dom/plugins/base/nsJSNPRuntime.cpp firefox-50.1.0+build2/dom/plugins/base/nsJSNPRuntime.cpp
--- firefox-50.0.2+build1/dom/plugins/base/nsJSNPRuntime.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/dom/plugins/base/nsJSNPRuntime.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -1185,6 +1185,8 @@
}
return obj;
}
+
+ JSAutoCompartment ac(cx, obj);
if (!::JS_GetPrototype(cx, obj, &obj)) {
return nullptr;
}
diff -Nru firefox-50.0.2+build1/dom/security/test/csp/file_bug1312272.html firefox-50.1.0+build2/dom/security/test/csp/file_bug1312272.html
--- firefox-50.0.2+build1/dom/security/test/csp/file_bug1312272.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/dom/security/test/csp/file_bug1312272.html 2016-12-09 08:27:47.000000000 +0000
@@ -0,0 +1,13 @@
+
+
+
+
+
+ marquee inline script tests for Bug 1312272
+
+
+
+
+
+
diff -Nru firefox-50.0.2+build1/dom/security/test/csp/file_bug1312272.html^headers^ firefox-50.1.0+build2/dom/security/test/csp/file_bug1312272.html^headers^
--- firefox-50.0.2+build1/dom/security/test/csp/file_bug1312272.html^headers^ 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/dom/security/test/csp/file_bug1312272.html^headers^ 2016-12-09 08:27:47.000000000 +0000
@@ -0,0 +1 @@
+Content-Security-Policy: default-src *; script-src * 'unsafe-eval'
diff -Nru firefox-50.0.2+build1/dom/security/test/csp/file_bug1312272.js firefox-50.1.0+build2/dom/security/test/csp/file_bug1312272.js
--- firefox-50.0.2+build1/dom/security/test/csp/file_bug1312272.js 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/dom/security/test/csp/file_bug1312272.js 2016-12-09 08:27:47.000000000 +0000
@@ -0,0 +1,8 @@
+var m = document.getElementById("m");
+m.addEventListener("click", function() {
+ // this will trigger after onstart, obviously.
+ parent.postMessage('finish', '*');
+});
+console.log("finish-handler setup");
+m.click();
+console.log("clicked");
diff -Nru firefox-50.0.2+build1/dom/security/test/csp/mochitest.ini firefox-50.1.0+build2/dom/security/test/csp/mochitest.ini
--- firefox-50.0.2+build1/dom/security/test/csp/mochitest.ini 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/dom/security/test/csp/mochitest.ini 2016-12-09 08:27:47.000000000 +0000
@@ -22,6 +22,9 @@
file_bug885433_blocks.html^headers^
file_bug888172.html
file_bug888172.sjs
+ file_bug1312272.html
+ file_bug1312272.js
+ file_bug1312272.html^headers^
file_evalscript_main.js
file_evalscript_main_allowed.js
file_evalscript_main.html
@@ -279,3 +282,5 @@
[test_require_sri_meta.html]
[test_sendbeacon.html]
[test_upgrade_insecure_docwrite_iframe.html]
+[test_bug1312272.html]
+
diff -Nru firefox-50.0.2+build1/dom/security/test/csp/test_bug1312272.html firefox-50.1.0+build2/dom/security/test/csp/test_bug1312272.html
--- firefox-50.0.2+build1/dom/security/test/csp/test_bug1312272.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/dom/security/test/csp/test_bug1312272.html 2016-12-09 08:27:47.000000000 +0000
@@ -0,0 +1,32 @@
+
+
+
+
+
+ Test for bug 1312272
+
+
+
+
+
+
+
+
+
+
diff -Nru firefox-50.0.2+build1/dom/vr/VRDevice.cpp firefox-50.1.0+build2/dom/vr/VRDevice.cpp
--- firefox-50.0.2+build1/dom/vr/VRDevice.cpp 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/dom/vr/VRDevice.cpp 2016-12-09 08:27:49.000000000 +0000
@@ -22,10 +22,10 @@
namespace dom {
/*static*/ bool
-VRDevice::RefreshVRDevices(dom::Navigator* aNavigator)
+VRDevice::RefreshVRDevices(uint64_t aWindowId)
{
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- return vm && vm->RefreshVRDevicesWithCallback(aNavigator);
+ return vm && vm->RefreshVRDevicesWithCallback(aWindowId);
}
/*static*/ void
diff -Nru firefox-50.0.2+build1/dom/vr/VRDevice.h firefox-50.1.0+build2/dom/vr/VRDevice.h
--- firefox-50.0.2+build1/dom/vr/VRDevice.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/dom/vr/VRDevice.h 2016-12-09 08:27:49.000000000 +0000
@@ -201,7 +201,7 @@
VRDeviceType GetType() const { return mType; }
- static bool RefreshVRDevices(dom::Navigator* aNavigator);
+ static bool RefreshVRDevices(uint64_t aWindowId);
static void UpdateVRDevices(nsTArray >& aDevices,
nsISupports* aParent);
diff -Nru firefox-50.0.2+build1/dom/webidl/Document.webidl firefox-50.1.0+build2/dom/webidl/Document.webidl
--- firefox-50.0.2+build1/dom/webidl/Document.webidl 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/dom/webidl/Document.webidl 2016-12-09 08:27:49.000000000 +0000
@@ -438,9 +438,11 @@
};
// Extension to give chrome and XBL JS the ability to determine whether
-// the document is sandboxed without permission to run scripts.
+// the document is sandboxed without permission to run scripts
+// and whether inline scripts are blocked by the document's CSP.
partial interface Document {
[Func="IsChromeOrXBL"] readonly attribute boolean hasScriptsBlockedBySandbox;
+ [Func="IsChromeOrXBL"] readonly attribute boolean inlineScriptAllowedByCSP;
};
Document implements XPathEvaluator;
diff -Nru firefox-50.0.2+build1/editor/libeditor/HTMLEditor.cpp firefox-50.1.0+build2/editor/libeditor/HTMLEditor.cpp
--- firefox-50.0.2+build1/editor/libeditor/HTMLEditor.cpp 2016-11-30 08:51:08.000000000 +0000
+++ firefox-50.1.0+build2/editor/libeditor/HTMLEditor.cpp 2016-12-09 08:27:50.000000000 +0000
@@ -3222,6 +3222,27 @@
eInserted);
}
+bool
+HTMLEditor::IsInObservedSubtree(nsIDocument* aDocument,
+ nsIContent* aContainer,
+ nsIContent* aChild)
+{
+ if (!aChild) {
+ return false;
+ }
+
+ Element* root = GetRoot();
+ // To be super safe here, check both ChromeOnlyAccess and GetBindingParent.
+ // That catches (also unbound) native anonymous content, XBL and ShadowDOM.
+ if (root &&
+ (root->ChromeOnlyAccess() != aChild->ChromeOnlyAccess() ||
+ root->GetBindingParent() != aChild->GetBindingParent())) {
+ return false;
+ }
+
+ return !aChild->ChromeOnlyAccess() && !aChild->GetBindingParent();
+}
+
void
HTMLEditor::DoContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
@@ -3229,7 +3250,7 @@
int32_t aIndexInContainer,
InsertedOrAppended aInsertedOrAppended)
{
- if (!aChild) {
+ if (!IsInObservedSubtree(aDocument, aContainer, aChild)) {
return;
}
@@ -3277,6 +3298,10 @@
int32_t aIndexInContainer,
nsIContent* aPreviousSibling)
{
+ if (!IsInObservedSubtree(aDocument, aContainer, aChild)) {
+ return;
+ }
+
nsCOMPtr kungFuDeathGrip(this);
if (SameCOMIdentity(aChild, mRootElement)) {
diff -Nru firefox-50.0.2+build1/editor/libeditor/HTMLEditor.h firefox-50.1.0+build2/editor/libeditor/HTMLEditor.h
--- firefox-50.0.2+build1/editor/libeditor/HTMLEditor.h 2016-11-30 08:51:08.000000000 +0000
+++ firefox-50.1.0+build2/editor/libeditor/HTMLEditor.h 2016-12-09 08:27:50.000000000 +0000
@@ -939,6 +939,10 @@
int32_t& aMarginLeft,
int32_t& aMarginTop);
+ bool IsInObservedSubtree(nsIDocument* aDocument,
+ nsIContent* aContainer,
+ nsIContent* aChild);
+
// resizing
bool mIsObjectResizingEnabled;
bool mIsResizing;
diff -Nru firefox-50.0.2+build1/gfx/2d/DrawTargetRecording.cpp firefox-50.1.0+build2/gfx/2d/DrawTargetRecording.cpp
--- firefox-50.0.2+build1/gfx/2d/DrawTargetRecording.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/2d/DrawTargetRecording.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -245,7 +245,8 @@
mPattern =
new (mSurfPat) SurfacePattern(GetSourceSurface(surfPat->mSurface),
surfPat->mExtendMode, surfPat->mMatrix,
- surfPat->mSamplingFilter);
+ surfPat->mSamplingFilter,
+ surfPat->mSamplingRect);
return mPattern;
}
case PatternType::LINEAR_GRADIENT:
@@ -299,12 +300,13 @@
}
DrawTargetRecording::DrawTargetRecording(const DrawTargetRecording *aDT,
- const IntSize &aSize,
- SurfaceFormat aFormat)
+ DrawTarget *aSimilarDT)
: mRecorder(aDT->mRecorder)
- , mFinalDT(aDT->mFinalDT->CreateSimilarDrawTarget(aSize, aFormat))
+ , mFinalDT(aSimilarDT)
{
- mRecorder->RecordEvent(RecordedCreateSimilarDrawTarget(this, aSize, aFormat));
+ mRecorder->RecordEvent(RecordedCreateSimilarDrawTarget(this,
+ mFinalDT->GetSize(),
+ mFinalDT->GetFormat()));
mFormat = mFinalDT->GetFormat();
}
@@ -649,7 +651,14 @@
already_AddRefed
DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
- return MakeAndAddRef(this, aSize, aFormat);
+ RefPtr similarDT =
+ mFinalDT->CreateSimilarDrawTarget(aSize, aFormat);
+ if (!similarDT) {
+ return nullptr;
+ }
+
+ similarDT = new DrawTargetRecording(this, similarDT);
+ return similarDT.forget();
}
already_AddRefed
diff -Nru firefox-50.0.2+build1/gfx/2d/DrawTargetRecording.h firefox-50.1.0+build2/gfx/2d/DrawTargetRecording.h
--- firefox-50.0.2+build1/gfx/2d/DrawTargetRecording.h 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/2d/DrawTargetRecording.h 2016-12-09 08:27:44.000000000 +0000
@@ -19,16 +19,6 @@
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording, override)
DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData = false);
- /**
- * Used for creating a DrawTargetRecording for a CreateSimilarDrawTarget call.
- *
- * @param aDT DrawTargetRecording on which CreateSimilarDrawTarget was called
- * @param aSize size for the similar DrawTarget
- * @param aFormat format for the similar DrawTarget
- */
- DrawTargetRecording(const DrawTargetRecording *aDT, const IntSize &aSize,
- SurfaceFormat aFormat);
-
~DrawTargetRecording();
virtual DrawTargetType GetType() const override { return mFinalDT->GetType(); }
@@ -322,6 +312,17 @@
}
private:
+ /**
+ * Used for creating a DrawTargetRecording for a CreateSimilarDrawTarget call.
+ * We have to call CreateSimilarDrawTarget on mFinalDT up front and pass it in
+ * as it can fail.
+ *
+ * @param aDT DrawTargetRecording on which CreateSimilarDrawTarget was called
+ * @param aSimilarDT Similar DrawTarget created from aDT.mFinalDT.
+ */
+ DrawTargetRecording(const DrawTargetRecording *aDT,
+ DrawTarget *aSimilarDT);
+
Path *GetPathForPathRecording(const Path *aPath) const;
already_AddRefed EnsurePathStored(const Path *aPath);
void EnsurePatternDependenciesStored(const Pattern &aPattern);
diff -Nru firefox-50.0.2+build1/gfx/2d/Factory.cpp firefox-50.1.0+build2/gfx/2d/Factory.cpp
--- firefox-50.0.2+build1/gfx/2d/Factory.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/gfx/2d/Factory.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -434,7 +434,7 @@
}
if (!retVal) {
- gfxCriticalNote << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize << ", Data: " << hexa(aData) << ", Stride: " << aStride;
+ gfxCriticalNote << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize << ", Data: " << hexa((void *)aData) << ", Stride: " << aStride;
}
return retVal.forget();
diff -Nru firefox-50.0.2+build1/gfx/2d/RecordedEvent.cpp firefox-50.1.0+build2/gfx/2d/RecordedEvent.cpp
--- firefox-50.0.2+build1/gfx/2d/RecordedEvent.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/2d/RecordedEvent.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -282,6 +282,7 @@
store->mSamplingFilter = pat->mSamplingFilter;
store->mMatrix = pat->mMatrix;
store->mSurface = pat->mSurface;
+ store->mSamplingRect = pat->mSamplingRect;
return;
}
}
@@ -551,7 +552,8 @@
mPattern =
new (mSurfPat) SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface),
storage->mExtend, storage->mMatrix,
- storage->mSamplingFilter);
+ storage->mSamplingFilter,
+ storage->mSamplingRect);
return mPattern;
}
case PatternType::LINEAR_GRADIENT:
diff -Nru firefox-50.0.2+build1/gfx/2d/RecordedEvent.h firefox-50.1.0+build2/gfx/2d/RecordedEvent.h
--- firefox-50.0.2+build1/gfx/2d/RecordedEvent.h 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/2d/RecordedEvent.h 2016-12-09 08:27:44.000000000 +0000
@@ -24,10 +24,10 @@
// loss of backwards compatibility. Old streams will not work in a player
// using a newer major revision. And new streams will not work in a player
// using an older major revision.
-const uint16_t kMajorRevision = 4;
+const uint16_t kMajorRevision = 5;
// A change in minor revision means additions of new events. New streams will
// not play in older players.
-const uint16_t kMinorRevision = 1;
+const uint16_t kMinorRevision = 0;
struct ReferencePtr
{
@@ -141,6 +141,7 @@
SamplingFilter mSamplingFilter;
ReferencePtr mSurface;
Matrix mMatrix;
+ IntRect mSamplingRect;
};
struct PatternStorage
diff -Nru firefox-50.0.2+build1/gfx/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp firefox-50.1.0+build2/gfx/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp
--- firefox-50.0.2+build1/gfx/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/gfx/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -73,6 +73,10 @@
unsigned int maxVaryingVectors = static_cast(mRegisterMap.size());
+ if (varyingRows > maxVaryingVectors) {
+ return false;
+ }
+
// "For 2, 3 and 4 component variables packing is started using the 1st column of the 1st row.
// Variables are then allocated to successive rows, aligning them to the 1st column."
if (varyingColumns >= 2 && varyingColumns <= 4)
diff -Nru firefox-50.0.2+build1/gfx/skia/skia/src/effects/gradients/Sk4fGradientBase.cpp firefox-50.1.0+build2/gfx/skia/skia/src/effects/gradients/Sk4fGradientBase.cpp
--- firefox-50.0.2+build1/gfx/skia/skia/src/effects/gradients/Sk4fGradientBase.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/skia/skia/src/effects/gradients/Sk4fGradientBase.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -127,7 +127,13 @@
const Sk4f c4f0 = SkPM4f::FromPMColor(c0).to4f() * componentScale;
const Sk4f c4f1 = SkPM4f::FromPMColor(c1).to4f() * componentScale;
- const Sk4f dc4f = (c4f1 - c4f0) / (p1 - p0);
+
+ // Either p0 or p1 can be (-)inf for synthetic clamp edge intervals.
+ SkASSERT(SkScalarIsFinite(p0) || SkScalarIsFinite(p1));
+ const auto dp = p1 - p0;
+ // Clamp edge intervals are always zero-ramp.
+ SkASSERT(SkScalarIsFinite(dp) || fZeroRamp);
+ const Sk4f dc4f = SkScalarIsFinite(dp) ? (c4f1 - c4f0) / dp : 0;
c4f0.store(&fC0.fVec);
dc4f.store(&fDc.fVec);
@@ -218,7 +224,7 @@
// synthetic edge interval: -/+inf .. P0
const SkPMColor clamp_color = pack_color(shader.fOrigColors[first_index],
fColorsArePremul);
- const SkScalar clamp_pos = reverse ? SK_ScalarMax : SK_ScalarMin;
+ const SkScalar clamp_pos = reverse ? SK_ScalarInfinity : SK_ScalarNegativeInfinity;
fIntervals.emplace_back(clamp_color, clamp_pos,
clamp_color, first_pos,
componentScale);
@@ -245,7 +251,7 @@
// synthetic edge interval: Pn .. +/-inf
const SkPMColor clamp_color =
pack_color(shader.fOrigColors[last_index], fColorsArePremul);
- const SkScalar clamp_pos = reverse ? SK_ScalarMin : SK_ScalarMax;
+ const SkScalar clamp_pos = reverse ? SK_ScalarNegativeInfinity : SK_ScalarInfinity;
fIntervals.emplace_back(clamp_color, last_pos,
clamp_color, clamp_pos,
componentScale);
diff -Nru firefox-50.0.2+build1/gfx/skia/skia/src/effects/gradients/Sk4fLinearGradient.cpp firefox-50.1.0+build2/gfx/skia/skia/src/effects/gradients/Sk4fLinearGradient.cpp
--- firefox-50.0.2+build1/gfx/skia/skia/src/effects/gradients/Sk4fLinearGradient.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/skia/skia/src/effects/gradients/Sk4fLinearGradient.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -318,11 +318,16 @@
private:
void compute_interval_props(SkScalar t) {
- const Sk4f dC = DstTraits::load(fInterval->fDc);
- fCc = DstTraits::load(fInterval->fC0);
- fCc = fCc + dC * Sk4f(t);
- fDcDx = dC * fDx;
fZeroRamp = fIsVertical || fInterval->isZeroRamp();
+ fCc = DstTraits::load(fInterval->fC0);
+
+ if (fInterval->isZeroRamp()) {
+ fDcDx = 0;
+ } else {
+ const Sk4f dC = DstTraits::load(fInterval->fDc);
+ fCc = fCc + dC * Sk4f(t);
+ fDcDx = dC * fDx;
+ }
}
const Interval* next_interval(const Interval* i) const {
diff -Nru firefox-50.0.2+build1/gfx/skia/skia/src/gpu/GrResourceProvider.cpp firefox-50.1.0+build2/gfx/skia/skia/src/gpu/GrResourceProvider.cpp
--- firefox-50.0.2+build1/gfx/skia/skia/src/gpu/GrResourceProvider.cpp 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/gfx/skia/skia/src/gpu/GrResourceProvider.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -96,8 +96,11 @@
if (kDynamic_GrAccessPattern == accessPattern) {
// bin by pow2 with a reasonable min
- static const uint32_t MIN_SIZE = 1 << 12;
- size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
+ static const size_t MIN_SIZE = 1 << 12;
+ size_t allocSize = size > (1u << 31)
+ ? size_t(SkTMin(uint64_t(SIZE_MAX), uint64_t(GrNextPow2(uint32_t(uint64_t(size) >> 32))) << 32))
+ : size_t(GrNextPow2(uint32_t(size)));
+ allocSize = SkTMax(allocSize, MIN_SIZE);
GrScratchKey key;
GrBuffer::ComputeScratchKeyForDynamicBuffer(size, intendedType, &key);
diff -Nru firefox-50.0.2+build1/gfx/thebes/gfxUserFontSet.cpp firefox-50.1.0+build2/gfx/thebes/gfxUserFontSet.cpp
--- firefox-50.0.2+build1/gfx/thebes/gfxUserFontSet.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/gfx/thebes/gfxUserFontSet.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -635,6 +635,16 @@
SanitizeOpenTypeData(aFontData, aLength, saneLen, fontType);
if (!saneData) {
mFontSet->LogMessage(this, "rejected by sanitizer");
+ } else {
+ // Check whether saneData is a known OpenType format; it might be
+ // a TrueType Collection, which OTS would accept but we don't yet
+ // know how to handle. If so, discard.
+ if (gfxFontUtils::DetermineFontDataType(saneData, saneLen) !=
+ GFX_USERFONT_OPENTYPE) {
+ mFontSet->LogMessage(this, "not a supported OpenType format");
+ free((void*)saneData);
+ saneData = nullptr;
+ }
}
if (saneData) {
if (saneLen) {
diff -Nru firefox-50.0.2+build1/gfx/vr/ipc/VRManagerChild.cpp firefox-50.1.0+build2/gfx/vr/ipc/VRManagerChild.cpp
--- firefox-50.0.2+build1/gfx/vr/ipc/VRManagerChild.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/gfx/vr/ipc/VRManagerChild.cpp 2016-12-09 08:27:46.000000000 +0000
@@ -9,6 +9,7 @@
#include "VRManagerParent.h"
#include "VRDeviceProxy.h"
#include "VRDeviceProxyOrientationFallBack.h"
+#include "nsGlobalWindow.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/layers/CompositorThread.h" // for CompositorThread
#include "mozilla/dom/Navigator.h"
@@ -149,7 +150,16 @@
mDevices = devices;
- for (auto& nav: mNavigatorCallbacks) {
+ for (auto& windowId : mNavigatorCallbacks) {
+ nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(windowId);
+ if (!window) {
+ continue;
+ }
+ ErrorResult result;
+ dom::Navigator* nav = window->GetNavigator(result);
+ if (NS_WARN_IF(result.Failed())) {
+ continue;
+ }
nav->NotifyVRDevicesUpdated();
}
mNavigatorCallbacks.Clear();
@@ -183,11 +193,11 @@
}
bool
-VRManagerChild::RefreshVRDevicesWithCallback(dom::Navigator* aNavigator)
+VRManagerChild::RefreshVRDevicesWithCallback(uint64_t aWindowId)
{
bool success = SendRefreshDevices();
if (success) {
- mNavigatorCallbacks.AppendElement(aNavigator);
+ mNavigatorCallbacks.AppendElement(aWindowId);
}
return success;
}
diff -Nru firefox-50.0.2+build1/gfx/vr/ipc/VRManagerChild.h firefox-50.1.0+build2/gfx/vr/ipc/VRManagerChild.h
--- firefox-50.0.2+build1/gfx/vr/ipc/VRManagerChild.h 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/gfx/vr/ipc/VRManagerChild.h 2016-12-09 08:27:46.000000000 +0000
@@ -27,7 +27,7 @@
int GetInputFrameID();
bool GetVRDevices(nsTArray >& aDevices);
- bool RefreshVRDevicesWithCallback(dom::Navigator* aNavigator);
+ bool RefreshVRDevicesWithCallback(uint64_t aWindowId);
static void InitSameProcess();
static void InitWithGPUProcess(Endpoint&& aEndpoint);
@@ -52,7 +52,7 @@
private:
nsTArray > mDevices;
- nsTArray mNavigatorCallbacks;
+ nsTArray mNavigatorCallbacks;
int32_t mInputFrameID;
};
diff -Nru firefox-50.0.2+build1/gfx/vr/moz.build firefox-50.1.0+build2/gfx/vr/moz.build
--- firefox-50.0.2+build1/gfx/vr/moz.build 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/gfx/vr/moz.build 2016-12-09 08:27:46.000000000 +0000
@@ -14,6 +14,7 @@
]
LOCAL_INCLUDES += [
+ '/dom/base',
'/gfx/thebes',
]
diff -Nru firefox-50.0.2+build1/js/public/Id.h firefox-50.1.0+build2/js/public/Id.h
--- firefox-50.0.2+build1/js/public/Id.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/js/public/Id.h 2016-12-09 08:27:49.000000000 +0000
@@ -182,18 +182,6 @@
namespace js {
template <>
-struct DefaultHasher
-{
- typedef jsid Lookup;
- static HashNumber hash(jsid id) {
- return JSID_BITS(id);
- }
- static bool match(jsid id1, jsid id2) {
- return id1 == id2;
- }
-};
-
-template <>
struct BarrierMethods
{
static void postBarrier(jsid* idp, jsid prev, jsid next) {}
diff -Nru firefox-50.0.2+build1/js/src/builtin/MapObject.cpp firefox-50.1.0+build2/js/src/builtin/MapObject.cpp
--- firefox-50.0.2+build1/js/src/builtin/MapObject.cpp 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/js/src/builtin/MapObject.cpp 2016-12-09 08:27:49.000000000 +0000
@@ -63,13 +63,21 @@
return true;
}
-HashNumber
-HashableValue::hash() const
+static HashNumber
+HashValue(const Value& v)
{
// HashableValue::setValue normalizes values so that the SameValue relation
// on HashableValues is the same as the == relationship on
// value.data.asBits.
- return value.asRawBits();
+ if (v.isString())
+ return v.toString()->asAtom().hash();
+ return v.asRawBits();
+}
+
+HashNumber
+HashableValue::hash() const
+{
+ return HashValue(value);
}
bool
@@ -364,7 +372,7 @@
struct UnbarrieredHashPolicy {
typedef Value Lookup;
- static HashNumber hash(const Lookup& v) { return v.asRawBits(); }
+ static HashNumber hash(const Lookup& v) { return HashValue(v); }
static bool match(const Value& k, const Lookup& l) { return k == l; }
static bool isEmpty(const Value& v) { return v.isMagic(JS_HASH_KEY_EMPTY); }
static void makeEmpty(Value* vp) { vp->setMagic(JS_HASH_KEY_EMPTY); }
diff -Nru firefox-50.0.2+build1/js/src/builtin/RegExp.cpp firefox-50.1.0+build2/js/src/builtin/RegExp.cpp
--- firefox-50.0.2+build1/js/src/builtin/RegExp.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/js/src/builtin/RegExp.cpp 2016-12-09 08:27:49.000000000 +0000
@@ -1613,18 +1613,14 @@
}
bool
-js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* rx, JSObject* proto, uint8_t* result)
+js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result)
{
JS::AutoCheckCannotGC nogc;
- if (!rx->isNative()) {
- *result = false;
- return true;
- }
- NativeObject* nobj = static_cast(rx);
+ RegExpObject* rx = &obj->as();
Shape* shape = cx->compartment()->regExps.getOptimizableRegExpInstanceShape();
- if (shape == nobj->lastProperty()) {
+ if (shape == rx->lastProperty()) {
*result = true;
return true;
}
@@ -1639,12 +1635,12 @@
return true;
}
- if (!RegExpObject::isInitialShape(nobj)) {
+ if (!RegExpObject::isInitialShape(rx)) {
*result = false;
return true;
}
- cx->compartment()->regExps.setOptimizableRegExpInstanceShape(nobj->lastProperty());
+ cx->compartment()->regExps.setOptimizableRegExpInstanceShape(rx->lastProperty());
*result = true;
return true;
}
diff -Nru firefox-50.0.2+build1/js/src/builtin/RegExp.h firefox-50.1.0+build2/js/src/builtin/RegExp.h
--- firefox-50.0.2+build1/js/src/builtin/RegExp.h 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/js/src/builtin/RegExp.h 2016-12-09 08:27:49.000000000 +0000
@@ -113,7 +113,7 @@
RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp);
extern MOZ_MUST_USE bool
-RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* rx, JSObject* proto, uint8_t* result);
+RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result);
extern MOZ_MUST_USE bool
RegExpGetSubstitution(JSContext* cx, HandleLinearString matched, HandleLinearString string,
diff -Nru firefox-50.0.2+build1/js/src/builtin/RegExp.js firefox-50.1.0+build2/js/src/builtin/RegExp.js
--- firefox-50.0.2+build1/js/src/builtin/RegExp.js 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/js/src/builtin/RegExp.js 2016-12-09 08:27:49.000000000 +0000
@@ -156,6 +156,9 @@
// * exec
// * lastIndex
function IsRegExpMethodOptimizable(rx) {
+ if (!IsRegExpObject(rx))
+ return false;
+
var RegExpProto = GetBuiltinPrototype("RegExp");
// If RegExpPrototypeOptimizable and RegExpInstanceOptimizable succeed,
// `RegExpProto.exec` is guaranteed to be data properties.
diff -Nru firefox-50.0.2+build1/js/src/gc/Allocator.cpp firefox-50.1.0+build2/js/src/gc/Allocator.cpp
--- firefox-50.0.2+build1/js/src/gc/Allocator.cpp 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/js/src/gc/Allocator.cpp 2016-12-09 08:27:49.000000000 +0000
@@ -191,11 +191,14 @@
}
#if defined(JS_GC_ZEAL) || defined(DEBUG)
- MOZ_ASSERT_IF(rt->isAtomsCompartment(cx->compartment()),
- kind == AllocKind::STRING ||
- kind == AllocKind::FAT_INLINE_STRING ||
+ MOZ_ASSERT_IF(cx->compartment()->isAtomsCompartment(),
+ kind == AllocKind::ATOM ||
+ kind == AllocKind::FAT_INLINE_ATOM ||
kind == AllocKind::SYMBOL ||
kind == AllocKind::JITCODE);
+ MOZ_ASSERT_IF(!cx->compartment()->isAtomsCompartment(),
+ kind != AllocKind::ATOM &&
+ kind != AllocKind::FAT_INLINE_ATOM);
MOZ_ASSERT(!rt->isHeapBusy());
MOZ_ASSERT(isAllocAllowed());
#endif
diff -Nru firefox-50.0.2+build1/js/src/gc/Heap.h firefox-50.1.0+build2/js/src/gc/Heap.h
--- firefox-50.0.2+build1/js/src/gc/Heap.h 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/js/src/gc/Heap.h 2016-12-09 08:27:49.000000000 +0000
@@ -109,6 +109,8 @@
FAT_INLINE_STRING,
STRING,
EXTERNAL_STRING,
+ FAT_INLINE_ATOM,
+ ATOM,
SYMBOL,
JITCODE,
LIMIT,
@@ -145,6 +147,8 @@
D(FAT_INLINE_STRING, String, JSFatInlineString, JSFatInlineString) \
D(STRING, String, JSString, JSString) \
D(EXTERNAL_STRING, String, JSExternalString, JSExternalString) \
+ D(FAT_INLINE_ATOM, String, js::FatInlineAtom, js::FatInlineAtom) \
+ D(ATOM, String, js::NormalAtom, js::NormalAtom) \
D(SYMBOL, Symbol, JS::Symbol, JS::Symbol) \
D(JITCODE, JitCode, js::jit::JitCode, js::jit::JitCode)
diff -Nru firefox-50.0.2+build1/js/src/jit/VMFunctions.cpp firefox-50.1.0+build2/js/src/jit/VMFunctions.cpp
--- firefox-50.0.2+build1/js/src/jit/VMFunctions.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jit/VMFunctions.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -1182,14 +1182,18 @@
MOZ_ASSERT(str->length() <= JSString::MAX_LENGTH);
gc::AllocKind kind = str->getAllocKind();
- if (str->isFatInline())
- MOZ_ASSERT(kind == gc::AllocKind::FAT_INLINE_STRING);
- else if (str->isExternal())
+ if (str->isFatInline()) {
+ MOZ_ASSERT(kind == gc::AllocKind::FAT_INLINE_STRING ||
+ kind == gc::AllocKind::FAT_INLINE_ATOM);
+ } else if (str->isExternal()) {
MOZ_ASSERT(kind == gc::AllocKind::EXTERNAL_STRING);
- else if (str->isAtom() || str->isFlat())
+ } else if (str->isAtom()) {
+ MOZ_ASSERT(kind == gc::AllocKind::ATOM);
+ } else if (str->isFlat()) {
MOZ_ASSERT(kind == gc::AllocKind::STRING || kind == gc::AllocKind::FAT_INLINE_STRING);
- else
+ } else {
MOZ_ASSERT(kind == gc::AllocKind::STRING);
+ }
#endif
}
diff -Nru firefox-50.0.2+build1/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js firefox-50.1.0+build2/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js
--- firefox-50.0.2+build1/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js 2016-11-30 08:51:08.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js 2016-12-09 08:27:50.000000000 +0000
@@ -44,36 +44,38 @@
// JSExtensibleString - limited by available memory - X
// JSUndependedString - same as JSExtensibleString -
+// Note that atoms are 8 bytes larger than non-atoms, to store the atom's hash code.
+
// Latin-1
-assertEq(tByteSize(""), s(16, 24)); // T, T
-assertEq(tByteSize("1"), s(16, 24)); // T, T
-assertEq(tByteSize("1234567"), s(16, 24)); // T, T
-assertEq(tByteSize("12345678"), s(32, 24)); // F, T
-assertEq(tByteSize("123456789.12345"), s(32, 24)); // F, T
-assertEq(tByteSize("123456789.123456"), s(32, 32)); // F, F
-assertEq(tByteSize("123456789.123456789.123"), s(32, 32)); // F, F
-assertEq(tByteSize("123456789.123456789.1234"), s(48, 56)); // X, X
-assertEq(tByteSize("123456789.123456789.123456789.1"), s(48, 56)); // X, X
-assertEq(tByteSize("123456789.123456789.123456789.12"), s(64, 72)); // X, X
+assertEq(tByteSize(""), s(24, 32)); // T, T
+assertEq(tByteSize("1"), s(24, 32)); // T, T
+assertEq(tByteSize("1234567"), s(24, 32)); // T, T
+assertEq(tByteSize("12345678"), s(40, 32)); // F, T
+assertEq(tByteSize("123456789.12345"), s(40, 32)); // F, T
+assertEq(tByteSize("123456789.123456"), s(40, 40)); // F, F
+assertEq(tByteSize("123456789.123456789.123"), s(40, 40)); // F, F
+assertEq(tByteSize("123456789.123456789.1234"), s(56, 64)); // X, X
+assertEq(tByteSize("123456789.123456789.123456789.1"), s(56, 64)); // X, X
+assertEq(tByteSize("123456789.123456789.123456789.12"), s(72, 80)); // X, X
// Inline char16_t atoms.
// "Impassionate gods have never seen the red that is the Tatsuta River."
// - Ariwara no Narihira
-assertEq(tByteSize("千"), s(16, 24)); // T, T
-assertEq(tByteSize("千早"), s(16, 24)); // T, T
-assertEq(tByteSize("千早ぶ"), s(16, 24)); // T, T
-assertEq(tByteSize("千早ぶる"), s(32, 24)); // F, T
-assertEq(tByteSize("千早ぶる神"), s(32, 24)); // F, T
-assertEq(tByteSize("千早ぶる神代"), s(32, 24)); // F, T
-assertEq(tByteSize("千早ぶる神代も"), s(32, 24)); // F, T
-assertEq(tByteSize("千早ぶる神代もき"), s(32, 32)); // F, F
-assertEq(tByteSize("千早ぶる神代もきかず龍"), s(32, 32)); // F, F
-assertEq(tByteSize("千早ぶる神代もきかず龍田"), s(48, 56)); // X, X
-assertEq(tByteSize("千早ぶる神代もきかず龍田川 か"), s(48, 56)); // X, X
-assertEq(tByteSize("千早ぶる神代もきかず龍田川 から"), s(64, 72)); // X, X
-assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水く"), s(64, 72)); // X, X
-assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水くく"), s(80, 88)); // X, X
-assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水くくるとは"), s(80, 88)); // X, X
+assertEq(tByteSize("千"), s(24, 32)); // T, T
+assertEq(tByteSize("千早"), s(24, 32)); // T, T
+assertEq(tByteSize("千早ぶ"), s(24, 32)); // T, T
+assertEq(tByteSize("千早ぶる"), s(40, 32)); // F, T
+assertEq(tByteSize("千早ぶる神"), s(40, 32)); // F, T
+assertEq(tByteSize("千早ぶる神代"), s(40, 32)); // F, T
+assertEq(tByteSize("千早ぶる神代も"), s(40, 32)); // F, T
+assertEq(tByteSize("千早ぶる神代もき"), s(40, 40)); // F, F
+assertEq(tByteSize("千早ぶる神代もきかず龍"), s(40, 40)); // F, F
+assertEq(tByteSize("千早ぶる神代もきかず龍田"), s(56, 64)); // X, X
+assertEq(tByteSize("千早ぶる神代もきかず龍田川 か"), s(56, 64)); // X, X
+assertEq(tByteSize("千早ぶる神代もきかず龍田川 から"), s(72, 80)); // X, X
+assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水く"), s(72, 80)); // X, X
+assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水くく"), s(88, 96)); // X, X
+assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水くくるとは"), s(88, 96)); // X, X
// A Latin-1 rope. This changes size when flattened.
// "In a village of La Mancha, the name of which I have no desire to call to mind"
diff -Nru firefox-50.0.2+build1/js/src/jsatom.cpp firefox-50.1.0+build2/js/src/jsatom.cpp
--- firefox-50.0.2+build1/js/src/jsatom.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jsatom.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -346,7 +346,8 @@
return nullptr;
}
- JSAtom* atom = flat->morphAtomizedStringIntoAtom();
+ JSAtom* atom = flat->morphAtomizedStringIntoAtom(lookup.hash);
+ MOZ_ASSERT(atom->hash() == lookup.hash);
// We have held the lock since looking up p, and the operations we've done
// since then can't GC; therefore the atoms table has not been modified and
diff -Nru firefox-50.0.2+build1/js/src/jsatom.h firefox-50.1.0+build2/js/src/jsatom.h
--- firefox-50.0.2+build1/js/src/jsatom.h 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jsatom.h 2016-12-09 08:27:44.000000000 +0000
@@ -23,14 +23,6 @@
namespace js {
-JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
-
-static MOZ_ALWAYS_INLINE js::HashNumber
-HashId(jsid id)
-{
- return mozilla::HashGeneric(JSID_BITS(id));
-}
-
/*
* Return a printable, lossless char[] representation of a string-type atom.
* The lifetime of the result matches the lifetime of bytes.
diff -Nru firefox-50.0.2+build1/js/src/jsatominlines.h firefox-50.1.0+build2/js/src/jsatominlines.h
--- firefox-50.0.2+build1/js/src/jsatominlines.h 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jsatominlines.h 2016-12-09 08:27:44.000000000 +0000
@@ -156,12 +156,13 @@
AtomHasher::Lookup::Lookup(const JSAtom* atom)
: isLatin1(atom->hasLatin1Chars()), length(atom->length()), atom(atom)
{
+ hash = atom->hash();
if (isLatin1) {
latin1Chars = atom->latin1Chars(nogc);
- hash = mozilla::HashString(latin1Chars, length);
+ MOZ_ASSERT(mozilla::HashString(latin1Chars, length) == hash);
} else {
twoByteChars = atom->twoByteChars(nogc);
- hash = mozilla::HashString(twoByteChars, length);
+ MOZ_ASSERT(mozilla::HashString(twoByteChars, length) == hash);
}
}
@@ -171,7 +172,7 @@
JSAtom* key = entry.asPtrUnbarriered();
if (lookup.atom)
return lookup.atom == key;
- if (key->length() != lookup.length)
+ if (key->length() != lookup.length || key->hash() != lookup.hash)
return false;
if (key->hasLatin1Chars()) {
diff -Nru firefox-50.0.2+build1/js/src/jscompartment.cpp firefox-50.1.0+build2/js/src/jscompartment.cpp
--- firefox-50.0.2+build1/js/src/jscompartment.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jscompartment.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -50,6 +50,7 @@
runtime_(zone->runtimeFromMainThread()),
principals_(nullptr),
isSystem_(false),
+ isAtomsCompartment_(false),
isSelfHosting(false),
marked(true),
warnedAboutExprClosure(false),
diff -Nru firefox-50.0.2+build1/js/src/jscompartment.h firefox-50.1.0+build2/js/src/jscompartment.h
--- firefox-50.0.2+build1/js/src/jscompartment.h 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jscompartment.h 2016-12-09 08:27:44.000000000 +0000
@@ -324,6 +324,13 @@
isSystem_ = isSystem;
}
+ bool isAtomsCompartment() const {
+ return isAtomsCompartment_;
+ }
+ void setIsAtomsCompartment() {
+ isAtomsCompartment_ = true;
+ }
+
// Used to approximate non-content code when reporting telemetry.
inline bool isProbablySystemOrAddonCode() const {
if (creationOptions_.addonIdOrNull())
@@ -334,6 +341,8 @@
private:
JSPrincipals* principals_;
bool isSystem_;
+ bool isAtomsCompartment_;
+
public:
bool isSelfHosting;
bool marked;
diff -Nru firefox-50.0.2+build1/js/src/jsgc.cpp firefox-50.1.0+build2/js/src/jsgc.cpp
--- firefox-50.0.2+build1/js/src/jsgc.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jsgc.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -358,6 +358,8 @@
gcstats::PHASE_SWEEP_STRING, {
AllocKind::FAT_INLINE_STRING,
AllocKind::STRING,
+ AllocKind::FAT_INLINE_ATOM,
+ AllocKind::ATOM,
AllocKind::SYMBOL
}
},
@@ -1764,7 +1766,9 @@
AllocKind::BASE_SHAPE,
AllocKind::FAT_INLINE_STRING,
AllocKind::STRING,
- AllocKind::EXTERNAL_STRING
+ AllocKind::EXTERNAL_STRING,
+ AllocKind::FAT_INLINE_ATOM,
+ AllocKind::ATOM
};
Arena*
diff -Nru firefox-50.0.2+build1/js/src/jsgc.h firefox-50.1.0+build2/js/src/jsgc.h
--- firefox-50.0.2+build1/js/src/jsgc.h 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jsgc.h 2016-12-09 08:27:44.000000000 +0000
@@ -105,6 +105,8 @@
false, /* AllocKind::FAT_INLINE_STRING */
false, /* AllocKind::STRING */
false, /* AllocKind::EXTERNAL_STRING */
+ false, /* AllocKind::FAT_INLINE_ATOM */
+ false, /* AllocKind::ATOM */
false, /* AllocKind::SYMBOL */
false, /* AllocKind::JITCODE */
};
@@ -140,6 +142,8 @@
true, /* AllocKind::FAT_INLINE_STRING */
true, /* AllocKind::STRING */
false, /* AllocKind::EXTERNAL_STRING */
+ true, /* AllocKind::FAT_INLINE_ATOM */
+ true, /* AllocKind::ATOM */
true, /* AllocKind::SYMBOL */
false, /* AllocKind::JITCODE */
};
diff -Nru firefox-50.0.2+build1/js/src/jsiter.cpp firefox-50.1.0+build2/js/src/jsiter.cpp
--- firefox-50.0.2+build1/js/src/jsiter.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/jsiter.cpp 2016-12-09 08:27:44.000000000 +0000
@@ -68,17 +68,7 @@
TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj");
}
-struct IdHashPolicy {
- typedef jsid Lookup;
- static HashNumber hash(jsid id) {
- return JSID_BITS(id);
- }
- static bool match(jsid id1, jsid id2) {
- return id1 == id2;
- }
-};
-
-typedef HashSet IdSet;
+typedef HashSet> IdSet;
static inline bool
NewKeyValuePair(JSContext* cx, jsid id, const Value& val, MutableHandleValue rval)
diff -Nru firefox-50.0.2+build1/js/src/proxy/Wrapper.cpp firefox-50.1.0+build2/js/src/proxy/Wrapper.cpp
--- firefox-50.0.2+build1/js/src/proxy/Wrapper.cpp 2016-11-30 08:51:01.000000000 +0000
+++ firefox-50.1.0+build2/js/src/proxy/Wrapper.cpp 2016-12-09 08:27:45.000000000 +0000
@@ -329,7 +329,10 @@
Wrapper::wrappedObject(JSObject* wrapper)
{
MOZ_ASSERT(wrapper->is());
- return wrapper->as().target();
+ JSObject* target = wrapper->as().target();
+ if (target)
+ JS::ExposeObjectToActiveJS(target);
+ return target;
}
JS_FRIEND_API(JSObject*)
diff -Nru firefox-50.0.2+build1/js/src/vm/ObjectGroup.cpp firefox-50.1.0+build2/js/src/vm/ObjectGroup.cpp
--- firefox-50.0.2+build1/js/src/vm/ObjectGroup.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/ObjectGroup.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -553,39 +553,33 @@
return nullptr;
}
- if (proto.isObject()) {
- RootedObject obj(cx, proto.toObject());
-
- if (associated) {
- if (associated->is()) {
- if (!TypeNewScript::make(cx->asJSContext(), group, &associated->as()))
- return nullptr;
- } else {
- group->setTypeDescr(&associated->as());
- }
+ if (associated) {
+ if (associated->is()) {
+ if (!TypeNewScript::make(cx->asJSContext(), group, &associated->as()))
+ return nullptr;
+ } else {
+ group->setTypeDescr(&associated->as());
}
+ }
- /*
- * Some builtin objects have slotful native properties baked in at
- * creation via the Shape::{insert,get}initialShape mechanism. Since
- * these properties are never explicitly defined on new objects, update
- * the type information for them here.
- */
-
- const JSAtomState& names = cx->names();
-
- if (obj->is())
- AddTypePropertyId(cx, group, nullptr, NameToId(names.lastIndex), TypeSet::Int32Type());
-
- if (obj->is())
- AddTypePropertyId(cx, group, nullptr, NameToId(names.length), TypeSet::Int32Type());
-
- if (obj->is()) {
- AddTypePropertyId(cx, group, nullptr, NameToId(names.fileName), TypeSet::StringType());
- AddTypePropertyId(cx, group, nullptr, NameToId(names.lineNumber), TypeSet::Int32Type());
- AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type());
- AddTypePropertyId(cx, group, nullptr, NameToId(names.stack), TypeSet::StringType());
- }
+ /*
+ * Some builtin objects have slotful native properties baked in at
+ * creation via the Shape::{insert,get}initialShape mechanism. Since
+ * these properties are never explicitly defined on new objects, update
+ * the type information for them here.
+ */
+
+ const JSAtomState& names = cx->names();
+
+ if (clasp == &RegExpObject::class_) {
+ AddTypePropertyId(cx, group, nullptr, NameToId(names.lastIndex), TypeSet::Int32Type());
+ } else if (clasp == &StringObject::class_) {
+ AddTypePropertyId(cx, group, nullptr, NameToId(names.length), TypeSet::Int32Type());
+ } else if (ErrorObject::isErrorClass((clasp))) {
+ AddTypePropertyId(cx, group, nullptr, NameToId(names.fileName), TypeSet::StringType());
+ AddTypePropertyId(cx, group, nullptr, NameToId(names.lineNumber), TypeSet::Int32Type());
+ AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type());
+ AddTypePropertyId(cx, group, nullptr, NameToId(names.stack), TypeSet::StringType());
}
return group;
@@ -1119,7 +1113,7 @@
};
static inline HashNumber hash(const Lookup& lookup) {
- return (HashNumber) (JSID_BITS(lookup.properties[lookup.nproperties - 1].id) ^
+ return (HashNumber) (HashId(lookup.properties[lookup.nproperties - 1].id) ^
lookup.nproperties);
}
diff -Nru firefox-50.0.2+build1/js/src/vm/RegExpObject.h firefox-50.1.0+build2/js/src/vm/RegExpObject.h
--- firefox-50.0.2+build1/js/src/vm/RegExpObject.h 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/RegExpObject.h 2016-12-09 08:27:47.000000000 +0000
@@ -425,8 +425,8 @@
static unsigned lastIndexSlot() { return LAST_INDEX_SLOT; }
- static bool isInitialShape(NativeObject* nobj) {
- Shape* shape = nobj->lastProperty();
+ static bool isInitialShape(RegExpObject* rx) {
+ Shape* shape = rx->lastProperty();
if (!shape->hasSlot())
return false;
if (shape->maybeSlot() != LAST_INDEX_SLOT)
diff -Nru firefox-50.0.2+build1/js/src/vm/Runtime.cpp firefox-50.1.0+build2/js/src/vm/Runtime.cpp
--- firefox-50.0.2+build1/js/src/vm/Runtime.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/Runtime.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -312,6 +312,7 @@
return false;
atomsCompartment->setIsSystem(true);
+ atomsCompartment->setIsAtomsCompartment();
atomsZone.forget();
this->atomsCompartment_ = atomsCompartment.forget();
diff -Nru firefox-50.0.2+build1/js/src/vm/Shape.h firefox-50.1.0+build2/js/src/vm/Shape.h
--- firefox-50.0.2+build1/js/src/vm/Shape.h 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/Shape.h 2016-12-09 08:27:47.000000000 +0000
@@ -29,6 +29,7 @@
#include "js/RootingAPI.h"
#include "js/UbiNode.h"
#include "vm/ObjectGroup.h"
+#include "vm/String.h"
#ifdef _MSC_VER
#pragma warning(push)
@@ -1205,7 +1206,7 @@
/* Accumulate from least to most random so the low bits are most random. */
hash = mozilla::RotateLeft(hash, 4) ^ attrs;
hash = mozilla::RotateLeft(hash, 4) ^ slot_;
- hash = mozilla::RotateLeft(hash, 4) ^ JSID_BITS(propid);
+ hash = mozilla::RotateLeft(hash, 4) ^ HashId(propid);
hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawGetter);
hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawSetter);
return hash;
diff -Nru firefox-50.0.2+build1/js/src/vm/String.cpp firefox-50.1.0+build2/js/src/vm/String.cpp
--- firefox-50.0.2+build1/js/src/vm/String.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/String.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -71,8 +71,12 @@
JS::ubi::Node::Size
JS::ubi::Concrete::size(mozilla::MallocSizeOf mallocSizeOf) const
{
- JSString &str = get();
- size_t size = str.isFatInline() ? sizeof(JSFatInlineString) : sizeof(JSString);
+ JSString& str = get();
+ size_t size;
+ if (str.isAtom())
+ size = str.isFatInline() ? sizeof(js::FatInlineAtom) : sizeof(js::NormalAtom);
+ else
+ size = str.isFatInline() ? sizeof(JSFatInlineString) : sizeof(JSString);
// We can't use mallocSizeof on things in the nursery. At the moment,
// strings are never in the nursery, but that may change.
@@ -802,7 +806,8 @@
JSFlatString* s = NewInlineString(cx, Latin1Range(buffer, 1));
if (!s)
return false;
- unitStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom();
+ HashNumber hash = mozilla::HashString(buffer, 1);
+ unitStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(hash);
}
for (uint32_t i = 0; i < NUM_SMALL_CHARS * NUM_SMALL_CHARS; i++) {
@@ -810,7 +815,8 @@
JSFlatString* s = NewInlineString(cx, Latin1Range(buffer, 2));
if (!s)
return false;
- length2StaticTable[i] = s->morphAtomizedStringIntoPermanentAtom();
+ HashNumber hash = mozilla::HashString(buffer, 2);
+ length2StaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(hash);
}
for (uint32_t i = 0; i < INT_STATIC_LIMIT; i++) {
@@ -828,7 +834,8 @@
JSFlatString* s = NewInlineString(cx, Latin1Range(buffer, 3));
if (!s)
return false;
- intStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom();
+ HashNumber hash = mozilla::HashString(buffer, 3);
+ intStaticTable[i] = s->morphAtomizedStringIntoPermanentAtom(hash);
}
}
diff -Nru firefox-50.0.2+build1/js/src/vm/String.h firefox-50.1.0+build2/js/src/vm/String.h
--- firefox-50.0.2+build1/js/src/vm/String.h 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/String.h 2016-12-09 08:27:47.000000000 +0000
@@ -123,7 +123,11 @@
* | |
* | +-- JSFatInlineString - / header is fat
* |
- * JSAtom - / string equality === pointer equality
+ * JSAtom (abstract) - / string equality === pointer equality
+ * | |
+ * | +-- js::NormalAtom - JSFlatString + atom hash code
+ * | |
+ * | +-- js::FatInlineAtom - JSFatInlineString + atom hash code
* |
* js::PropertyName - / chars don't contain an index (uint32_t)
*
@@ -135,10 +139,9 @@
* Atoms can additionally be permanent, i.e. unable to be collected, and can
* be combined with other string types to create additional most-derived types
* that satisfy the invariants of more than one of the abovementioned
- * most-derived types:
- * - InlineAtom = JSInlineString + JSAtom (atom with inline chars, abstract)
- * - ThinInlineAtom = JSThinInlineString + JSAtom (atom with inline chars)
- * - FatInlineAtom = JSFatInlineString + JSAtom (atom with (more) inline chars)
+ * most-derived types. Furthermore, each atom stores a hash number (based on its
+ * chars). This hash number is used as key in the atoms table and when the atom
+ * is used as key in a JS Map/Set.
*
* Derived string types can be queried from ancestor types via isX() and
* retrieved with asX() debug-only-checked casts.
@@ -769,14 +772,8 @@
* Once a JSFlatString sub-class has been added to the atom state, this
* operation changes the string to the JSAtom type, in place.
*/
- MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoAtom() {
- d.u1.flags |= ATOM_BIT;
- return &asAtom();
- }
- MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoPermanentAtom() {
- d.u1.flags |= PERMANENT_ATOM_MASK;
- return &asAtom();
- }
+ MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoAtom(js::HashNumber hash);
+ MOZ_ALWAYS_INLINE JSAtom* morphAtomizedStringIntoPermanentAtom(js::HashNumber hash);
inline void finalize(js::FreeOp* fop);
@@ -988,6 +985,9 @@
d.u1.flags |= PERMANENT_ATOM_MASK;
}
+ inline js::HashNumber hash() const;
+ inline void initHash(js::HashNumber hash);
+
#ifdef DEBUG
void dump(FILE* fp);
void dump();
@@ -999,6 +999,83 @@
namespace js {
+class NormalAtom : public JSAtom
+{
+ protected: // Silence Clang unused-field warning.
+ HashNumber hash_;
+ uint32_t padding_; // Ensure the size is a multiple of gc::CellSize.
+
+ public:
+ HashNumber hash() const {
+ return hash_;
+ }
+ void initHash(HashNumber hash) {
+ hash_ = hash;
+ }
+};
+
+static_assert(sizeof(NormalAtom) == sizeof(JSString) + sizeof(uint64_t),
+ "NormalAtom must have size of a string + HashNumber, "
+ "aligned to gc::CellSize");
+
+class FatInlineAtom : public JSAtom
+{
+ protected: // Silence Clang unused-field warning.
+ char inlineStorage_[sizeof(JSFatInlineString) - sizeof(JSString)];
+ HashNumber hash_;
+ uint32_t padding_; // Ensure the size is a multiple of gc::CellSize.
+
+ public:
+ HashNumber hash() const {
+ return hash_;
+ }
+ void initHash(HashNumber hash) {
+ hash_ = hash;
+ }
+};
+
+static_assert(sizeof(FatInlineAtom) == sizeof(JSFatInlineString) + sizeof(uint64_t),
+ "FatInlineAtom must have size of a fat inline string + HashNumber, "
+ "aligned to gc::CellSize");
+
+} // namespace js
+
+inline js::HashNumber
+JSAtom::hash() const
+{
+ if (isFatInline())
+ return static_cast(this)->hash();
+ return static_cast(this)->hash();
+}
+
+inline void
+JSAtom::initHash(js::HashNumber hash)
+{
+ if (isFatInline())
+ return static_cast(this)->initHash(hash);
+ return static_cast(this)->initHash(hash);
+}
+
+MOZ_ALWAYS_INLINE JSAtom*
+JSFlatString::morphAtomizedStringIntoAtom(js::HashNumber hash)
+{
+ d.u1.flags |= ATOM_BIT;
+ JSAtom* atom = &asAtom();
+ atom->initHash(hash);
+ return atom;
+}
+
+MOZ_ALWAYS_INLINE JSAtom*
+JSFlatString::morphAtomizedStringIntoPermanentAtom(js::HashNumber hash)
+{
+ d.u1.flags |= PERMANENT_ATOM_MASK;
+ JSAtom* atom = &asAtom();
+ atom->initHash(hash);
+ return atom;
+}
+
+namespace js {
+
class StaticStrings
{
private:
@@ -1206,6 +1283,28 @@
return NewStringCopyN(cx, s, strlen(s));
}
+JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
+
+static MOZ_ALWAYS_INLINE js::HashNumber
+HashId(jsid id)
+{
+ if (MOZ_LIKELY(JSID_IS_ATOM(id)))
+ return JSID_TO_ATOM(id)->hash();
+ return mozilla::HashGeneric(JSID_BITS(id));
+}
+
+template <>
+struct DefaultHasher
+{
+ typedef jsid Lookup;
+ static HashNumber hash(jsid id) {
+ return HashId(id);
+ }
+ static bool match(jsid id1, jsid id2) {
+ return id1 == id2;
+ }
+};
+
} /* namespace js */
// Addon IDs are interned atoms which are never destroyed. This detail is
diff -Nru firefox-50.0.2+build1/js/src/vm/String-inl.h firefox-50.1.0+build2/js/src/vm/String-inl.h
--- firefox-50.0.2+build1/js/src/vm/String-inl.h 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/js/src/vm/String-inl.h 2016-12-09 08:27:47.000000000 +0000
@@ -13,6 +13,7 @@
#include "mozilla/Range.h"
#include "jscntxt.h"
+#include "jscompartment.h"
#include "gc/Allocator.h"
#include "gc/Marking.h"
@@ -220,7 +221,11 @@
if (!validateLength(cx, length))
return nullptr;
- JSFlatString* str = static_cast(js::Allocate(cx));
+ JSFlatString* str;
+ if (cx->compartment()->isAtomsCompartment())
+ str = js::Allocate(cx);
+ else
+ str = static_cast(js::Allocate(cx));
if (!str)
return nullptr;
@@ -247,6 +252,9 @@
MOZ_ALWAYS_INLINE JSThinInlineString*
JSThinInlineString::new_(js::ExclusiveContext* cx)
{
+ if (cx->compartment()->isAtomsCompartment())
+ return (JSThinInlineString*)(js::Allocate(cx));
+
return static_cast(js::Allocate(cx));
}
@@ -254,6 +262,9 @@
MOZ_ALWAYS_INLINE JSFatInlineString*
JSFatInlineString::new_(js::ExclusiveContext* cx)
{
+ if (cx->compartment()->isAtomsCompartment())
+ return (JSFatInlineString*)(js::Allocate(cx));
+
return js::Allocate(cx);
}
@@ -351,6 +362,7 @@
{
/* FatInline strings are in a different arena. */
MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_STRING);
+ MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_ATOM);
if (isFlat())
asFlat().finalize(fop);
@@ -362,6 +374,7 @@
JSFlatString::finalize(js::FreeOp* fop)
{
MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_STRING);
+ MOZ_ASSERT(getAllocKind() != js::gc::AllocKind::FAT_INLINE_ATOM);
if (!isInline())
fop->free_(nonInlineCharsRaw());
@@ -381,6 +394,8 @@
{
MOZ_ASSERT(JSString::isAtom());
MOZ_ASSERT(JSString::isFlat());
+ MOZ_ASSERT(getAllocKind() == js::gc::AllocKind::ATOM ||
+ getAllocKind() == js::gc::AllocKind::FAT_INLINE_ATOM);
if (!isInline())
fop->free_(nonInlineCharsRaw());
diff -Nru firefox-50.0.2+build1/l10n/changesets firefox-50.1.0+build2/l10n/changesets
--- firefox-50.0.2+build1/l10n/changesets 2016-11-30 09:03:54.000000000 +0000
+++ firefox-50.1.0+build2/l10n/changesets 2016-12-09 08:40:18.000000000 +0000
@@ -1,91 +1,91 @@
ach 730:72c548f97e82
af 966:676daf929ded
-an 833:e5d825045ca1
-ar 2230:123fea67f4e0
-as 1068:463b595279e5
-ast 1745:dda44cadd427
-az 839:4d87e836c55b
-be 2172:047c164b5b1d
-bg 1651:e36f8bcfd846
-bn-BD 1459:1023c93a4fe2
-bn-IN 1311:2b2cbdb42980
-br 1826:f674fce50b82
+an 835:7406fc6fdc58
+ar 2233:c613be7b7494
+as 1070:b72dd4b7a305
+ast 1748:f0f66a7117f9
+az 841:d88d21acbdd4
+be 2175:b72707d30bf0
+bg 1652:da9a9f4ad94d
+bn-BD 1460:b8df37338700
+bn-IN 1313:e127be82fc9b
+br 1829:e1f1d6194976
bs 863:3425b8fcf1ab
-ca 3006:0a69a761fcf2
-cak 553:256e9a302293
-cs 4731:eaebf7e6fa81
-cy 1631:9fe477174313
-da 2745:f7dd57cbdcbc
-de 5496:d4f63990331c
-dsb 851:b3b798a4e175
-el 1727:83ffe66a2828
-en-GB 2452:6041abb4c88b
-en-ZA 873:5e2d46f1be42
-eo 1390:4bcae5df01a7
-es-AR 3103:e92ed9fb8a69
-es-CL 1663:c7254ea14d74
-es-ES 4799:02ae8e6640c2
-es-MX 1563:8ef82e2cf334
-et 2225:a4591b6c10f1
-eu 2098:1cd915cc6f46
-fa 1629:3e126d37ce2a
-ff 900:b98f6b5b31ac
-fi 2760:7bc66dc34cca
-fr 7799:59c1fadd1e56
-fy-NL 3172:4fb65d3b8a0b
-ga-IE 2327:f32ab42cfb46
-gd 2159:0df17a47a583
-gl 3482:33b4f4e2eb4e
-gn 266:7c57fe8d4c2f
-gu-IN 1549:76b4ed27c48f
-he 1821:db95c8dd2878
-hi-IN 1448:51531d6591e2
-hr 2217:69f2784ebed7
-hsb 1018:abc7a15315e3
-hu 3064:ae10f12a46c6
-hy-AM 1723:29c8673c03ba
-id 2179:697f81afbedf
-is 1873:6d448e1f3c83
-it 7253:43c1bf577560
-ja 2913:5e2e217b5355
-ja-JP-mac 2388:4f0460057e33
-kk 1461:f0373dfa1d69
+ca 3009:7dd5009dc783
+cak 555:369033cfd5c6
+cs 4734:265a445f2bdf
+cy 1634:64a6aec4a78d
+da 2748:f9a32324dfdb
+de 5499:65d00240c57c
+dsb 854:eb533f5fcde9
+el 1730:2e0349ede0e9
+en-GB 2455:a8ece8304624
+en-ZA 875:dca05b316cae
+eo 1392:2fb355572837
+es-AR 3106:e34ca800be77
+es-CL 1665:d3a7dc11410d
+es-ES 4802:f56f25ea9035
+es-MX 1565:4386ddfaa4a8
+et 2228:ee2aa0dca879
+eu 2101:0f47e8a15f27
+fa 1631:352b57e48327
+ff 902:9f63ab726685
+fi 2763:1b61ddddb405
+fr 7802:d91d09e9589e
+fy-NL 3175:fb5941206a9d
+ga-IE 2330:34c71eccf78e
+gd 2162:9c16f7543ad4
+gl 3485:7225cee37061
+gn 268:cb488dd12fe5
+gu-IN 1551:ab7edf4d5640
+he 1824:ad4f9154a6ec
+hi-IN 1450:27dd37dc8e3c
+hr 2220:f4f593c515e0
+hsb 1021:968d2b31c9af
+hu 3067:a23a810de9f9
+hy-AM 1726:5df91ff23b17
+id 2182:f18d00685080
+is 1876:92556bd9fa24
+it 7256:57f4f63b62f9
+ja 2916:45a60d6b8655
+ja-JP-mac 2389:de83265732bc
+kk 1463:fcea16e131c4
km 982:00277d0045d3
-kn 1449:02172da07e92
-ko 2472:aa41fd9e790e
+kn 1451:65fc5ee91377
+ko 2475:a9981b90295c
lij 992:6a94ea30eef6
-lt 3582:79fdc2902e5a
-lv 1710:3fd9278458e6
-mai 1159:75cc0a2f33ad
+lt 3585:6ccb2e579bfd
+lv 1712:0fb141dfc6c8
+mai 1161:e2b5034a6d9e
mk 847:0f98fd626df2
-ml 1328:21a44d0f6f7a
-mr 1466:90a0c0fd7aaf
-ms 945:c32ae2d06e30
-nb-NO 3220:828b32e0bde5
-nl 6109:5adbe6d0853b
-nn-NO 1968:34443e0e449d
-or 1153:9e20f3f9b4b1
-pa-IN 2263:b447eaf0b96b
-pl 9287:8bb0e08b2f80
-pt-BR 2877:3595a49ce288
-pt-PT 5686:c5a7b7e87fe9
-rm 1787:389c3307725b
-ro 2505:845033cc08f4
-ru 4701:d0213f5db4a0
-si 1545:8a2f079e0b3c
-sk 4470:078ed9415ec9
-sl 2962:670c32f5a433
-son 1193:e7789d73ce32
-sq 2375:c7f92d999144
-sr 1613:614cbf875285
-sv-SE 5303:9b50a51b4e6c
-ta 1230:4196ccbccc96
-te 1294:4932f72ac2dd
-th 1751:510bb901e9e6
-tr 2793:a76bb110a253
-uk 3655:d91da766fb7f
-uz 774:bf2d3a9b5401
-vi 1233:a0c5754da707
-xh 993:01776b460dd7
-zh-CN 2974:3d4aa11e66b6
-zh-TW 3123:16271b4e6b6e
+ml 1330:e13287eda129
+mr 1468:25e4a93d07eb
+ms 947:b74c5f0322fd
+nb-NO 3223:5894b32e79a6
+nl 6112:bcdfd5b486fd
+nn-NO 1971:8a0da41fb201
+or 1155:89a3846c0b3c
+pa-IN 2266:4261e12dad64
+pl 9293:3cada1a3feb9
+pt-BR 2880:1a3e26127441
+pt-PT 5689:4be058ed887c
+rm 1790:dfe70a5e304d
+ro 2508:d18454fc4cae
+ru 4704:323ab3a71098
+si 1546:9665fbaa4c69
+sk 4473:941f6eb9b286
+sl 2965:670d95eccc35
+son 1195:5207fd38961a
+sq 2378:3165434dc77c
+sr 1616:1ea28c2b6187
+sv-SE 5306:7eb57a836b89
+ta 1232:ff95ca25b765
+te 1296:21d675058c87
+th 1753:186494dd70cc
+tr 2796:95f563ea206c
+uk 3658:74507dd03f8c
+uz 776:9c06a8d1b402
+vi 1234:7c712e2f9db2
+xh 995:41f521ddc69c
+zh-CN 2977:c7d9bc361e9c
+zh-TW 3126:00ad8b4d6425
diff -Nru firefox-50.0.2+build1/layout/base/nsCSSRendering.cpp firefox-50.1.0+build2/layout/base/nsCSSRendering.cpp
--- firefox-50.0.2+build1/layout/base/nsCSSRendering.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/layout/base/nsCSSRendering.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -2744,16 +2744,21 @@
}
// Fit the gradient line exactly into the source rect.
+ // aSrc is relative to aIntrinsincSize.
+ // srcRectDev will be relative to srcSize, so in the same coordinate space
+ // as lineStart / lineEnd.
+ gfxRect srcRectDev = nsLayoutUtils::RectToGfxRect(
+ CSSPixel::ToAppUnits(aSrc), appUnitsPerDevPixel);
if (lineStart.x != lineEnd.x) {
- rectLen = aPresContext->CSSPixelsToDevPixels(aSrc.width);
- offset = ((double)aSrc.x - lineStart.x) / lineLength;
- lineStart.x = aSrc.x;
- lineEnd.x = aSrc.x + rectLen;
+ rectLen = srcRectDev.width;
+ offset = (srcRectDev.x - lineStart.x) / lineLength;
+ lineStart.x = srcRectDev.x;
+ lineEnd.x = srcRectDev.XMost();
} else {
- rectLen = aPresContext->CSSPixelsToDevPixels(aSrc.height);
- offset = ((double)aSrc.y - lineStart.y) / lineLength;
- lineStart.y = aSrc.y;
- lineEnd.y = aSrc.y + rectLen;
+ rectLen = srcRectDev.height;
+ offset = (srcRectDev.y - lineStart.y) / lineLength;
+ lineStart.y = srcRectDev.y;
+ lineEnd.y = srcRectDev.YMost();
}
// Adjust gradient stop positions for the new gradient line.
@@ -5759,8 +5764,7 @@
nsSize repeatSize;
nsRect fillRect(aFill);
nsRect tile = ComputeTile(fillRect, aHFill, aVFill, aUnitSize, repeatSize);
- CSSIntSize imageSize(nsPresContext::AppUnitsToIntCSSPixels(srcRect.width),
- nsPresContext::AppUnitsToIntCSSPixels(srcRect.height));
+ CSSIntSize imageSize(srcRect.width, srcRect.height);
return nsLayoutUtils::DrawBackgroundImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage, imageSize, samplingFilter,
diff -Nru firefox-50.0.2+build1/layout/base/Units.h firefox-50.1.0+build2/layout/base/Units.h
--- firefox-50.0.2+build1/layout/base/Units.h 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/layout/base/Units.h 2016-12-09 08:27:47.000000000 +0000
@@ -264,6 +264,13 @@
NSToCoordRoundWithClamp(aRect.width * float(AppUnitsPerCSSPixel())),
NSToCoordRoundWithClamp(aRect.height * float(AppUnitsPerCSSPixel())));
}
+
+ static nsRect ToAppUnits(const CSSIntRect& aRect) {
+ return nsRect(NSToCoordRoundWithClamp(float(aRect.x) * float(AppUnitsPerCSSPixel())),
+ NSToCoordRoundWithClamp(float(aRect.y) * float(AppUnitsPerCSSPixel())),
+ NSToCoordRoundWithClamp(float(aRect.width) * float(AppUnitsPerCSSPixel())),
+ NSToCoordRoundWithClamp(float(aRect.height) * float(AppUnitsPerCSSPixel())));
+ }
};
/*
diff -Nru firefox-50.0.2+build1/layout/reftests/bugs/1315113-1.html firefox-50.1.0+build2/layout/reftests/bugs/1315113-1.html
--- firefox-50.0.2+build1/layout/reftests/bugs/1315113-1.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/layout/reftests/bugs/1315113-1.html 2016-12-09 08:27:48.000000000 +0000
@@ -0,0 +1,23 @@
+
+
+
+Test for bug 1315113: Gradient in border image
+
+
+
diff -Nru firefox-50.0.2+build1/layout/reftests/bugs/1315113-1-ref.html firefox-50.1.0+build2/layout/reftests/bugs/1315113-1-ref.html
--- firefox-50.0.2+build1/layout/reftests/bugs/1315113-1-ref.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/layout/reftests/bugs/1315113-1-ref.html 2016-12-09 08:27:48.000000000 +0000
@@ -0,0 +1,21 @@
+
+
+
+Reference for test for bug 1315113: Gradient in border image
+
+
+
diff -Nru firefox-50.0.2+build1/layout/reftests/bugs/1315113-2.html firefox-50.1.0+build2/layout/reftests/bugs/1315113-2.html
--- firefox-50.0.2+build1/layout/reftests/bugs/1315113-2.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/layout/reftests/bugs/1315113-2.html 2016-12-09 08:27:48.000000000 +0000
@@ -0,0 +1,23 @@
+
+
+
+Test for bug 1315113: Gradient in border image
+
+
+
diff -Nru firefox-50.0.2+build1/layout/reftests/bugs/1315113-2-ref.html firefox-50.1.0+build2/layout/reftests/bugs/1315113-2-ref.html
--- firefox-50.0.2+build1/layout/reftests/bugs/1315113-2-ref.html 1970-01-01 00:00:00.000000000 +0000
+++ firefox-50.1.0+build2/layout/reftests/bugs/1315113-2-ref.html 2016-12-09 08:27:48.000000000 +0000
@@ -0,0 +1,21 @@
+
+
+
+Reference for test for bug 1315113: Gradient in border image
+
+
+
diff -Nru firefox-50.0.2+build1/layout/reftests/bugs/reftest.list firefox-50.1.0+build2/layout/reftests/bugs/reftest.list
--- firefox-50.0.2+build1/layout/reftests/bugs/reftest.list 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/layout/reftests/bugs/reftest.list 2016-12-09 08:27:49.000000000 +0000
@@ -1968,3 +1968,6 @@
# should be same. |fuzzy()| here allows the difference in border, but not
# background color.
fuzzy(255,1000) skip-if(!cocoaWidget) == 1294102-1.html 1294102-1-ref.html
+fuzzy(2,320000) == 1315113-1.html 1315113-1-ref.html
+fuzzy(2,20000) == 1315113-2.html 1315113-2-ref.html
+
diff -Nru firefox-50.0.2+build1/layout/style/nsRuleNode.cpp firefox-50.1.0+build2/layout/style/nsRuleNode.cpp
--- firefox-50.0.2+build1/layout/style/nsRuleNode.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/layout/style/nsRuleNode.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -393,6 +393,11 @@
return viewportSize;
}
+// If |aStyleFont| is nullptr, aStyleContext->StyleFont() is used.
+//
+// In case that |aValue| is rem unit, if |aStyleContext| is null, callers must
+// specify a valid |aStyleFont| and |aUseProvidedRootEmSize| must be true so
+// that we can get the length from |aStyleFont|.
static nscoord CalcLengthWith(const nsCSSValue& aValue,
nscoord aFontSize,
const nsStyleFont* aStyleFont,
@@ -409,8 +414,8 @@
"not a length or calc unit");
NS_ASSERTION(aStyleFont || aStyleContext,
"Must have style data");
- NS_ASSERTION(!aStyleFont || !aStyleContext,
- "Duplicate sources of data");
+ NS_ASSERTION(aStyleContext || aUseProvidedRootEmSize,
+ "Must have style context or specify aUseProvidedRootEmSize");
NS_ASSERTION(aPresContext, "Must have prescontext");
if (aValue.IsFixedLengthUnit()) {
@@ -505,21 +510,13 @@
} else {
// This is not the root element or we are calculating something other
// than font size, so rem is relative to the root element's font size.
- RefPtr rootStyle;
- const nsStyleFont *rootStyleFont = styleFont;
- Element* docElement = aPresContext->Document()->GetRootElement();
-
- if (docElement) {
- nsIFrame* rootFrame = docElement->GetPrimaryFrame();
- if (rootFrame) {
- rootStyle = rootFrame->StyleContext();
- } else {
- rootStyle = aPresContext->StyleSet()->ResolveStyleFor(docElement,
- nullptr);
- }
- rootStyleFont = rootStyle->StyleFont();
+ // Find the root style context by walking up the style context tree.
+ nsStyleContext* rootStyle = aStyleContext;
+ while (rootStyle->GetParent()) {
+ rootStyle = rootStyle->GetParent();
}
+ const nsStyleFont *rootStyleFont = rootStyle->StyleFont();
rootFontSize = rootStyleFont->mFont.size;
}
@@ -3199,15 +3196,19 @@
const nscoord mParentSize;
const nsStyleFont* const mParentFont;
nsPresContext* const mPresContext;
+ nsStyleContext* const mStyleContext;
const bool mAtRoot;
RuleNodeCacheConditions& mConditions;
SetFontSizeCalcOps(nscoord aParentSize, const nsStyleFont* aParentFont,
- nsPresContext* aPresContext, bool aAtRoot,
+ nsPresContext* aPresContext,
+ nsStyleContext* aStyleContext,
+ bool aAtRoot,
RuleNodeCacheConditions& aConditions)
: mParentSize(aParentSize),
mParentFont(aParentFont),
mPresContext(aPresContext),
+ mStyleContext(aStyleContext),
mAtRoot(aAtRoot),
mConditions(aConditions)
{
@@ -3222,7 +3223,7 @@
// between us and the parent is simply ignored.
size = CalcLengthWith(aValue, mParentSize,
mParentFont,
- nullptr, mPresContext, mAtRoot,
+ mStyleContext, mPresContext, mAtRoot,
true, mConditions);
if (!aValue.IsRelativeLengthUnit() && mParentFont->mAllowZoom) {
size = nsStyleFont::ZoomText(mPresContext, size);
@@ -3246,6 +3247,7 @@
/* static */ void
nsRuleNode::SetFontSize(nsPresContext* aPresContext,
+ nsStyleContext* aContext,
const nsRuleData* aRuleData,
const nsStyleFont* aFont,
const nsStyleFont* aParentFont,
@@ -3312,7 +3314,8 @@
sizeValue->GetUnit() == eCSSUnit_Percent ||
sizeValue->IsCalcUnit()) {
SetFontSizeCalcOps ops(aParentSize, aParentFont,
- aPresContext, aAtRoot,
+ aPresContext, aContext,
+ aAtRoot,
aConditions);
*aSize = css::ComputeCalc(*sizeValue, ops);
if (*aSize < 0) {
@@ -3658,7 +3661,7 @@
aFont->mScriptMinSize =
CalcLengthWith(*scriptMinSizeValue, aParentFont->mSize,
aParentFont,
- nullptr, aPresContext, atRoot, true,
+ aContext, aPresContext, atRoot, true /* aUseUserFontSet */,
aConditions);
}
@@ -3900,7 +3903,8 @@
scriptLevelAdjustedParentSize !=
scriptLevelAdjustedUnconstrainedParentSize;
- SetFontSize(aPresContext, aRuleData, aFont, aParentFont,
+ SetFontSize(aPresContext, aContext,
+ aRuleData, aFont, aParentFont,
&aFont->mSize,
systemFont, aParentFont->mSize, scriptLevelAdjustedParentSize,
aUsedStartStruct, atRoot, aConditions);
@@ -3930,7 +3934,8 @@
// already called SetUncacheable.
RuleNodeCacheConditions unconstrainedConditions;
- SetFontSize(aPresContext, aRuleData, aFont, aParentFont,
+ SetFontSize(aPresContext, aContext,
+ aRuleData, aFont, aParentFont,
&aFont->mScriptUnconstrainedSize,
systemFont, aParentFont->mScriptUnconstrainedSize,
scriptLevelAdjustedUnconstrainedParentSize,
diff -Nru firefox-50.0.2+build1/layout/style/nsRuleNode.h firefox-50.1.0+build2/layout/style/nsRuleNode.h
--- firefox-50.0.2+build1/layout/style/nsRuleNode.h 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/layout/style/nsRuleNode.h 2016-12-09 08:27:47.000000000 +0000
@@ -755,6 +755,7 @@
// helpers for |ComputeFontData| that need access to |mNoneBits|:
static void SetFontSize(nsPresContext* aPresContext,
+ nsStyleContext* aContext,
const nsRuleData* aRuleData,
const nsStyleFont* aFont,
const nsStyleFont* aParentFont,
diff -Nru firefox-50.0.2+build1/layout/style/xbl-marquee/xbl-marquee.xml firefox-50.1.0+build2/layout/style/xbl-marquee/xbl-marquee.xml
--- firefox-50.0.2+build1/layout/style/xbl-marquee/xbl-marquee.xml 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/layout/style/xbl-marquee/xbl-marquee.xml 2016-12-09 08:27:47.000000000 +0000
@@ -285,6 +285,12 @@
return true;
}
+ // attribute event handlers should only be added if the
+ // document's CSP allows it.
+ if (!document.inlineScriptAllowedByCSP) {
+ return true;
+ }
+
if (this._ignoreNextCall) {
return this._ignoreNextCall = false;
}
diff -Nru firefox-50.0.2+build1/mobile/android/installer/package-manifest.in firefox-50.1.0+build2/mobile/android/installer/package-manifest.in
--- firefox-50.0.2+build1/mobile/android/installer/package-manifest.in 2016-11-30 08:51:03.000000000 +0000
+++ firefox-50.1.0+build2/mobile/android/installer/package-manifest.in 2016-12-09 08:27:46.000000000 +0000
@@ -304,6 +304,8 @@
@BINPATH@/components/TooltipTextProvider.manifest
@BINPATH@/components/NetworkGeolocationProvider.manifest
@BINPATH@/components/NetworkGeolocationProvider.js
+@BINPATH@/components/EditorUtils.manifest
+@BINPATH@/components/EditorUtils.js
@BINPATH@/components/extensions.manifest
@BINPATH@/components/utils.manifest
@BINPATH@/components/simpleServices.js
diff -Nru firefox-50.0.2+build1/netwerk/base/ArrayBufferInputStream.cpp firefox-50.1.0+build2/netwerk/base/ArrayBufferInputStream.cpp
--- firefox-50.0.2+build1/netwerk/base/ArrayBufferInputStream.cpp 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/base/ArrayBufferInputStream.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -13,7 +13,6 @@
ArrayBufferInputStream::ArrayBufferInputStream()
: mBufferLength(0)
-, mOffset(0)
, mPos(0)
, mClosed(false)
{
@@ -33,11 +32,16 @@
return NS_ERROR_FAILURE;
}
- mArrayBuffer.emplace(aCx, arrayBuffer);
-
uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer);
- mOffset = std::min(buflen, aByteOffset);
- mBufferLength = std::min(buflen - mOffset, aLength);
+ uint32_t offset = std::min(buflen, aByteOffset);
+ mBufferLength = std::min(buflen - offset, aLength);
+
+ mArrayBuffer = mozilla::MakeUnique(mBufferLength);
+
+ JS::AutoCheckCannotGC nogc;
+ bool isShared;
+ char* src = (char*) JS_GetArrayBufferData(arrayBuffer, &isShared, nogc) + offset;
+ memcpy(&mArrayBuffer[0], src, mBufferLength);
return NS_OK;
}
@@ -55,8 +59,7 @@
return NS_BASE_STREAM_CLOSED;
}
if (mArrayBuffer) {
- uint32_t buflen = JS_GetArrayBufferByteLength(mArrayBuffer->get());
- *aCount = buflen ? buflen - mPos : 0;
+ *aCount = mBufferLength ? mBufferLength - mPos : 0;
} else {
*aCount = 0;
}
@@ -86,34 +89,14 @@
while (mPos < mBufferLength) {
uint32_t remaining = mBufferLength - mPos;
MOZ_ASSERT(mArrayBuffer);
- uint32_t byteLength = JS_GetArrayBufferByteLength(mArrayBuffer->get());
- if (byteLength == 0) {
- mClosed = true;
- return NS_BASE_STREAM_CLOSED;
- }
- // If you change the size of this buffer, please also remember to
- // update test_arraybufferinputstream.html.
- char buffer[8192];
- uint32_t count = std::min(std::min(aCount, remaining), uint32_t(mozilla::ArrayLength(buffer)));
+ uint32_t count = std::min(aCount, remaining);
if (count == 0) {
break;
}
- // It is just barely possible that writer() will detach the ArrayBuffer's
- // data, setting its length to zero. Or move the data to a different memory
- // area. (This would only happen in a subclass that passed something other
- // than NS_CopySegmentToBuffer as 'writer'). So copy the data out into a
- // holding area before passing it to writer().
- {
- JS::AutoCheckCannotGC nogc;
- bool isShared;
- char* src = (char*) JS_GetArrayBufferData(mArrayBuffer->get(), &isShared, nogc) + mOffset + mPos;
- MOZ_ASSERT(!isShared); // Because ArrayBuffer
- memcpy(buffer, src, count);
- }
uint32_t written;
- nsresult rv = writer(this, closure, buffer, *result, count, &written);
+ nsresult rv = writer(this, closure, &mArrayBuffer[0] + mPos, *result, count, &written);
if (NS_FAILED(rv)) {
// InputStreams do not propagate errors to caller.
return NS_OK;
diff -Nru firefox-50.0.2+build1/netwerk/base/ArrayBufferInputStream.h firefox-50.1.0+build2/netwerk/base/ArrayBufferInputStream.h
--- firefox-50.0.2+build1/netwerk/base/ArrayBufferInputStream.h 2016-11-30 08:51:04.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/base/ArrayBufferInputStream.h 2016-12-09 08:27:47.000000000 +0000
@@ -9,6 +9,7 @@
#include "nsIArrayBufferInputStream.h"
#include "js/Value.h"
#include "mozilla/Maybe.h"
+#include "mozilla/UniquePtr.h"
#define NS_ARRAYBUFFERINPUTSTREAM_CONTRACTID "@mozilla.org/io/arraybuffer-input-stream;1"
#define NS_ARRAYBUFFERINPUTSTREAM_CID \
@@ -28,10 +29,9 @@
private:
virtual ~ArrayBufferInputStream() {}
- mozilla::Maybe > mArrayBuffer;
- uint32_t mBufferLength; // length of slice
- uint32_t mOffset; // permanent offset from start of actual buffer
- uint32_t mPos; // offset from start of slice
+ mozilla::UniquePtr mArrayBuffer;
+ uint32_t mBufferLength;
+ uint32_t mPos;
bool mClosed;
};
diff -Nru firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelChild.cpp firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelChild.cpp
--- firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelChild.cpp 2016-11-30 08:51:05.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelChild.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -204,10 +204,10 @@
// to, so we fall through.
if (mKeptAlive && mRefCnt == 1 && mIPCOpen) {
mKeptAlive = false;
- // Send_delete calls NeckoChild::DeallocPHttpChannel, which will release
- // again to refcount==0
- PHttpChannelChild::Send__delete__(this);
- return 0;
+ // We send a message to the parent, which calls SendDelete, and then the
+ // child calling Send__delete__() to finally drop the refcount to 0.
+ SendDeletingChannel();
+ return 1;
}
if (mRefCnt == 0) {
@@ -920,9 +920,9 @@
mKeptAlive = true;
SendDocumentChannelCleanup();
} else {
- // This calls NeckoChild::DeallocPHttpChannelChild(), which deletes |this| if IPDL
- // holds the last reference. Don't rely on |this| existing after here.
- PHttpChannelChild::Send__delete__(this);
+ // The parent process will respond by sending a DeleteSelf message and
+ // making sure not to send any more messages after that.
+ SendDeletingChannel();
}
}
@@ -1108,12 +1108,8 @@
HandleAsyncAbort();
if (mIPCOpen) {
- PHttpChannelChild::Send__delete__(this);
+ SendDeletingChannel();
}
- // WARNING: DO NOT RELY ON |THIS| EXISTING ANY MORE!
- //
- // NeckoChild::DeallocPHttpChannelChild() may have been called, which deletes
- // |this| if IPDL holds the last reference.
}
void
@@ -1144,12 +1140,96 @@
return true;
}
+bool
+HttpChannelChild::RecvFinishInterceptedRedirect()
+{
+ // Hold a ref to this to keep it from being deleted by Send__delete__()
+ RefPtr self(this);
+ Send__delete__(this);
+
+ // The IPDL connection was torn down by a interception logic in
+ // CompleteRedirectSetup, and we need to call FinishInterceptedRedirect.
+ NS_DispatchToMainThread(NewRunnableMethod(this, &HttpChannelChild::FinishInterceptedRedirect));
+
+ return true;
+}
+
void
HttpChannelChild::DeleteSelf()
{
+ // Hold a ref to this to keep it from being deleted by Send__delete__()
+ RefPtr self(this);
Send__delete__(this);
}
+class OverrideRunnable : public Runnable {
+public:
+ RefPtr mChannel;
+ RefPtr mNewChannel;
+ RefPtr mListener;
+ nsCOMPtr mInput;
+ nsAutoPtr mHead;
+
+ OverrideRunnable(HttpChannelChild* aChannel,
+ HttpChannelChild* aNewChannel,
+ InterceptStreamListener* aListener,
+ nsIInputStream* aInput,
+ nsAutoPtr& aHead)
+ : mChannel(aChannel)
+ , mNewChannel(aNewChannel)
+ , mListener(aListener)
+ , mInput(aInput)
+ , mHead(aHead)
+ {
+ }
+
+ NS_IMETHOD Run() override {
+ bool ret = mChannel->Redirect3Complete(this);
+
+ // If the method returns false, it means the IPDL connection is being
+ // asyncly torn down and reopened, and OverrideWithSynthesizedResponse
+ // will be called later from FinishInterceptedRedirect. This object will
+ // be assigned to HttpChannelChild::mOverrideRunnable in order to do so.
+ // If it is true, we can call the method right now.
+ if (ret) {
+ OverrideWithSynthesizedResponse();
+ }
+
+ return NS_OK;
+ }
+
+ void OverrideWithSynthesizedResponse() {
+ if (mNewChannel) {
+ mNewChannel->OverrideWithSynthesizedResponse(mHead, mInput, mListener);
+ }
+ }
+};
+
+void HttpChannelChild::FinishInterceptedRedirect()
+{
+ nsresult rv;
+ if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
+ MOZ_ASSERT(!mInterceptedRedirectContext, "the context should be null!");
+ rv = AsyncOpen2(mInterceptedRedirectListener);
+ } else {
+ rv = AsyncOpen(mInterceptedRedirectListener, mInterceptedRedirectContext);
+ }
+ mInterceptedRedirectListener = nullptr;
+ mInterceptedRedirectContext = nullptr;
+
+ if (mInterceptingChannel) {
+ mInterceptingChannel->CleanupRedirectingChannel(rv);
+ mInterceptingChannel = nullptr;
+ }
+
+ if (mOverrideRunnable) {
+ RefPtr override =
+ static_cast(mOverrideRunnable.get());
+ override->OverrideWithSynthesizedResponse();
+ mOverrideRunnable = nullptr;
+ }
+}
+
bool
HttpChannelChild::RecvReportSecurityMessage(const nsString& messageTag,
const nsString& messageCategory)
@@ -1351,7 +1431,7 @@
{
public:
explicit Redirect3Event(HttpChannelChild* child) : mChild(child) {}
- void Run() { mChild->Redirect3Complete(); }
+ void Run() { mChild->Redirect3Complete(nullptr); }
private:
HttpChannelChild* mChild;
};
@@ -1427,17 +1507,45 @@
return true;
}
-void
-HttpChannelChild::Redirect3Complete()
+// Returns true if has actually completed the redirect and cleaned up the
+// channel, or false the interception logic kicked in and we need to asyncly
+// call FinishInterceptedRedirect and CleanupRedirectingChannel.
+// The argument is an optional OverrideRunnable that we pass to the redirected
+// channel.
+bool
+HttpChannelChild::Redirect3Complete(OverrideRunnable* aRunnable)
{
LOG(("HttpChannelChild::Redirect3Complete [this=%p]\n", this));
nsresult rv = NS_OK;
+ nsCOMPtr chan = do_QueryInterface(mRedirectChannelChild);
+ RefPtr httpChannelChild = static_cast(chan.get());
// Chrome channel has been AsyncOpen'd. Reflect this in child.
- if (mRedirectChannelChild)
+ if (mRedirectChannelChild) {
+ if (httpChannelChild) {
+ httpChannelChild->mOverrideRunnable = aRunnable;
+ httpChannelChild->mInterceptingChannel = this;
+ }
rv = mRedirectChannelChild->CompleteRedirectSetup(mListener,
mListenerContext);
+ }
+
+ if (!httpChannelChild || !httpChannelChild->mShouldParentIntercept) {
+ // The redirect channel either isn't a HttpChannelChild, or the interception
+ // logic wasn't triggered, so we can clean it up right here.
+ CleanupRedirectingChannel(rv);
+ if (httpChannelChild) {
+ httpChannelChild->mOverrideRunnable = nullptr;
+ httpChannelChild->mInterceptingChannel = nullptr;
+ }
+ return true;
+ }
+ return false;
+}
+void
+HttpChannelChild::CleanupRedirectingChannel(nsresult rv)
+{
// Redirecting to new channel: shut this down and init new channel
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nullptr, NS_BINDING_ABORTED);
@@ -1515,12 +1623,26 @@
// AsyncOpen but was intercepted and suspended. We must tear it down and start
// fresh - we will intercept the child channel this time, before creating a new
// parent channel unnecessarily.
- PHttpChannelChild::Send__delete__(this);
- if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
- MOZ_ASSERT(!aContext, "aContext should be null!");
- return AsyncOpen2(listener);
- }
- return AsyncOpen(listener, aContext);
+
+ // Since this method is called from RecvRedirect3Complete which itself is
+ // called from either OnRedirectVerifyCallback via OverrideRunnable, or from
+ // RecvRedirect3Complete. The order of events must always be:
+ // 1. Teardown the IPDL connection
+ // 2. AsyncOpen the connection again
+ // 3. Cleanup the redirecting channel (the one calling Redirect3Complete)
+ // 4. [optional] Call OverrideWithSynthesizedResponse on the redirected
+ // channel if the call came from OverrideRunnable.
+ mInterceptedRedirectListener = listener;
+ mInterceptedRedirectContext = aContext;
+
+ // This will send a message to the parent notifying it that we are closing
+ // down. After closing the IPC channel, we will proceed to execute
+ // FinishInterceptedRedirect() which AsyncOpen's the channel again.
+ SendFinishInterceptedRedirect();
+
+ // XXX valentin: The interception logic should be rewritten to avoid
+ // calling AsyncOpen on the channel _after_ we call Send__delete__()
+ return NS_OK;
}
/*
@@ -1549,34 +1671,6 @@
// HttpChannelChild::nsIAsyncVerifyRedirectCallback
//-----------------------------------------------------------------------------
-class OverrideRunnable : public Runnable {
- RefPtr mChannel;
- RefPtr mNewChannel;
- RefPtr mListener;
- nsCOMPtr mInput;
- nsAutoPtr mHead;
-
-public:
- OverrideRunnable(HttpChannelChild* aChannel,
- HttpChannelChild* aNewChannel,
- InterceptStreamListener* aListener,
- nsIInputStream* aInput,
- nsAutoPtr& aHead)
- : mChannel(aChannel)
- , mNewChannel(aNewChannel)
- , mListener(aListener)
- , mInput(aInput)
- , mHead(aHead)
- {
- }
-
- NS_IMETHOD Run() {
- mChannel->Redirect3Complete();
- mNewChannel->OverrideWithSynthesizedResponse(mHead, mInput, mListener);
- return NS_OK;
- }
-};
-
NS_IMETHODIMP
HttpChannelChild::OnRedirectVerifyCallback(nsresult result)
{
@@ -1603,9 +1697,10 @@
if (mRedirectingForSubsequentSynthesizedResponse) {
nsCOMPtr httpChannelChild = do_QueryInterface(mRedirectChannelChild);
- MOZ_ASSERT(httpChannelChild);
RefPtr redirectedChannel =
static_cast(httpChannelChild.get());
+ // redirectChannel will be NULL if mRedirectChannelChild isn't a
+ // nsIHttpChannelChild (it could be a DataChannelChild).
RefPtr streamListener =
new InterceptStreamListener(redirectedChannel, mListenerContext);
diff -Nru firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelChild.h firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelChild.h
--- firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelChild.h 2016-11-30 08:51:05.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelChild.h 2016-12-09 08:27:48.000000000 +0000
@@ -145,6 +145,7 @@
bool RecvFlushedForDiversion() override;
bool RecvDivertMessages() override;
bool RecvDeleteSelf() override;
+ bool RecvFinishInterceptedRedirect() override;
bool RecvReportSecurityMessage(const nsString& messageTag,
const nsString& messageCategory) override;
@@ -245,6 +246,17 @@
// is synthesized.
bool mSuspendParentAfterSynthesizeResponse;
+ // Needed to call AsyncOpen in FinishInterceptedRedirect
+ nsCOMPtr mInterceptedRedirectListener;
+ nsCOMPtr mInterceptedRedirectContext;
+ // Needed to call CleanupRedirectingChannel in FinishInterceptedRedirect
+ RefPtr mInterceptingChannel;
+ // Used to call OverrideWithSynthesizedResponse in FinishInterceptedRedirect
+ RefPtr mOverrideRunnable;
+
+ void FinishInterceptedRedirect();
+ void CleanupRedirectingChannel(nsresult rv);
+
// true after successful AsyncOpen until OnStopRequest completes.
bool RemoteChannelExists() { return mIPCOpen && !mKeptAlive; }
@@ -284,7 +296,7 @@
const nsHttpResponseHead& responseHead,
const nsACString& securityInfoSerialization,
const nsACString& channelId);
- void Redirect3Complete();
+ bool Redirect3Complete(OverrideRunnable* aRunnable);
void DeleteSelf();
// Create a a new channel to be used in a redirection, based on the provided
diff -Nru firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelParent.cpp firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelParent.cpp
--- firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelParent.cpp 2016-11-30 08:51:05.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelParent.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -1296,11 +1296,14 @@
}
nsHttpResponseHead *responseHead = mChannel->GetResponseHead();
- bool result = SendRedirect1Begin(registrarId, uriParams, redirectFlags,
- responseHead ? *responseHead
- : nsHttpResponseHead(),
- secInfoSerialization,
- channelId);
+ bool result = false;
+ if (!mIPCClosed) {
+ result = SendRedirect1Begin(registrarId, uriParams, redirectFlags,
+ responseHead ? *responseHead
+ : nsHttpResponseHead(),
+ secInfoSerialization,
+ channelId);
+ }
if (!result) {
// Bug 621446 investigation
mSentRedirect1BeginFailed = true;
@@ -1653,6 +1656,24 @@
return rv;
}
+bool
+HttpChannelParent::RecvDeletingChannel()
+{
+ // We need to ensure that the parent channel will not be sending any more IPC
+ // messages after this, as the child is going away. DoSendDeleteSelf will
+ // set mIPCClosed = true;
+ return DoSendDeleteSelf();
+}
+
+bool
+HttpChannelParent::RecvFinishInterceptedRedirect()
+{
+ // We make sure not to send any more messages until the IPC channel is torn
+ // down by the child.
+ mIPCClosed = true;
+ return SendFinishInterceptedRedirect();
+}
+
//-----------------------------------------------------------------------------
// HttpChannelSecurityWarningReporter
//-----------------------------------------------------------------------------
diff -Nru firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelParent.h firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelParent.h
--- firefox-50.0.2+build1/netwerk/protocol/http/HttpChannelParent.h 2016-11-30 08:51:05.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/protocol/http/HttpChannelParent.h 2016-12-09 08:27:48.000000000 +0000
@@ -185,6 +185,9 @@
// Calls SendDeleteSelf and sets mIPCClosed to true because we should not
// send any more messages after that. Bug 1274886
bool DoSendDeleteSelf();
+ // Called to notify the parent channel to not send any more IPC messages.
+ virtual bool RecvDeletingChannel() override;
+ virtual bool RecvFinishInterceptedRedirect() override;
private:
void UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurityInfoOut);
diff -Nru firefox-50.0.2+build1/netwerk/protocol/http/nsHttpChunkedDecoder.cpp firefox-50.1.0+build2/netwerk/protocol/http/nsHttpChunkedDecoder.cpp
--- firefox-50.0.2+build1/netwerk/protocol/http/nsHttpChunkedDecoder.cpp 2016-11-30 08:51:05.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/protocol/http/nsHttpChunkedDecoder.cpp 2016-12-09 08:27:48.000000000 +0000
@@ -96,14 +96,18 @@
char *p = static_cast(memchr(buf, '\n', count));
if (p) {
*p = 0;
- if ((p > buf) && (*(p-1) == '\r')) // eliminate a preceding CR
+ count = p - buf; // new length
+ *bytesConsumed = count + 1; // length + newline
+ if ((p > buf) && (*(p-1) == '\r')) { // eliminate a preceding CR
*(p-1) = 0;
- *bytesConsumed = p - buf + 1;
+ count--;
+ }
// make buf point to the full line buffer to parse
if (!mLineBuf.IsEmpty()) {
- mLineBuf.Append(buf);
+ mLineBuf.Append(buf, count);
buf = (char *) mLineBuf.get();
+ count = mLineBuf.Length();
}
if (mWaitEOF) {
diff -Nru firefox-50.0.2+build1/netwerk/protocol/http/PHttpChannel.ipdl firefox-50.1.0+build2/netwerk/protocol/http/PHttpChannel.ipdl
--- firefox-50.0.2+build1/netwerk/protocol/http/PHttpChannel.ipdl 2016-11-30 08:51:05.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/protocol/http/PHttpChannel.ipdl 2016-12-09 08:27:48.000000000 +0000
@@ -85,6 +85,10 @@
async RemoveCorsPreflightCacheEntry(URIParams uri,
PrincipalInfo requestingPrincipal);
+ // After receiving this message, the parent calls SendDeleteSelf, and makes
+ // sure not to send any more messages after that.
+ async DeletingChannel();
+
async __delete__();
child:
@@ -158,6 +162,13 @@
// Tell the child to issue a deprecation warning.
async IssueDeprecationWarning(uint32_t warning, bool asError);
+
+both:
+ // After receiving this message, the parent calls SendDeleteSelf, and makes
+ // sure not to send any more messages after that. When receiving this message,
+ // the child will call Send__delete__() and complete the steps required to
+ // finish the redirect.
+ async FinishInterceptedRedirect();
};
diff -Nru firefox-50.0.2+build1/netwerk/test/mochitests/test_arraybufferinputstream.html firefox-50.1.0+build2/netwerk/test/mochitests/test_arraybufferinputstream.html
--- firefox-50.0.2+build1/netwerk/test/mochitests/test_arraybufferinputstream.html 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/netwerk/test/mochitests/test_arraybufferinputstream.html 2016-12-09 08:27:48.000000000 +0000
@@ -19,6 +19,7 @@
var ab = new ArrayBuffer(4000);
var ta = new Uint8Array(ab);
ta[0] = 'a'.charCodeAt(0);
+ ta[1] = 'b'.charCodeAt(0);
const Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci, Cr = SpecialPowers.Cr;
var abis = Cc["@mozilla.org/io/arraybuffer-input-stream;1"]
@@ -41,13 +42,11 @@
try
{
- sis.read(1);
- ok(false, "reading from stream shouldn't have worked");
+ is(sis.read(1), "b", "should read 'b' after detaching buffer");
}
catch (e)
{
- ok(e.result === Cr.NS_BASE_STREAM_CLOSED,
- "detaching underneath an input stream should close it");
+ ok(false, "reading from stream should have worked");
}
// A regression test for bug 1265076. Previously, overflowing
diff -Nru firefox-50.0.2+build1/parser/html/jArray.h firefox-50.1.0+build2/parser/html/jArray.h
--- firefox-50.0.2+build1/parser/html/jArray.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/parser/html/jArray.h 2016-12-09 08:27:48.000000000 +0000
@@ -50,12 +50,12 @@
L length;
static jArray newJArray(L const len) {
MOZ_ASSERT(len >= 0, "Negative length.");
- jArray newArray = { new T[len], len };
+ jArray newArray = { new T[size_t(len)], len };
return newArray;
}
static jArray newFallibleJArray(L const len) {
MOZ_ASSERT(len >= 0, "Negative length.");
- T* a = new (mozilla::fallible) T[len];
+ T* a = new (mozilla::fallible) T[size_t(len)];
jArray newArray = { a, a ? len : 0 };
return newArray;
}
diff -Nru firefox-50.0.2+build1/parser/html/nsHtml5ArrayCopy.h firefox-50.1.0+build2/parser/html/nsHtml5ArrayCopy.h
--- firefox-50.0.2+build1/parser/html/nsHtml5ArrayCopy.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/parser/html/nsHtml5ArrayCopy.h 2016-12-09 08:27:48.000000000 +0000
@@ -36,43 +36,43 @@
static inline void
arraycopy(char16_t* source, int32_t sourceOffset, char16_t* target, int32_t targetOffset, int32_t length)
{
- memcpy(&(target[targetOffset]), &(source[sourceOffset]), length * sizeof(char16_t));
+ memcpy(&(target[targetOffset]), &(source[sourceOffset]), size_t(length) * sizeof(char16_t));
}
static inline void
arraycopy(char16_t* source, char16_t* target, int32_t length)
{
- memcpy(target, source, length * sizeof(char16_t));
+ memcpy(target, source, size_t(length) * sizeof(char16_t));
}
static inline void
arraycopy(int32_t* source, int32_t* target, int32_t length)
{
- memcpy(target, source, length * sizeof(int32_t));
+ memcpy(target, source, size_t(length) * sizeof(int32_t));
}
static inline void
arraycopy(nsString** source, nsString** target, int32_t length)
{
- memcpy(target, source, length * sizeof(nsString*));
+ memcpy(target, source, size_t(length) * sizeof(nsString*));
}
static inline void
arraycopy(nsHtml5AttributeName** source, nsHtml5AttributeName** target, int32_t length)
{
- memcpy(target, source, length * sizeof(nsHtml5AttributeName*));
+ memcpy(target, source, size_t(length) * sizeof(nsHtml5AttributeName*));
}
static inline void
arraycopy(nsHtml5StackNode** source, nsHtml5StackNode** target, int32_t length)
{
- memcpy(target, source, length * sizeof(nsHtml5StackNode*));
+ memcpy(target, source, size_t(length) * sizeof(nsHtml5StackNode*));
}
static inline void
arraycopy(nsHtml5StackNode** arr, int32_t sourceOffset, int32_t targetOffset, int32_t length)
{
- memmove(&(arr[targetOffset]), &(arr[sourceOffset]), length * sizeof(nsHtml5StackNode*));
+ memmove(&(arr[targetOffset]), &(arr[sourceOffset]), size_t(length) * sizeof(nsHtml5StackNode*));
}
};
#endif // nsHtml5ArrayCopy_h
diff -Nru firefox-50.0.2+build1/parser/html/nsHtml5TokenizerCppSupplement.h firefox-50.1.0+build2/parser/html/nsHtml5TokenizerCppSupplement.h
--- firefox-50.0.2+build1/parser/html/nsHtml5TokenizerCppSupplement.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/parser/html/nsHtml5TokenizerCppSupplement.h 2016-12-09 08:27:48.000000000 +0000
@@ -4,39 +4,56 @@
#include "mozilla/Likely.h"
+// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
+// is 2^30. Note that this is counting char16_t units. The underlying
+// bytes will be twice that, but they fit even in 32-bit size_t even
+// if a contiguous chunk of memory of that size is pretty unlikely to
+// be available on a 32-bit system.
+#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
+
bool
nsHtml5Tokenizer::EnsureBufferSpace(int32_t aLength)
{
- MOZ_ASSERT(aLength >= 0, "Negative length.");
+ MOZ_RELEASE_ASSERT(aLength >= 0, "Negative length.");
+ if (aLength > MAX_POWER_OF_TWO_IN_INT32) {
+ // Can't happen when loading from network.
+ return false;
+ }
+ CheckedInt worstCase(strBufLen);
+ worstCase += aLength;
+ worstCase += charRefBufLen;
// Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
// Adding to the general worst case instead of only the
// TreeBuilder-exposed worst case to avoid re-introducing a bug when
// unifying the tokenizer and tree builder buffers in the future.
- size_t worstCase = size_t(strBufLen) +
- size_t(aLength) +
- size_t(charRefBufLen) +
- size_t(2);
- if (worstCase > INT32_MAX) {
- // Since we index into the buffer using int32_t due to the Java heritage
- // of the code, let's treat this as OOM.
+ worstCase += 2;
+ if (!worstCase.isValid()) {
+ return false;
+ }
+ if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
return false;
}
// TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
// so that the call below becomes unnecessary.
- tokenHandler->EnsureBufferSpace(worstCase);
+ if (!tokenHandler->EnsureBufferSpace(worstCase.value())) {
+ return false;
+ }
if (!strBuf) {
- // Add one to round to the next power of two to avoid immediate
- // reallocation once there are a few characters in the buffer.
- strBuf = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase + 1));
+ if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
+ // Add one to round to the next power of two to avoid immediate
+ // reallocation once there are a few characters in the buffer.
+ worstCase += 1;
+ }
+ strBuf = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
if (!strBuf) {
return false;
}
- } else if (worstCase > size_t(strBuf.length)) {
- jArray newBuf = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase));
+ } else if (worstCase.value() > strBuf.length) {
+ jArray newBuf = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
if (!newBuf) {
return false;
}
- memcpy(newBuf,strBuf, sizeof(char16_t) * strBufLen);
+ memcpy(newBuf, strBuf, sizeof(char16_t) * size_t(strBufLen));
strBuf = newBuf;
}
return true;
diff -Nru firefox-50.0.2+build1/parser/html/nsHtml5TreeBuilderCppSupplement.h firefox-50.1.0+build2/parser/html/nsHtml5TreeBuilderCppSupplement.h
--- firefox-50.0.2+build1/parser/html/nsHtml5TreeBuilderCppSupplement.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/parser/html/nsHtml5TreeBuilderCppSupplement.h 2016-12-09 08:27:48.000000000 +0000
@@ -961,30 +961,42 @@
charBufferLen += aLength;
}
+// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
+// is 2^30. Note that this is counting char16_t units. The underlying
+// bytes will be twice that, but they fit even in 32-bit size_t even
+// if a contiguous chunk of memory of that size is pretty unlikely to
+// be available on a 32-bit system.
+#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
+
bool
-nsHtml5TreeBuilder::EnsureBufferSpace(size_t aLength)
+nsHtml5TreeBuilder::EnsureBufferSpace(int32_t aLength)
{
// TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
// so that this method becomes unnecessary.
- size_t worstCase = size_t(charBufferLen) + aLength;
- if (worstCase > INT32_MAX) {
- // Since we index into the buffer using int32_t due to the Java heritage
- // of the code, let's treat this as OOM.
+ CheckedInt worstCase(charBufferLen);
+ worstCase += aLength;
+ if (!worstCase.isValid()) {
+ return false;
+ }
+ if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
return false;
}
if (!charBuffer) {
- // Add one to round to the next power of two to avoid immediate
- // reallocation once there are a few characters in the buffer.
- charBuffer = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase + 1));
+ if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
+ // Add one to round to the next power of two to avoid immediate
+ // reallocation once there are a few characters in the buffer.
+ worstCase += 1;
+ }
+ charBuffer = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
if (!charBuffer) {
return false;
}
- } else if (worstCase > size_t(charBuffer.length)) {
- jArray newBuf = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase));
+ } else if (worstCase.value() > charBuffer.length) {
+ jArray newBuf = jArray::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
if (!newBuf) {
return false;
}
- memcpy(newBuf, charBuffer, sizeof(char16_t) * charBufferLen);
+ memcpy(newBuf, charBuffer, sizeof(char16_t) * size_t(charBufferLen));
charBuffer = newBuf;
}
return true;
diff -Nru firefox-50.0.2+build1/parser/html/nsHtml5TreeBuilderHSupplement.h firefox-50.1.0+build2/parser/html/nsHtml5TreeBuilderHSupplement.h
--- firefox-50.0.2+build1/parser/html/nsHtml5TreeBuilderHSupplement.h 2016-11-30 08:51:06.000000000 +0000
+++ firefox-50.1.0+build2/parser/html/nsHtml5TreeBuilderHSupplement.h 2016-12-09 08:27:48.000000000 +0000
@@ -138,7 +138,7 @@
* next call to this method.
* @return true if successful; false if out of memory
*/
- bool EnsureBufferSpace(size_t aLength);
+ bool EnsureBufferSpace(int32_t aLength);
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
diff -Nru firefox-50.0.2+build1/SOURCE_CHANGESET firefox-50.1.0+build2/SOURCE_CHANGESET
--- firefox-50.0.2+build1/SOURCE_CHANGESET 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/SOURCE_CHANGESET 2016-12-09 08:27:51.000000000 +0000
@@ -1 +1 @@
-cc272f7d48d3544ffaf242b51430ffcf3a932a29
\ No newline at end of file
+8612c3320053b796678921f8f23358e3e9df997e
\ No newline at end of file
diff -Nru firefox-50.0.2+build1/testing/docker/recipes/run-task firefox-50.1.0+build2/testing/docker/recipes/run-task
--- firefox-50.0.2+build1/testing/docker/recipes/run-task 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/docker/recipes/run-task 2016-12-09 08:27:45.000000000 +0000
@@ -23,6 +23,7 @@
import os
import pwd
import re
+import socket
import stat
import subprocess
import sys
@@ -109,7 +110,7 @@
except ValueError:
print_line(b'vcs', 'invalid JSON in hg fingerprint secret')
sys.exit(1)
- except urllib2.URLError:
+ except (urllib2.URLError, socket.timeout):
print_line(b'vcs', 'Unable to retrieve current hg.mozilla.org fingerprint'
'using the secret service, using fallback instead.')
# XXX This fingerprint will not be accurate if running on an old
diff -Nru firefox-50.0.2+build1/testing/firefox-ui/tests/puppeteer/test_windows.py firefox-50.1.0+build2/testing/firefox-ui/tests/puppeteer/test_windows.py
--- firefox-50.0.2+build1/testing/firefox-ui/tests/puppeteer/test_windows.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/firefox-ui/tests/puppeteer/test_windows.py 2016-12-09 08:27:45.000000000 +0000
@@ -38,7 +38,7 @@
finally:
BaseWindowTestCase.tearDown(self)
- def test_windows(self):
+ def test_switch_to(self):
url = self.marionette.absolute_url('layout/mozilla.html')
# Open two more windows
@@ -81,6 +81,18 @@
self.assertEqual(len(self.windows.all), 1)
+ def test_switch_to_unknown_window_type(self):
+ def open_by_js(_):
+ with self.marionette.using_context('chrome'):
+ self.marionette.execute_script("""
+ window.open('chrome://browser/content/safeMode.xul', '_blank',
+ 'chrome,centerscreen,resizable=no');
+ """)
+
+ win = self.browser.open_window(callback=open_by_js, expected_window_class=BaseWindow)
+ win.close()
+ self.browser.switch_to()
+
class TestBaseWindow(BaseWindowTestCase):
diff -Nru firefox-50.0.2+build1/testing/mozharness/configs/releases/postrelease_firefox_release.py firefox-50.1.0+build2/testing/mozharness/configs/releases/postrelease_firefox_release.py
--- firefox-50.0.2+build1/testing/mozharness/configs/releases/postrelease_firefox_release.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/mozharness/configs/releases/postrelease_firefox_release.py 2016-12-09 08:27:45.000000000 +0000
@@ -7,7 +7,7 @@
],
"repo": {
"repo": "https://hg.mozilla.org/releases/mozilla-release",
- "branch": "FIREFOX_50_0_2_RELBRANCH",
+ "branch": "default",
"dest": "mozilla-release",
"vcs": "hg",
},
diff -Nru firefox-50.0.2+build1/testing/mozharness/configs/releases/updates_firefox_release.py firefox-50.1.0+build2/testing/mozharness/configs/releases/updates_firefox_release.py
--- firefox-50.0.2+build1/testing/mozharness/configs/releases/updates_firefox_release.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/mozharness/configs/releases/updates_firefox_release.py 2016-12-09 08:27:45.000000000 +0000
@@ -3,7 +3,7 @@
"log_name": "updates_release",
"repo": {
"repo": "https://hg.mozilla.org/build/tools",
- "branch": "FIREFOX_50_0_2",
+ "branch": "default",
"dest": "tools",
"vcs": "hg",
},
diff -Nru firefox-50.0.2+build1/testing/mozharness/scripts/release/generate-checksums.py firefox-50.1.0+build2/testing/mozharness/scripts/release/generate-checksums.py
--- firefox-50.0.2+build1/testing/mozharness/scripts/release/generate-checksums.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/mozharness/scripts/release/generate-checksums.py 2016-12-09 08:27:46.000000000 +0000
@@ -130,6 +130,7 @@
r"^.*\.mar$",
r"^.*Setup.*\.exe$",
r"^.*\.xpi$",
+ r"^.*fennec.*\.apk$",
]
def _get_bucket_name(self):
diff -Nru firefox-50.0.2+build1/testing/mozharness/scripts/release/push-candidate-to-releases.py firefox-50.1.0+build2/testing/mozharness/scripts/release/push-candidate-to-releases.py
--- firefox-50.0.2+build1/testing/mozharness/scripts/release/push-candidate-to-releases.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/mozharness/scripts/release/push-candidate-to-releases.py 2016-12-09 08:27:46.000000000 +0000
@@ -49,6 +49,7 @@
r"^.*/host.*$",
r"^.*/mar-tools/.*$",
r"^.*robocop.apk$",
+ r"^.*bouncer.apk$",
r"^.*contrib.*",
r"^.*/beetmover-checksums/.*$",
],
diff -Nru firefox-50.0.2+build1/testing/puppeteer/firefox/firefox_puppeteer/ui/windows.py firefox-50.1.0+build2/testing/puppeteer/firefox/firefox_puppeteer/ui/windows.py
--- firefox-50.0.2+build1/testing/puppeteer/firefox/firefox_puppeteer/ui/windows.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/puppeteer/firefox/firefox_puppeteer/ui/windows.py 2016-12-09 08:27:46.000000000 +0000
@@ -106,12 +106,7 @@
# Retrieve window type to determine the type of chrome window
if handle != self.marionette.current_chrome_window_handle:
self.switch_to(handle)
-
- window_type = Wait(self.marionette).until(
- lambda mn: mn.get_window_type(),
- message='Cannot get window type for chrome window handle "%s"' % handle
- )
-
+ window_type = self.marionette.get_window_type()
finally:
# Ensure to switch back to the original window
if handle != current_handle:
@@ -120,8 +115,7 @@
if window_type in self.windows_map:
window = self.windows_map[window_type](lambda: self.marionette, handle)
else:
- raise errors.UnknownWindowError('Unknown window type "%s" for handle: "%s"' %
- (window_type, handle))
+ window = BaseWindow(lambda: self.marionette, handle)
if expected_class is not None and type(window) is not expected_class:
raise errors.UnexpectedWindowTypeError('Expected window "%s" but got "%s"' %
diff -Nru firefox-50.0.2+build1/testing/web-platform/harness/wptrunner/browsers/firefox.py firefox-50.1.0+build2/testing/web-platform/harness/wptrunner/browsers/firefox.py
--- firefox-50.0.2+build1/testing/web-platform/harness/wptrunner/browsers/firefox.py 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/testing/web-platform/harness/wptrunner/browsers/firefox.py 2016-12-09 08:27:46.000000000 +0000
@@ -63,7 +63,7 @@
**kwargs):
executor_kwargs = base_executor_kwargs(test_type, server_config,
cache_manager, **kwargs)
- executor_kwargs["close_after_done"] = True
+ executor_kwargs["close_after_done"] = test_type != "reftest"
if kwargs["timeout_multiplier"] is None:
if test_type == "reftest":
if run_info_data["debug"] or run_info_data.get("asan"):
diff -Nru firefox-50.0.2+build1/toolkit/components/places/nsNavHistory.cpp firefox-50.1.0+build2/toolkit/components/places/nsNavHistory.cpp
--- firefox-50.0.2+build1/toolkit/components/places/nsNavHistory.cpp 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/toolkit/components/places/nsNavHistory.cpp 2016-12-09 08:27:47.000000000 +0000
@@ -3363,7 +3363,8 @@
// URI
if (NS_SUCCEEDED(aQuery->GetHasUri(&hasIt)) && hasIt) {
- clause.Condition("h.url =").Param(":uri");
+ clause.Condition("h.url_hash = hash(").Param(":uri").Str(")")
+ .Condition("h.url =").Param(":uri");
}
// annotation
diff -Nru firefox-50.0.2+build1/toolkit/modules/WebChannel.jsm firefox-50.1.0+build2/toolkit/modules/WebChannel.jsm
--- firefox-50.0.2+build1/toolkit/modules/WebChannel.jsm 2016-11-30 08:51:10.000000000 +0000
+++ firefox-50.1.0+build2/toolkit/modules/WebChannel.jsm 2016-12-09 08:27:48.000000000 +0000
@@ -171,7 +171,7 @@
// The permission manager operates on domain names rather than true
// origins (bug 1066517). To mitigate that, we explicitly check that
// the scheme is https://.
- let uri = Services.io.newURI(requestPrincipal.origin, null, null);
+ let uri = Services.io.newURI(requestPrincipal.originNoSuffix, null, null);
if (uri.scheme != "https") {
return false;
}
@@ -183,7 +183,7 @@
} else {
// a simple URI, so just check for an exact match.
this._originCheckCallback = requestPrincipal => {
- return originOrPermission.prePath === requestPrincipal.origin;
+ return originOrPermission.prePath === requestPrincipal.originNoSuffix;
}
}
this._originOrPermission = originOrPermission;
diff -Nru firefox-50.0.2+build1/widget/cocoa/TextInputHandler.h firefox-50.1.0+build2/widget/cocoa/TextInputHandler.h
--- firefox-50.0.2+build1/widget/cocoa/TextInputHandler.h 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/widget/cocoa/TextInputHandler.h 2016-12-09 08:27:49.000000000 +0000
@@ -521,6 +521,10 @@
bool mKeyPressHandled;
// Whether the key event causes other key events via IME or something.
bool mCausedOtherKeyEvents;
+ // Whether the key event causes composition change or committing
+ // composition. So, even if InsertText() is called, this may be false
+ // if it dispatches keypress event.
+ bool mCompositionDispatched;
KeyEventState() : mKeyEvent(nullptr)
{
@@ -559,11 +563,13 @@
mKeyPressDispatched = false;
mKeyPressHandled = false;
mCausedOtherKeyEvents = false;
+ mCompositionDispatched = false;
}
bool IsDefaultPrevented() const
{
- return mKeyDownHandled || mKeyPressHandled || mCausedOtherKeyEvents;
+ return mKeyDownHandled || mKeyPressHandled || mCausedOtherKeyEvents ||
+ mCompositionDispatched;
}
bool CanDispatchKeyPressEvent() const
diff -Nru firefox-50.0.2+build1/widget/cocoa/TextInputHandler.mm firefox-50.1.0+build2/widget/cocoa/TextInputHandler.mm
--- firefox-50.0.2+build1/widget/cocoa/TextInputHandler.mm 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/widget/cocoa/TextInputHandler.mm 2016-12-09 08:27:49.000000000 +0000
@@ -1682,10 +1682,12 @@
MOZ_LOG(gLog, LogLevel::Info,
("%p TextInputHandler::HandleKeyDownEvent, "
- "keydown handled=%s, keypress handled=%s, causedOtherKeyEvents=%s",
+ "keydown handled=%s, keypress handled=%s, causedOtherKeyEvents=%s, "
+ "compositionDispatched=%s",
this, TrueOrFalse(currentKeyEvent->mKeyDownHandled),
TrueOrFalse(currentKeyEvent->mKeyPressHandled),
- TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents)));
+ TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents),
+ TrueOrFalse(currentKeyEvent->mCompositionDispatched)));
return currentKeyEvent->IsDefaultPrevented();
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
@@ -2119,7 +2121,7 @@
"aReplacementRange=%p { location=%llu, length=%llu }, "
"IsIMEComposing()=%s, IgnoreIMEComposition()=%s, "
"keyevent=%p, keydownHandled=%s, keypressDispatched=%s, "
- "causedOtherKeyEvents=%s",
+ "causedOtherKeyEvents=%s, compositionDispatched=%s",
this, GetCharacters([aAttrString string]), aReplacementRange,
aReplacementRange ? aReplacementRange->location : 0,
aReplacementRange ? aReplacementRange->length : 0,
@@ -2130,7 +2132,9 @@
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyPressDispatched) : "N/A",
currentKeyEvent ?
- TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A"));
+ TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A",
+ currentKeyEvent ?
+ TrueOrFalse(currentKeyEvent->mCompositionDispatched) : "N/A"));
if (IgnoreIMEComposition()) {
return;
@@ -2188,15 +2192,15 @@
return;
}
- if (str.Length() != 1 || IsIMEComposing()) {
+ if (str.Length() != 1 || IsIMEComposing() ||
+ (currentKeyEvent && currentKeyEvent->mCompositionDispatched)) {
InsertTextAsCommittingComposition(aAttrString, aReplacementRange);
// For now, consume keypress events when we dispatch the string with a
// composition for preventing to dispatch keypress events later.
// TODO: When there is a currentKeyEvent, we should dispatch keypress
// events even if the length of the string is over 1.
if (currentKeyEvent) {
- currentKeyEvent->mKeyPressHandled = true;
- currentKeyEvent->mKeyPressDispatched = true;
+ currentKeyEvent->mCompositionDispatched = true;
}
return;
}
diff -Nru firefox-50.0.2+build1/widget/ContentCache.cpp firefox-50.1.0+build2/widget/ContentCache.cpp
--- firefox-50.0.2+build1/widget/ContentCache.cpp 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/widget/ContentCache.cpp 2016-12-09 08:27:49.000000000 +0000
@@ -829,7 +829,7 @@
return false;
}
- if ((aRoundToExistingOffset && mTextRectArray.IsValid()) ||
+ if ((aRoundToExistingOffset && mTextRectArray.HasRects()) ||
mTextRectArray.IsOverlappingWith(aOffset, aLength)) {
aUnionTextRect =
mTextRectArray.GetUnionRectAsFarAsPossible(aOffset, aLength,
@@ -1173,7 +1173,8 @@
bool aRoundToExistingOffset) const
{
LayoutDeviceIntRect rect;
- if (!aRoundToExistingOffset && !IsOverlappingWith(aOffset, aLength)) {
+ if (!HasRects() ||
+ (!aRoundToExistingOffset && !IsOverlappingWith(aOffset, aLength))) {
return rect;
}
uint32_t startOffset = std::max(aOffset, mStart);
@@ -1184,6 +1185,9 @@
if (aRoundToExistingOffset && endOffset < mStart + 1) {
endOffset = mStart + 1;
}
+ if (NS_WARN_IF(endOffset < startOffset)) {
+ return rect;
+ }
for (uint32_t i = 0; i < endOffset - startOffset; i++) {
rect = rect.Union(mRects[startOffset - mStart + i]);
}
diff -Nru firefox-50.0.2+build1/widget/ContentCache.h firefox-50.1.0+build2/widget/ContentCache.h
--- firefox-50.0.2+build1/widget/ContentCache.h 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/widget/ContentCache.h 2016-12-09 08:27:49.000000000 +0000
@@ -182,6 +182,10 @@
CheckedInt(mStart) + mRects.Length();
return endOffset.isValid();
}
+ bool HasRects() const
+ {
+ return IsValid() && !mRects.IsEmpty();
+ }
uint32_t StartOffset() const
{
NS_ASSERTION(IsValid(),
@@ -213,7 +217,7 @@
}
bool IsOverlappingWith(uint32_t aOffset, uint32_t aLength) const
{
- if (!IsValid() || aOffset == UINT32_MAX) {
+ if (!HasRects() || aOffset == UINT32_MAX || !aLength) {
return false;
}
CheckedInt endOffset =
@@ -221,7 +225,7 @@
if (NS_WARN_IF(!endOffset.isValid())) {
return false;
}
- return aOffset <= EndOffset() && endOffset.value() >= mStart;
+ return aOffset < EndOffset() && endOffset.value() > mStart;
}
LayoutDeviceIntRect GetRect(uint32_t aOffset) const;
LayoutDeviceIntRect GetUnionRect(uint32_t aOffset, uint32_t aLength) const;
diff -Nru firefox-50.0.2+build1/widget/gtk/mozgtk/mozgtk.c firefox-50.1.0+build2/widget/gtk/mozgtk/mozgtk.c
--- firefox-50.0.2+build1/widget/gtk/mozgtk/mozgtk.c 2016-11-30 08:51:07.000000000 +0000
+++ firefox-50.1.0+build2/widget/gtk/mozgtk/mozgtk.c 2016-12-09 08:27:49.000000000 +0000
@@ -609,3 +609,22 @@
STUB(gdkx_visual_get)
STUB(gtk_object_get_type)
#endif
+
+#ifndef GTK3_SYMBOLS
+// Only define the following workaround when using GTK3, which we detect
+// by checking if GTK3 stubs are not provided.
+#include
+// Bug 1271100
+// We need to trick system Cairo into not using the XShm extension due to
+// a race condition in it that results in frequent BadAccess errors. Cairo
+// relies upon XShmQueryExtension to initially detect if XShm is available.
+// So we define our own stub that always indicates XShm not being present.
+// mozgtk loads before libXext/libcairo and so this stub will take priority.
+// Our tree usage goes through xcb and remains unaffected by this.
+MOZ_EXPORT Bool
+XShmQueryExtension(Display* aDisplay)
+{
+ return False;
+}
+#endif
+