diff --git a/accessible/generic/ApplicationAccessible.cpp b/accessible/generic/ApplicationAccessible.cpp index dd8b82bac333..c81e1e3aeaee 100644 --- a/accessible/generic/ApplicationAccessible.cpp +++ b/accessible/generic/ApplicationAccessible.cpp @@ -165,17 +165,16 @@ ApplicationAccessible::Init() // that all root accessibles are stored in application accessible children // array. - nsGlobalWindow::WindowByIdTable* windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowOuter::OuterWindowByIdTable* windowsById = + nsGlobalWindowOuter::GetWindowsTable(); if (!windowsById) { return; } for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { - nsGlobalWindow* window = iter.Data(); - if (window->GetDocShell() && window->IsOuterWindow() && - window->IsRootOuterWindow()) { + nsGlobalWindowOuter* window = iter.Data(); + if (window->GetDocShell() && window->IsRootOuterWindow()) { nsCOMPtr docNode = window->GetExtantDoc(); if (docNode) { diff --git a/accessible/generic/RootAccessible.cpp b/accessible/generic/RootAccessible.cpp index bf1434c5f343..d949eef94ab2 100644 --- a/accessible/generic/RootAccessible.cpp +++ b/accessible/generic/RootAccessible.cpp @@ -485,7 +485,8 @@ RootAccessible::RelationByType(RelationType aType) return DocAccessibleWrap::RelationByType(aType); if (nsPIDOMWindowOuter* rootWindow = mDocumentNode->GetWindow()) { - nsCOMPtr contentWindow = nsGlobalWindow::Cast(rootWindow)->GetContent(); + nsCOMPtr contentWindow = + nsGlobalWindowOuter::Cast(rootWindow)->GetContent(); if (contentWindow) { nsCOMPtr contentDocumentNode = contentWindow->GetDoc(); if (contentDocumentNode) { diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index ace53c0c565f..268c73b07adb 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -429,6 +429,7 @@ pref("permissions.default.camera", 0); pref("permissions.default.microphone", 0); pref("permissions.default.geo", 0); pref("permissions.default.desktop-notification", 0); +pref("permissions.default.shortcuts", 0); // handle links targeting new windows // 1=current window/tab, 2=new window, 3=new tab in most recent window diff --git a/browser/base/content/test/permissions/browser.ini b/browser/base/content/test/permissions/browser.ini index 3fe359a85399..4a146a3b2ba5 100644 --- a/browser/base/content/test/permissions/browser.ini +++ b/browser/base/content/test/permissions/browser.ini @@ -5,6 +5,7 @@ support-files= [browser_canvas_fingerprinting_resistance.js] [browser_permissions.js] +[browser_reservedkey.js] [browser_temporary_permissions.js] support-files = temporary_permissions_subframe.html diff --git a/browser/base/content/test/permissions/browser_permissions.js b/browser/base/content/test/permissions/browser_permissions.js index c503eff3f83c..4834b960b29b 100644 --- a/browser/base/content/test/permissions/browser_permissions.js +++ b/browser/base/content/test/permissions/browser_permissions.js @@ -176,3 +176,43 @@ add_task(async function testPermissionIcons() { SitePermissions.remove(gBrowser.currentURI, "camera"); }); }); + +add_task(async function testPermissionShortcuts() { + await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function(browser) { + browser.focus(); + + await new Promise(r => { + SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 0]]}, r); + }); + + async function tryKey(desc, expectedValue) { + await EventUtils.synthesizeAndWaitKey("c", { accelKey: true }); + let result = await ContentTask.spawn(browser, null, function() { + return content.wrappedJSObject.gKeyPresses; + }); + is(result, expectedValue, desc); + } + + await tryKey("pressed with default permissions", 1); + + SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.BLOCK); + await tryKey("pressed when site blocked", 1); + + SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.ALLOW); + await tryKey("pressed when site allowed", 2); + + SitePermissions.remove(gBrowser.currentURI, "shortcuts"); + await new Promise(r => { + SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, r); + }); + + await tryKey("pressed when globally blocked", 2); + SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.ALLOW); + await tryKey("pressed when globally blocked but site allowed", 3); + + SitePermissions.set(gBrowser.currentURI, "shortcuts", SitePermissions.BLOCK); + await tryKey("pressed when globally blocked and site blocked", 3); + + SitePermissions.remove(gBrowser.currentURI, "shortcuts"); + }); +}); diff --git a/browser/base/content/test/permissions/browser_reservedkey.js b/browser/base/content/test/permissions/browser_reservedkey.js new file mode 100644 index 000000000000..d932f7743188 --- /dev/null +++ b/browser/base/content/test/permissions/browser_reservedkey.js @@ -0,0 +1,92 @@ +add_task(async function test_reserved_shortcuts() { + /* eslint-disable no-unsanitized/property */ + let keyset = ` + + + + `; + + let container = document.createElement("box"); + container.innerHTML = keyset; + document.documentElement.appendChild(container); + /* eslint-enable no-unsanitized/property */ + + const pageUrl = "data:text/html,
Test
"; + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl); + + EventUtils.synthesizeKey("O", { shiftKey: true }); + EventUtils.synthesizeKey("P", { shiftKey: true }); + EventUtils.synthesizeKey("Q", { shiftKey: true }); + + is(document.getElementById("kt_reserved").getAttribute("count"), "1", "reserved='true' with preference off"); + is(document.getElementById("kt_notreserved").getAttribute("count"), "0", "reserved='false' with preference off"); + is(document.getElementById("kt_reserveddefault").getAttribute("count"), "0", "default reserved with preference off"); + + // Now try with reserved shortcut key handling enabled. + await new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, resolve); + }); + + EventUtils.synthesizeKey("O", { shiftKey: true }); + EventUtils.synthesizeKey("P", { shiftKey: true }); + EventUtils.synthesizeKey("Q", { shiftKey: true }); + + is(document.getElementById("kt_reserved").getAttribute("count"), "2", "reserved='true' with preference on"); + is(document.getElementById("kt_notreserved").getAttribute("count"), "0", "reserved='false' with preference on"); + is(document.getElementById("kt_reserveddefault").getAttribute("count"), "1", "default reserved with preference on"); + + document.documentElement.removeChild(container); + + await BrowserTestUtils.removeTab(tab); +}); + +// This test checks that Alt+ and F10 cannot be blocked when the preference is set. +if (navigator.platform.indexOf("Mac") == -1) { + add_task(async function test_accesskeys_menus() { + await new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, resolve); + }); + + const uri = "data:text/html,"; + let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri); + + // Pressing Alt+H should open the Help menu. + let helpPopup = document.getElementById("menu_HelpPopup"); + let popupShown = BrowserTestUtils.waitForEvent(helpPopup, "popupshown"); + EventUtils.synthesizeKey("VK_ALT", { type: "keydown" }); + EventUtils.synthesizeKey("H", { altKey: true }); + EventUtils.synthesizeKey("VK_ALT", { type: "keyup" }); + await popupShown; + + ok(true, "Help menu opened"); + + let popupHidden = BrowserTestUtils.waitForEvent(helpPopup, "popuphidden"); + helpPopup.hidePopup(); + await popupHidden; + + // Pressing F10 should focus the menubar. On Linux, the file menu should open, but on Windows, + // pressing Down will open the file menu. + let menubar = document.getElementById("main-menubar"); + let menubarActive = BrowserTestUtils.waitForEvent(menubar, "DOMMenuBarActive"); + EventUtils.sendKey("F10"); + await menubarActive; + + let filePopup = document.getElementById("menu_FilePopup"); + popupShown = BrowserTestUtils.waitForEvent(filePopup, "popupshown"); + if (navigator.platform.indexOf("Win") >= 0) { + EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" }); + } + await popupShown; + + ok(true, "File menu opened"); + + popupHidden = BrowserTestUtils.waitForEvent(filePopup, "popuphidden"); + filePopup.hidePopup(); + await popupHidden; + + await BrowserTestUtils.removeTab(tab1); + }); +} diff --git a/browser/base/content/test/permissions/permissions.html b/browser/base/content/test/permissions/permissions.html index 2e78bc4ed79a..9fc2f372c1f2 100644 --- a/browser/base/content/test/permissions/permissions.html +++ b/browser/base/content/test/permissions/permissions.html @@ -6,7 +6,10 @@ - + + diff --git a/browser/extensions/pdfjs/README.mozilla b/browser/extensions/pdfjs/README.mozilla index b0b5fbd28f6d..0214a9999d17 100644 --- a/browser/extensions/pdfjs/README.mozilla +++ b/browser/extensions/pdfjs/README.mozilla @@ -1,5 +1,5 @@ This is the PDF.js project output, https://github.com/mozilla/pdf.js -Current extension version is: 2.0.104 +Current extension version is: 2.0.106 -Taken from upstream commit: 012d0756 +Taken from upstream commit: 0052dc2b diff --git a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm index b308d99c5c92..488475af273f 100644 --- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm +++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm @@ -149,7 +149,7 @@ function getLocalizedString(strings, id, property) { // PDF data storage function PdfDataListener(length) { this.length = length; // less than 0, if length is unknown - this.buffer = null; + this.buffers = []; this.loaded = 0; } @@ -157,15 +157,7 @@ PdfDataListener.prototype = { append: function PdfDataListener_append(chunk) { // In most of the cases we will pass data as we receive it, but at the // beginning of the loading we may accumulate some data. - if (!this.buffer) { - this.buffer = new Uint8Array(chunk); - } else { - var buffer = this.buffer; - var newBuffer = new Uint8Array(buffer.length + chunk.length); - newBuffer.set(buffer); - newBuffer.set(chunk, buffer.length); - this.buffer = newBuffer; - } + this.buffers.push(chunk); this.loaded += chunk.length; if (this.length >= 0 && this.length < this.loaded) { this.length = -1; // reset the length, server is giving incorrect one @@ -173,9 +165,26 @@ PdfDataListener.prototype = { this.onprogress(this.loaded, this.length >= 0 ? this.length : void 0); }, readData: function PdfDataListener_readData() { - var result = this.buffer; - this.buffer = null; - return result; + if (this.buffers.length === 0) { + return null; + } + if (this.buffers.length === 1) { + return this.buffers.pop(); + } + // There are multiple buffers that need to be combined into a single + // buffer. + let combinedLength = 0; + for (let buffer of this.buffers) { + combinedLength += buffer.length; + } + let combinedArray = new Uint8Array(combinedLength); + let writeOffset = 0; + while (this.buffers.length) { + let buffer = this.buffers.shift(); + combinedArray.set(buffer, writeOffset); + writeOffset += buffer.length; + } + return combinedArray; }, finish: function PdfDataListener_finish() { this.isDataReady = true; @@ -878,8 +887,9 @@ PdfStreamConverter.prototype = { var binaryStream = this.binaryStream; binaryStream.setInputStream(aInputStream); - var chunk = binaryStream.readByteArray(aCount); - this.dataListener.append(chunk); + let chunk = new ArrayBuffer(aCount); + binaryStream.readArrayBuffer(aCount, chunk); + this.dataListener.append(new Uint8Array(chunk)); }, // nsIRequestObserver::onStartRequest diff --git a/browser/extensions/pdfjs/content/build/pdf.js b/browser/extensions/pdfjs/content/build/pdf.js index 38302f7982d7..83b70c742b5e 100644 --- a/browser/extensions/pdfjs/content/build/pdf.js +++ b/browser/extensions/pdfjs/content/build/pdf.js @@ -1961,7 +1961,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) { if (worker.destroyed) { return Promise.reject(new Error('Worker was destroyed')); } - let apiVersion = '2.0.104'; + let apiVersion = '2.0.106'; source.disableAutoFetch = (0, _dom_utils.getDefaultSetting)('disableAutoFetch'); source.disableStream = (0, _dom_utils.getDefaultSetting)('disableStream'); source.chunkedViewerLoading = !!pdfDataRangeTransport; @@ -3258,8 +3258,8 @@ var InternalRenderTask = function InternalRenderTaskClosure() { }(); var version, build; { - exports.version = version = '2.0.104'; - exports.build = build = '012d0756'; + exports.version = version = '2.0.106'; + exports.build = build = '0052dc2b'; } exports.getDocument = getDocument; exports.LoopbackPort = LoopbackPort; @@ -4993,8 +4993,8 @@ exports.SVGGraphics = SVGGraphics; "use strict"; -var pdfjsVersion = '2.0.104'; -var pdfjsBuild = '012d0756'; +var pdfjsVersion = '2.0.106'; +var pdfjsBuild = '0052dc2b'; var pdfjsSharedUtil = __w_pdfjs_require__(0); var pdfjsDisplayGlobal = __w_pdfjs_require__(13); var pdfjsDisplayAPI = __w_pdfjs_require__(3); @@ -8118,8 +8118,8 @@ if (!_global_scope2.default.PDFJS) { } var PDFJS = _global_scope2.default.PDFJS; { - PDFJS.version = '2.0.104'; - PDFJS.build = '012d0756'; + PDFJS.version = '2.0.106'; + PDFJS.build = '0052dc2b'; } PDFJS.pdfBug = false; if (PDFJS.verbosity !== undefined) { diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js index b3ad36852a4d..ebfa19839b4e 100644 --- a/browser/extensions/pdfjs/content/build/pdf.worker.js +++ b/browser/extensions/pdfjs/content/build/pdf.worker.js @@ -23284,8 +23284,8 @@ exports.PostScriptCompiler = PostScriptCompiler; "use strict"; -var pdfjsVersion = '2.0.104'; -var pdfjsBuild = '012d0756'; +var pdfjsVersion = '2.0.106'; +var pdfjsBuild = '0052dc2b'; var pdfjsCoreWorker = __w_pdfjs_require__(18); exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler; @@ -23480,7 +23480,7 @@ var WorkerMessageHandler = { var cancelXHRs = null; var WorkerTasks = []; let apiVersion = docParams.apiVersion; - let workerVersion = '2.0.104'; + let workerVersion = '2.0.106'; if (apiVersion !== null && apiVersion !== workerVersion) { throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); } diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 1a6d818ba4a3..a603ac0f14bd 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -206,7 +206,6 @@ @RESPATH@/components/dom_notification.xpt @RESPATH@/components/dom_html.xpt @RESPATH@/components/dom_offline.xpt -@RESPATH@/components/dom_json.xpt @RESPATH@/components/dom_payments.xpt @RESPATH@/components/dom_power.xpt @RESPATH@/components/dom_push.xpt diff --git a/browser/locales/en-US/chrome/browser/sitePermissions.properties b/browser/locales/en-US/chrome/browser/sitePermissions.properties index c576cbac2bdb..8670162268b5 100644 --- a/browser/locales/en-US/chrome/browser/sitePermissions.properties +++ b/browser/locales/en-US/chrome/browser/sitePermissions.properties @@ -35,5 +35,6 @@ permission.screen.label = Share the Screen permission.install.label = Install Add-ons permission.popup.label = Open Pop-up Windows permission.geo.label = Access Your Location +permission.shortcuts.label = Override Keyboard Shortcuts permission.focus-tab-by-prompt.label = Switch to this Tab permission.persistent-storage.label = Store Data in Persistent Storage diff --git a/browser/modules/SitePermissions.jsm b/browser/modules/SitePermissions.jsm index 4e1e42663e55..704a1472a6bb 100644 --- a/browser/modules/SitePermissions.jsm +++ b/browser/modules/SitePermissions.jsm @@ -626,7 +626,11 @@ var gPermissionObject = { }, "persistent-storage": { exactHostMatch: true - } + }, + + "shortcuts": { + states: [ SitePermissions.ALLOW, SitePermissions.BLOCK ], + }, }; // Delete this entry while being pre-off diff --git a/browser/modules/test/browser/browser_SitePermissions.js b/browser/modules/test/browser/browser_SitePermissions.js index db371603f569..bf07126ef757 100644 --- a/browser/modules/test/browser/browser_SitePermissions.js +++ b/browser/modules/test/browser/browser_SitePermissions.js @@ -25,10 +25,13 @@ add_task(async function testGetAllPermissionDetailsForBrowser() { let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri.spec); + Services.prefs.setIntPref("permissions.default.shortcuts", 2); + SitePermissions.set(uri, "camera", SitePermissions.ALLOW); SitePermissions.set(uri, "cookie", SitePermissions.ALLOW_COOKIES_FOR_SESSION); SitePermissions.set(uri, "popup", SitePermissions.BLOCK); SitePermissions.set(uri, "geo", SitePermissions.ALLOW, SitePermissions.SCOPE_SESSION); + SitePermissions.set(uri, "shortcuts", SitePermissions.ALLOW); let permissions = SitePermissions.getAllPermissionDetailsForBrowser(tab.linkedBrowser); @@ -71,9 +74,20 @@ add_task(async function testGetAllPermissionDetailsForBrowser() { scope: SitePermissions.SCOPE_SESSION, }); + let shortcuts = permissions.find(({id}) => id === "shortcuts"); + Assert.deepEqual(shortcuts, { + id: "shortcuts", + label: "Override Keyboard Shortcuts", + state: SitePermissions.ALLOW, + scope: SitePermissions.SCOPE_PERSISTENT, + }); + SitePermissions.remove(uri, "cookie"); SitePermissions.remove(uri, "popup"); SitePermissions.remove(uri, "geo"); + SitePermissions.remove(uri, "shortcuts"); + + Services.prefs.clearUserPref("permissions.default.shortcuts"); await BrowserTestUtils.removeTab(gBrowser.selectedTab); }); diff --git a/browser/modules/test/unit/test_SitePermissions.js b/browser/modules/test/unit/test_SitePermissions.js index 3311748d527e..826075244581 100644 --- a/browser/modules/test/unit/test_SitePermissions.js +++ b/browser/modules/test/unit/test_SitePermissions.js @@ -10,7 +10,7 @@ const STORAGE_MANAGER_ENABLED = Services.prefs.getBoolPref("browser.storageManag add_task(async function testPermissionsListing() { let expectedPermissions = ["camera", "cookie", "desktop-notification", "focus-tab-by-prompt", - "geo", "image", "install", "microphone", "popup", "screen"]; + "geo", "image", "install", "microphone", "popup", "screen", "shortcuts"]; if (STORAGE_MANAGER_ENABLED) { // The persistent-storage permission is still only pref-on on Nightly // so we add it only when it's pref-on. @@ -58,6 +58,18 @@ add_task(async function testGetAllByURI() { SitePermissions.set(uri, "addon", SitePermissions.BLOCK); Assert.deepEqual(SitePermissions.getAllByURI(uri), []); SitePermissions.remove(uri, "addon"); + + Assert.equal(Services.prefs.getIntPref("permissions.default.shortcuts"), 0); + SitePermissions.set(uri, "shortcuts", SitePermissions.BLOCK); + + // Customized preference should have been enabled, but the default should not. + Assert.equal(Services.prefs.getIntPref("permissions.default.shortcuts"), 0); + Assert.deepEqual(SitePermissions.getAllByURI(uri), [ + { id: "shortcuts", state: SitePermissions.BLOCK, scope: SitePermissions.SCOPE_PERSISTENT }, + ]); + + SitePermissions.remove(uri, "shortcuts"); + Services.prefs.clearUserPref("permissions.default.shortcuts"); }); add_task(async function testGetAvailableStates() { @@ -96,7 +108,7 @@ add_task(async function testExactHostMatch() { // Should remove this checking and add it as default after it is fully pref-on. exactHostMatched.push("persistent-storage"); } - let nonExactHostMatched = ["image", "cookie", "popup", "install"]; + let nonExactHostMatched = ["image", "cookie", "popup", "install", "shortcuts"]; let permissions = SitePermissions.listPermissions(); for (let permission of permissions) { diff --git a/build/build-clang/clang-win32.json b/build/build-clang/clang-win32.json index 80d931a5553c..d7f84324c5e5 100644 --- a/build/build-clang/clang-win32.json +++ b/build/build-clang/clang-win32.json @@ -13,6 +13,11 @@ "cxx": "cl.exe", "patches": [ "msvc-host-x64.patch", - "loosen-msvc-detection.patch" + "loosen-msvc-detection.patch", + "r314201.patch", + "r315677.patch", + "r316048.patch", + "r317705.patch", + "r317709.patch" ] } diff --git a/build/build-clang/clang-win64.json b/build/build-clang/clang-win64.json index 79ad4042d3d8..dcfcb52bc201 100644 --- a/build/build-clang/clang-win64.json +++ b/build/build-clang/clang-win64.json @@ -13,6 +13,11 @@ "cxx": "cl.exe", "ml": "ml64.exe", "patches": [ - "loosen-msvc-detection.patch" + "loosen-msvc-detection.patch", + "r314201.patch", + "r315677.patch", + "r316048.patch", + "r317705.patch", + "r317709.patch" ] } diff --git a/build/build-clang/r314201.patch b/build/build-clang/r314201.patch new file mode 100644 index 000000000000..fccc53c17975 --- /dev/null +++ b/build/build-clang/r314201.patch @@ -0,0 +1,54 @@ +From 71e7a8ba8994e5b1f9cc0a0986b2ef5d37ed8ad2 Mon Sep 17 00:00:00 2001 +From: Sylvestre Ledru +Date: Tue, 26 Sep 2017 11:56:43 +0000 +Subject: [PATCH] Don't move llvm.localescape outside the entry block in the + GCOV profiling pass + +Summary: +This fixes https://bugs.llvm.org/show_bug.cgi?id=34714. + +Patch by Marco Castelluccio + +Reviewers: rnk + +Reviewed By: rnk + +Subscribers: llvm-commits + +Differential Revision: https://reviews.llvm.org/D38224 + +git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314201 91177308-0d34-0410-b5e6-96231b3b80d8 +--- + lib/Transforms/Instrumentation/GCOVProfiling.cpp | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +index b2033536ac8..3154c1939ea 100644 +--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp ++++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +@@ -502,6 +502,16 @@ static bool functionHasLines(Function &F) { + return false; + } + ++static bool shouldKeepInEntry(BasicBlock::iterator It) { ++ if (isa(*It)) return true; ++ if (isa(*It)) return true; ++ if (auto *II = dyn_cast(It)) { ++ if (II->getIntrinsicID() == llvm::Intrinsic::localescape) return true; ++ } ++ ++ return false; ++} ++ + void GCOVProfiler::emitProfileNotes() { + NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); + if (!CU_Nodes) return; +@@ -537,7 +547,7 @@ void GCOVProfiler::emitProfileNotes() { + // single successor, so split the entry block to make sure of that. + BasicBlock &EntryBlock = F.getEntryBlock(); + BasicBlock::iterator It = EntryBlock.begin(); +- while (isa(*It) || isa(*It)) ++ while (shouldKeepInEntry(It)) + ++It; + EntryBlock.splitBasicBlock(It); + diff --git a/build/build-clang/r315677.patch b/build/build-clang/r315677.patch new file mode 100644 index 000000000000..8b932d6524ed --- /dev/null +++ b/build/build-clang/r315677.patch @@ -0,0 +1,67 @@ +From 44847b2e9838888e1536c90ad442a3958362139a Mon Sep 17 00:00:00 2001 +From: Marco Castelluccio +Date: Fri, 13 Oct 2017 13:49:15 +0000 +Subject: [PATCH] Disable gcov instrumentation of functions using funclet-based + exception handling + +Summary: This patch fixes the crash from https://bugs.llvm.org/show_bug.cgi?id=34659 and https://bugs.llvm.org/show_bug.cgi?id=34833. + +Reviewers: rnk, majnemer + +Reviewed By: rnk, majnemer + +Subscribers: majnemer, llvm-commits + +Differential Revision: https://reviews.llvm.org/D38223 + +git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315677 91177308-0d34-0410-b5e6-96231b3b80d8 +--- + lib/Transforms/Instrumentation/GCOVProfiling.cpp | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +index 3154c1939ea..67ca8172b0d 100644 +--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp ++++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +@@ -21,6 +21,7 @@ + #include "llvm/ADT/StringExtras.h" + #include "llvm/ADT/StringMap.h" + #include "llvm/ADT/UniqueVector.h" ++#include "llvm/Analysis/EHPersonalities.h" + #include "llvm/IR/DebugInfo.h" + #include "llvm/IR/DebugLoc.h" + #include "llvm/IR/IRBuilder.h" +@@ -502,6 +503,13 @@ static bool functionHasLines(Function &F) { + return false; + } + ++static bool isUsingFuncletBasedEH(Function &F) { ++ if (!F.hasPersonalityFn()) return false; ++ ++ EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn()); ++ return isFuncletEHPersonality(Personality); ++} ++ + static bool shouldKeepInEntry(BasicBlock::iterator It) { + if (isa(*It)) return true; + if (isa(*It)) return true; +@@ -542,6 +550,8 @@ void GCOVProfiler::emitProfileNotes() { + DISubprogram *SP = F.getSubprogram(); + if (!SP) continue; + if (!functionHasLines(F)) continue; ++ // TODO: Functions using funclet-based EH are currently not supported. ++ if (isUsingFuncletBasedEH(F)) continue; + + // gcov expects every function to start with an entry block that has a + // single successor, so split the entry block to make sure of that. +@@ -619,7 +629,10 @@ bool GCOVProfiler::emitProfileArcs() { + DISubprogram *SP = F.getSubprogram(); + if (!SP) continue; + if (!functionHasLines(F)) continue; ++ // TODO: Functions using funclet-based EH are currently not supported. ++ if (isUsingFuncletBasedEH(F)) continue; + if (!Result) Result = true; ++ + unsigned Edges = 0; + for (auto &BB : F) { + TerminatorInst *TI = BB.getTerminator(); diff --git a/build/build-clang/r316048.patch b/build/build-clang/r316048.patch new file mode 100644 index 000000000000..c7782de9992e --- /dev/null +++ b/build/build-clang/r316048.patch @@ -0,0 +1,60 @@ +From 98adaa2097783c0fe3a4c948397e3f2182dcc5d2 Mon Sep 17 00:00:00 2001 +From: Marco Castelluccio +Date: Wed, 18 Oct 2017 00:22:01 +0000 +Subject: [PATCH] Use O_BINARY when opening GCDA file on Windows + +Summary: +Fixes https://bugs.llvm.org/show_bug.cgi?id=34922. + +Apparently, the mode in **fdopen** gets simply ignored and Windows only cares about the mode of the original **open**. + +I have verified this both with the simple case from bug 34922 and with a full Firefox build. + +Reviewers: zturner + +Reviewed By: zturner + +Subscribers: llvm-commits + +Differential Revision: https://reviews.llvm.org/D38984 + +git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316048 91177308-0d34-0410-b5e6-96231b3b80d8 +--- + lib/profile/GCDAProfiling.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c +index 138af6ec4..8c92546bd 100644 +--- a/compiler-rt/lib/profile/GCDAProfiling.c ++++ b/compiler-rt/lib/profile/GCDAProfiling.c +@@ -37,6 +37,9 @@ + #ifndef MAP_FILE + #define MAP_FILE 0 + #endif ++#ifndef O_BINARY ++#define O_BINARY 0 ++#endif + #endif + + #if defined(__FreeBSD__) && defined(__i386__) +@@ -238,17 +241,17 @@ void llvm_gcda_start_file(const char *orig_filename, const char version[4], + + /* Try just opening the file. */ + new_file = 0; +- fd = open(filename, O_RDWR); ++ fd = open(filename, O_RDWR | O_BINARY); + + if (fd == -1) { + /* Try opening the file, creating it if necessary. */ + new_file = 1; + mode = "w+b"; +- fd = open(filename, O_RDWR | O_CREAT, 0644); ++ fd = open(filename, O_RDWR | O_CREAT | O_BINARY, 0644); + if (fd == -1) { + /* Try creating the directories first then opening the file. */ + __llvm_profile_recursive_mkdir(filename); +- fd = open(filename, O_RDWR | O_CREAT, 0644); ++ fd = open(filename, O_RDWR | O_CREAT | O_BINARY, 0644); + if (fd == -1) { + /* Bah! It's hopeless. */ + int errnum = errno; diff --git a/build/build-clang/r317705.patch b/build/build-clang/r317705.patch new file mode 100644 index 000000000000..a5f3c4b1e83e --- /dev/null +++ b/build/build-clang/r317705.patch @@ -0,0 +1,92 @@ +From 07e2a968c83c489c5b46efe4973114e78e1804c1 Mon Sep 17 00:00:00 2001 +From: Marco Castelluccio +Date: Wed, 8 Nov 2017 19:11:54 +0000 +Subject: [PATCH] Implement flock for Windows in compiler-rt + +Summary: +This patch implements flock for Windows, needed to make gcda writing work in a multiprocessing scenario. + +Fixes https://bugs.llvm.org/show_bug.cgi?id=34923. + +Reviewers: zturner + +Reviewed By: zturner + +Subscribers: rnk, zturner, llvm-commits + +Differential Revision: https://reviews.llvm.org/D38891 + +git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317705 91177308-0d34-0410-b5e6-96231b3b80d8 +--- + lib/profile/WindowsMMap.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 55 insertions(+), 3 deletions(-) + +diff --git a/compiler-rt/lib/profile/WindowsMMap.c b/lib/profile/WindowsMMap.c +index f81d7da53..0c534710b 100644 +--- a/compiler-rt/lib/profile/WindowsMMap.c ++++ b/compiler-rt/lib/profile/WindowsMMap.c +@@ -120,9 +120,61 @@ int msync(void *addr, size_t length, int flags) + } + + COMPILER_RT_VISIBILITY +-int flock(int fd, int operation) +-{ +- return -1; /* Not supported. */ ++int lock(HANDLE handle, DWORD lockType, BOOL blocking) { ++ DWORD flags = lockType; ++ if (!blocking) ++ flags |= LOCKFILE_FAIL_IMMEDIATELY; ++ ++ OVERLAPPED overlapped; ++ ZeroMemory(&overlapped, sizeof(OVERLAPPED)); ++ overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); ++ BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped); ++ if (!result) { ++ DWORD dw = GetLastError(); ++ ++ // In non-blocking mode, return an error if the file is locked. ++ if (!blocking && dw == ERROR_LOCK_VIOLATION) ++ return -1; // EWOULDBLOCK ++ ++ // If the error is ERROR_IO_PENDING, we need to wait until the operation ++ // finishes. Otherwise, we return an error. ++ if (dw != ERROR_IO_PENDING) ++ return -1; ++ ++ DWORD dwNumBytes; ++ if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE)) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++COMPILER_RT_VISIBILITY ++int flock(int fd, int operation) { ++ HANDLE handle = (HANDLE)_get_osfhandle(fd); ++ if (handle == INVALID_HANDLE_VALUE) ++ return -1; ++ ++ BOOL blocking = (operation & LOCK_NB) == 0; ++ int op = operation & ~LOCK_NB; ++ ++ switch (op) { ++ case LOCK_EX: ++ return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking); ++ ++ case LOCK_SH: ++ return lock(handle, 0, blocking); ++ ++ case LOCK_UN: ++ if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD)) ++ return -1; ++ break; ++ ++ default: ++ return -1; ++ } ++ ++ return 0; + } + + #undef DWORD_HI diff --git a/build/build-clang/r317709.patch b/build/build-clang/r317709.patch new file mode 100644 index 000000000000..f88502eecf69 --- /dev/null +++ b/build/build-clang/r317709.patch @@ -0,0 +1,51 @@ +From 8f15f3c70065372ce412075f5f369847b55351d2 Mon Sep 17 00:00:00 2001 +From: Marco Castelluccio +Date: Wed, 8 Nov 2017 19:21:54 +0000 +Subject: [PATCH] Add CoreOption flag to "-coverage" option to make it + available for clang-cl + +Summary: +The -coverage option is not a CoreOption, so it is not available to clang-cl. +This patch adds the CoreOption flag to "-coverage" to allow it to be used with clang-cl. + +Reviewers: rnk + +Reviewed By: rnk + +Subscribers: cfe-commits + +Differential Revision: https://reviews.llvm.org/D38221 + +git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317709 91177308-0d34-0410-b5e6-96231b3b80d8 +--- + include/clang/Driver/Options.td | 2 +- + test/Driver/coverage.c | 7 +++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + create mode 100644 test/Driver/coverage.c + +diff --git a/clang/include/clang/Driver/Options.td b/include/clang/Driver/Options.td +index 597e03b563d..01605619e02 100644 +--- a/clang/include/clang/Driver/Options.td ++++ b/clang/include/clang/Driver/Options.td +@@ -519,7 +519,7 @@ def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-round + def client__name : JoinedOrSeparate<["-"], "client_name">; + def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>; + def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">; +-def coverage : Flag<["-", "--"], "coverage">; ++def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>; + def cpp_precomp : Flag<["-"], "cpp-precomp">, Group; + def current__version : JoinedOrSeparate<["-"], "current_version">; + def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group, +diff --git a/clang/test/Driver/coverage.c b/clang/test/Driver/coverage.c +new file mode 100644 +index 00000000000..339c4a3f366 +--- /dev/null ++++ b/clang/test/Driver/coverage.c +@@ -0,0 +1,7 @@ ++// Test coverage flag. ++// ++// RUN: %clang_cl -### -coverage %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CLANG-CL-COVERAGE %s ++// CLANG-CL-COVERAGE-NOT: error: ++// CLANG-CL-COVERAGE-NOT: warning: ++// CLANG-CL-COVERAGE-NOT: argument unused ++// CLANG-CL-COVERAGE-NOT: unknown argument diff --git a/devtools/client/commandline/test/browser_cmd_pref3.js b/devtools/client/commandline/test/browser_cmd_pref3.js index d16ee87dda67..bbb3857008d3 100644 --- a/devtools/client/commandline/test/browser_cmd_pref3.js +++ b/devtools/client/commandline/test/browser_cmd_pref3.js @@ -7,9 +7,6 @@ var prefBranch = Cc["@mozilla.org/preferences-service;1"] .getService(Ci.nsIPrefService).getBranch(null) .QueryInterface(Ci.nsIPrefBranch); -var supportsString = Cc["@mozilla.org/supports-string;1"] - .createInstance(Ci.nsISupportsString); - const TEST_URI = "data:text/html;charset=utf-8,gcli-pref3"; function test() { @@ -101,9 +98,7 @@ function* spawnTest() { }, ]); - supportsString.data = remoteHostOrig; - prefBranch.setComplexValue("devtools.debugger.remote-host", - Ci.nsISupportsString, supportsString); + prefBranch.setStringPref("devtools.debugger.remote-host", remoteHostOrig); yield helpers.closeToolbar(options); yield helpers.closeTab(options); diff --git a/devtools/client/commandline/test/browser_cmd_settings.js b/devtools/client/commandline/test/browser_cmd_settings.js index 9a27fcd8fcc5..fbc56a91e5f3 100644 --- a/devtools/client/commandline/test/browser_cmd_settings.js +++ b/devtools/client/commandline/test/browser_cmd_settings.js @@ -7,9 +7,6 @@ var prefBranch = Cc["@mozilla.org/preferences-service;1"] .getService(Ci.nsIPrefService).getBranch(null) .QueryInterface(Ci.nsIPrefBranch); -var supportsString = Cc["@mozilla.org/supports-string;1"] - .createInstance(Ci.nsISupportsString); - const TEST_URI = "data:text/html;charset=utf-8,gcli-settings"; function test() { @@ -114,10 +111,7 @@ function* spawnTest() { // Cleanup prefBranch.setBoolPref("devtools.gcli.hideIntro", hideIntroOrig); prefBranch.setIntPref("devtools.editor.tabsize", tabSizeOrig); - supportsString.data = remoteHostOrig; - prefBranch.setComplexValue("devtools.debugger.remote-host", - Components.interfaces.nsISupportsString, - supportsString); + prefBranch.setStringPref("devtools.debugger.remote-host", remoteHostOrig); yield helpers.closeTab(options); } diff --git a/devtools/client/inspector/test/browser.ini b/devtools/client/inspector/test/browser.ini index 7e30d9b283f5..44466002fb26 100644 --- a/devtools/client/inspector/test/browser.ini +++ b/devtools/client/inspector/test/browser.ini @@ -93,6 +93,7 @@ subsuite = clipboard skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts [browser_inspector_highlighter-eyedropper-csp.js] [browser_inspector_highlighter-eyedropper-events.js] +skip-if = os == 'win' # bug 1413442 [browser_inspector_highlighter-eyedropper-image.js] [browser_inspector_highlighter-eyedropper-label.js] [browser_inspector_highlighter-eyedropper-show-hide.js] diff --git a/devtools/shared/gcli/source/lib/gcli/settings.js b/devtools/shared/gcli/source/lib/gcli/settings.js index 5149b4286c6e..e120006af986 100644 --- a/devtools/shared/gcli/source/lib/gcli/settings.js +++ b/devtools/shared/gcli/source/lib/gcli/settings.js @@ -31,11 +31,6 @@ XPCOMUtils.defineLazyGetter(imports, 'prefBranch', function() { return prefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch); }); -XPCOMUtils.defineLazyGetter(imports, 'supportsString', function() { - return Cc['@mozilla.org/supports-string;1'] - .createInstance(Ci.nsISupportsString); -}); - var util = require('./util/util'); /** @@ -266,10 +261,7 @@ Object.defineProperty(Setting.prototype, 'value', { break; case imports.prefBranch.PREF_STRING: - imports.supportsString.data = value; - imports.prefBranch.setComplexValue(this.name, - Ci.nsISupportsString, - imports.supportsString); + imports.prefBranch.setStringPref(this.name, value); break; default: diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 8846bfa35ee3..06afce862cd0 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -3274,7 +3274,7 @@ NS_IMETHODIMP nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent) { mCustomUserAgent = aCustomUserAgent; - RefPtr win = mScriptGlobal ? + RefPtr win = mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr; if (win) { Navigator* navigator = win->Navigator(); @@ -3779,7 +3779,7 @@ static bool ItemIsActive(nsIDocShellTreeItem* aItem) { if (nsCOMPtr window = aItem->GetWindow()) { - auto* win = nsGlobalWindow::Cast(window); + auto* win = nsGlobalWindowOuter::Cast(window); MOZ_ASSERT(win->IsOuterWindow()); if (!win->GetClosedOuter()) { return true; @@ -10619,8 +10619,8 @@ nsDocShell::InternalLoad(nsIURI* aURI, // applies to aURI. CopyFavicon(currentURI, aURI, doc->NodePrincipal(), UsePrivateBrowsing()); - RefPtr scriptGlobal = mScriptGlobal; - RefPtr win = scriptGlobal ? + RefPtr scriptGlobal = mScriptGlobal; + RefPtr win = scriptGlobal ? scriptGlobal->GetCurrentInnerWindowInternal() : nullptr; // ScrollToAnchor doesn't necessarily cause us to scroll the window; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index c097fcb1f49b..f805deaa2edf 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -77,7 +77,8 @@ typedef uint32_t ScreenOrientationInternal; class nsDocShell; class nsDOMNavigationTiming; -class nsGlobalWindow; +class nsGlobalWindowOuter; +class nsGlobalWindowInner; class nsIController; class nsIScrollableFrame; class OnLinkClickEvent; @@ -918,7 +919,7 @@ protected: nsCOMPtr mCurrentURI; nsCOMPtr mReferrerURI; uint32_t mReferrerPolicy; - RefPtr mScriptGlobal; + RefPtr mScriptGlobal; nsCOMPtr mSessionHistory; nsCOMPtr mGlobalHistory; nsCOMPtr mFind; diff --git a/docshell/test/chrome/chrome.ini b/docshell/test/chrome/chrome.ini index f5b187466748..2c07cffc67ff 100644 --- a/docshell/test/chrome/chrome.ini +++ b/docshell/test/chrome/chrome.ini @@ -53,6 +53,7 @@ support-files = [test_bug113934.xul] [test_bug215405.xul] [test_bug293235.xul] +skip-if = true # bug 1393441 [test_bug294258.xul] [test_bug298622.xul] [test_bug301397.xul] diff --git a/dom/animation/AnimationUtils.cpp b/dom/animation/AnimationUtils.cpp index 2450f0bb7c13..4ed529a135b0 100644 --- a/dom/animation/AnimationUtils.cpp +++ b/dom/animation/AnimationUtils.cpp @@ -42,7 +42,7 @@ AnimationUtils::LogAsyncAnimationFailure(nsCString& aMessage, /* static */ nsIDocument* AnimationUtils::GetCurrentRealmDocument(JSContext* aCx) { - nsGlobalWindow* win = xpc::CurrentWindowOrNull(aCx); + nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aCx); if (!win) { return nullptr; } diff --git a/dom/base/BarProps.cpp b/dom/base/BarProps.cpp index c267c13de77b..d7367e29db48 100644 --- a/dom/base/BarProps.cpp +++ b/dom/base/BarProps.cpp @@ -18,7 +18,7 @@ namespace dom { // // Basic (virtual) BarProp class implementation // -BarProp::BarProp(nsGlobalWindow* aWindow) +BarProp::BarProp(nsGlobalWindowInner* aWindow) : mDOMWindow(aWindow) { MOZ_ASSERT(aWindow->IsInnerWindow()); @@ -106,7 +106,7 @@ BarProp::GetBrowserChrome() // MenubarProp class implementation // -MenubarProp::MenubarProp(nsGlobalWindow *aWindow) +MenubarProp::MenubarProp(nsGlobalWindowInner *aWindow) : BarProp(aWindow) { } @@ -132,7 +132,7 @@ MenubarProp::SetVisible(bool aVisible, CallerType aCallerType, ErrorResult& aRv) // ToolbarProp class implementation // -ToolbarProp::ToolbarProp(nsGlobalWindow *aWindow) +ToolbarProp::ToolbarProp(nsGlobalWindowInner *aWindow) : BarProp(aWindow) { } @@ -158,7 +158,7 @@ ToolbarProp::SetVisible(bool aVisible, CallerType aCallerType, ErrorResult& aRv) // LocationbarProp class implementation // -LocationbarProp::LocationbarProp(nsGlobalWindow *aWindow) +LocationbarProp::LocationbarProp(nsGlobalWindowInner *aWindow) : BarProp(aWindow) { } @@ -186,7 +186,7 @@ LocationbarProp::SetVisible(bool aVisible, CallerType aCallerType, // PersonalbarProp class implementation // -PersonalbarProp::PersonalbarProp(nsGlobalWindow *aWindow) +PersonalbarProp::PersonalbarProp(nsGlobalWindowInner *aWindow) : BarProp(aWindow) { } @@ -215,7 +215,7 @@ PersonalbarProp::SetVisible(bool aVisible, CallerType aCallerType, // StatusbarProp class implementation // -StatusbarProp::StatusbarProp(nsGlobalWindow *aWindow) +StatusbarProp::StatusbarProp(nsGlobalWindowInner *aWindow) : BarProp(aWindow) { } @@ -243,7 +243,7 @@ StatusbarProp::SetVisible(bool aVisible, CallerType aCallerType, // ScrollbarsProp class implementation // -ScrollbarsProp::ScrollbarsProp(nsGlobalWindow *aWindow) +ScrollbarsProp::ScrollbarsProp(nsGlobalWindowInner *aWindow) : BarProp(aWindow) { } diff --git a/dom/base/BarProps.h b/dom/base/BarProps.h index eb8b674b5121..702607b96365 100644 --- a/dom/base/BarProps.h +++ b/dom/base/BarProps.h @@ -19,7 +19,7 @@ #include "nsPIDOMWindow.h" #include "mozilla/dom/BindingDeclarations.h" -class nsGlobalWindow; +class nsGlobalWindowInner; class nsIWebBrowserChrome; namespace mozilla { @@ -33,7 +33,7 @@ class BarProp : public nsISupports, public nsWrapperCache { public: - explicit BarProp(nsGlobalWindow *aWindow); + explicit BarProp(nsGlobalWindowInner *aWindow); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BarProp) @@ -56,14 +56,14 @@ protected: already_AddRefed GetBrowserChrome(); - RefPtr mDOMWindow; + RefPtr mDOMWindow; }; // Script "menubar" object class MenubarProp final : public BarProp { public: - explicit MenubarProp(nsGlobalWindow *aWindow); + explicit MenubarProp(nsGlobalWindowInner *aWindow); virtual ~MenubarProp(); virtual bool GetVisible(CallerType aCallerType, ErrorResult& aRv) override; @@ -75,7 +75,7 @@ public: class ToolbarProp final : public BarProp { public: - explicit ToolbarProp(nsGlobalWindow *aWindow); + explicit ToolbarProp(nsGlobalWindowInner *aWindow); virtual ~ToolbarProp(); virtual bool GetVisible(CallerType aCallerType, ErrorResult& aRv) override; @@ -87,7 +87,7 @@ public: class LocationbarProp final : public BarProp { public: - explicit LocationbarProp(nsGlobalWindow *aWindow); + explicit LocationbarProp(nsGlobalWindowInner *aWindow); virtual ~LocationbarProp(); virtual bool GetVisible(CallerType aCallerType, ErrorResult& aRv) override; @@ -99,7 +99,7 @@ public: class PersonalbarProp final : public BarProp { public: - explicit PersonalbarProp(nsGlobalWindow *aWindow); + explicit PersonalbarProp(nsGlobalWindowInner *aWindow); virtual ~PersonalbarProp(); virtual bool GetVisible(CallerType aCallerType, ErrorResult& aRv) override; @@ -111,7 +111,7 @@ public: class StatusbarProp final : public BarProp { public: - explicit StatusbarProp(nsGlobalWindow *aWindow); + explicit StatusbarProp(nsGlobalWindowInner *aWindow); virtual ~StatusbarProp(); virtual bool GetVisible(CallerType aCallerType, ErrorResult& aRv) override; @@ -123,7 +123,7 @@ public: class ScrollbarsProp final : public BarProp { public: - explicit ScrollbarsProp(nsGlobalWindow *aWindow); + explicit ScrollbarsProp(nsGlobalWindowInner *aWindow); virtual ~ScrollbarsProp(); virtual bool GetVisible(CallerType aCallerType, ErrorResult& aRv) override; diff --git a/dom/base/Location.cpp b/dom/base/Location.cpp index 85db41455db3..3131b8541abc 100644 --- a/dom/base/Location.cpp +++ b/dom/base/Location.cpp @@ -515,7 +515,7 @@ Location::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, nsIScriptContext* scriptContext = nullptr; nsCOMPtr win = do_QueryInterface(GetEntryGlobal()); if (win) { - scriptContext = nsGlobalWindow::Cast(win)->GetContextInternal(); + scriptContext = nsGlobalWindowInner::Cast(win)->GetContextInternal(); } if (scriptContext) { @@ -530,8 +530,7 @@ Location::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, } return SetURI(newUri, aReplace || inScriptTag); - } - + } return result; } diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index cbd56c36b959..e9b7f1450f62 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1446,7 +1446,7 @@ Navigator::GetGamepads(nsTArray >& aGamepads, return; } NS_ENSURE_TRUE_VOID(mWindow->GetDocShell()); - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); win->SetHasGamepadEventListener(true); win->GetGamepads(aGamepads); } @@ -1468,7 +1468,7 @@ Navigator::GetVRDisplays(ErrorResult& aRv) return nullptr; } - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); win->NotifyVREventListenerAdded(); nsCOMPtr go = do_QueryInterface(mWindow); @@ -1505,7 +1505,7 @@ Navigator::GetActiveVRDisplays(nsTArray>& aDisplays) const if (!mWindow || !mWindow->GetDocShell()) { return; } - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); nsTArray> displays; if (win->UpdateVRDisplays(displays)) { for (auto display : displays) { @@ -1521,7 +1521,7 @@ Navigator::NotifyVRDisplaysUpdated() { // Synchronize the VR devices and resolve the promises in // mVRGetDisplaysPromises - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); nsTArray> vrDisplays; if (win->UpdateVRDisplays(vrDisplays)) { @@ -1546,7 +1546,7 @@ VRServiceTest* Navigator::RequestVRServiceTest() { // Ensure that the Mock VR devices are not released prematurely - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); win->NotifyVREventListenerAdded(); if (!mVRServiceTest) { @@ -1558,21 +1558,21 @@ Navigator::RequestVRServiceTest() bool Navigator::IsWebVRContentDetected() const { - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); return win->IsVRContentDetected(); } bool Navigator::IsWebVRContentPresenting() const { - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); return win->IsVRContentPresenting(); } void Navigator::RequestVRPresentation(VRDisplay& aDisplay) { - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(mWindow); win->DispatchVRDisplayActivate(aDisplay.DisplayId(), VRDisplayEventReason::Requested); } diff --git a/dom/base/PostMessageEvent.cpp b/dom/base/PostMessageEvent.cpp index d1488031447f..fd5b3e3ac52e 100644 --- a/dom/base/PostMessageEvent.cpp +++ b/dom/base/PostMessageEvent.cpp @@ -29,9 +29,9 @@ namespace mozilla { namespace dom { -PostMessageEvent::PostMessageEvent(nsGlobalWindow* aSource, +PostMessageEvent::PostMessageEvent(nsGlobalWindowOuter* aSource, const nsAString& aCallerOrigin, - nsGlobalWindow* aTargetWindow, + nsGlobalWindowOuter* aTargetWindow, nsIPrincipal* aProvidedPrincipal, nsIDocument* aSourceDocument, bool aTrustedCaller) @@ -76,7 +76,7 @@ PostMessageEvent::Run() // If we bailed before this point we're going to leak mMessage, but // that's probably better than crashing. - RefPtr targetWindow; + RefPtr targetWindow; if (mTargetWindow->IsClosedOrClosing() || !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) || targetWindow->IsClosedOrClosing()) @@ -176,7 +176,7 @@ PostMessageEvent::Run() } void -PostMessageEvent::DispatchError(JSContext* aCx, nsGlobalWindow* aTargetWindow, +PostMessageEvent::DispatchError(JSContext* aCx, nsGlobalWindowInner* aTargetWindow, mozilla::dom::EventTarget* aEventTarget) { RootedDictionary init(aCx); @@ -195,7 +195,7 @@ PostMessageEvent::DispatchError(JSContext* aCx, nsGlobalWindow* aTargetWindow, } void -PostMessageEvent::Dispatch(nsGlobalWindow* aTargetWindow, Event* aEvent) +PostMessageEvent::Dispatch(nsGlobalWindowInner* aTargetWindow, Event* aEvent) { // We can't simply call dispatchEvent on the window because doing so ends // up flipping the trusted bit on the event, and we don't want that to diff --git a/dom/base/PostMessageEvent.h b/dom/base/PostMessageEvent.h index 0e16cf431f75..ce59522cdf6d 100644 --- a/dom/base/PostMessageEvent.h +++ b/dom/base/PostMessageEvent.h @@ -13,7 +13,8 @@ #include "nsTArray.h" #include "nsThreadUtils.h" -class nsGlobalWindow; +class nsGlobalWindowOuter; +class nsGlobalWindowInner; class nsIDocument; class nsIPrincipal; @@ -30,9 +31,9 @@ class PostMessageEvent final : public Runnable public: NS_DECL_NSIRUNNABLE - PostMessageEvent(nsGlobalWindow* aSource, + PostMessageEvent(nsGlobalWindowOuter* aSource, const nsAString& aCallerOrigin, - nsGlobalWindow* aTargetWindow, + nsGlobalWindowOuter* aTargetWindow, nsIPrincipal* aProvidedPrincipal, nsIDocument* aSourceDocument, bool aTrustedCaller); @@ -41,15 +42,15 @@ private: ~PostMessageEvent(); void - Dispatch(nsGlobalWindow* aTargetWindow, Event* aEvent); + Dispatch(nsGlobalWindowInner* aTargetWindow, Event* aEvent); void - DispatchError(JSContext* aCx, nsGlobalWindow* aTargetWindow, + DispatchError(JSContext* aCx, nsGlobalWindowInner* aTargetWindow, mozilla::dom::EventTarget* aEventTarget); - RefPtr mSource; + RefPtr mSource; nsString mCallerOrigin; - RefPtr mTargetWindow; + RefPtr mTargetWindow; nsCOMPtr mProvidedPrincipal; nsCOMPtr mSourceDocument; bool mTrustedCaller; diff --git a/dom/base/ScreenOrientation.cpp b/dom/base/ScreenOrientation.cpp index 2ca56d79cbb8..fa47bb1c0f87 100644 --- a/dom/base/ScreenOrientation.cpp +++ b/dom/base/ScreenOrientation.cpp @@ -613,7 +613,7 @@ ScreenOrientation::VisibleEventListener::HandleEvent(nsIDOMEvent* aEvent) return NS_OK; } - auto* win = nsGlobalWindow::Cast(doc->GetInnerWindow()); + auto* win = nsGlobalWindowInner::Cast(doc->GetInnerWindow()); if (!win) { return NS_OK; } diff --git a/dom/base/Timeout.h b/dom/base/Timeout.h index 0fab583ba20f..8231bea12bac 100644 --- a/dom/base/Timeout.h +++ b/dom/base/Timeout.h @@ -69,7 +69,7 @@ public: // keep decent binary packing. // Window for which this timeout fires - RefPtr mWindow; + RefPtr mWindow; // The language-specific information about the callback. nsCOMPtr mScriptHandler; diff --git a/dom/base/TimeoutManager.cpp b/dom/base/TimeoutManager.cpp index 1fe5c550dd1e..97f04a3720ec 100644 --- a/dom/base/TimeoutManager.cpp +++ b/dom/base/TimeoutManager.cpp @@ -395,7 +395,7 @@ int32_t gDisableOpenClickDelay; } // anonymous namespace -TimeoutManager::TimeoutManager(nsGlobalWindow& aWindow) +TimeoutManager::TimeoutManager(nsGlobalWindowInner& aWindow) : mWindow(aWindow), mExecutor(new TimeoutExecutor(this)), mNormalTimeouts(*this), @@ -1194,7 +1194,7 @@ class ThrottleTimeoutsCallback final : public nsITimerCallback , public nsINamed { public: - explicit ThrottleTimeoutsCallback(nsGlobalWindow* aWindow) + explicit ThrottleTimeoutsCallback(nsGlobalWindowInner* aWindow) : mWindow(aWindow) { MOZ_DIAGNOSTIC_ASSERT(aWindow->IsInnerWindow()); @@ -1215,7 +1215,7 @@ private: private: // The strong reference here keeps the Window and hence the TimeoutManager // object itself alive. - RefPtr mWindow; + RefPtr mWindow; }; NS_IMPL_ISUPPORTS(ThrottleTimeoutsCallback, nsITimerCallback, nsINamed) diff --git a/dom/base/TimeoutManager.h b/dom/base/TimeoutManager.h index 1a83f851f263..378741c2427c 100644 --- a/dom/base/TimeoutManager.h +++ b/dom/base/TimeoutManager.h @@ -12,7 +12,7 @@ class nsIEventTarget; class nsITimeoutHandler; -class nsGlobalWindow; +class nsGlobalWindowInner; namespace mozilla { namespace dom { @@ -24,7 +24,7 @@ class TimeoutExecutor; class TimeoutManager final { public: - explicit TimeoutManager(nsGlobalWindow& aWindow); + explicit TimeoutManager(nsGlobalWindowInner& aWindow); ~TimeoutManager(); TimeoutManager(const TimeoutManager& rhs) = delete; void operator=(const TimeoutManager& rhs) = delete; @@ -215,9 +215,9 @@ private: friend class OrderedTimeoutIterator; - // Each nsGlobalWindow object has a TimeoutManager member. This reference + // Each nsGlobalWindowInner object has a TimeoutManager member. This reference // points to that holder object. - nsGlobalWindow& mWindow; + nsGlobalWindowInner& mWindow; // The executor is specific to the nsGlobalWindow/TimeoutManager, but it // can live past the destruction of the window if its scheduled. Therefore // it must be a separate ref-counted object. diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index 07e3adde3877..c02990041fd7 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -1697,7 +1697,7 @@ WebSocketImpl::Init(JSContext* aCx, if (innerWindow == currentInnerWindow) { ErrorResult error; parentWindow = - nsGlobalWindow::Cast(innerWindow)->GetOpenerWindow(error); + nsGlobalWindowInner::Cast(innerWindow)->GetOpenerWindow(error); if (NS_WARN_IF(error.Failed())) { error.SuppressException(); return NS_ERROR_DOM_SECURITY_ERR; diff --git a/dom/base/WindowNamedPropertiesHandler.cpp b/dom/base/WindowNamedPropertiesHandler.cpp index 83afb97e8389..4ed4655bbe61 100644 --- a/dom/base/WindowNamedPropertiesHandler.cpp +++ b/dom/base/WindowNamedPropertiesHandler.cpp @@ -106,7 +106,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx, // Grab the DOM window. JS::Rooted global(aCx, JS_GetGlobalForObject(aCx, aProxy)); - nsGlobalWindow* win = xpc::WindowOrNull(global); + nsGlobalWindowInner* win = xpc::WindowOrNull(global); if (win->Length() > 0) { nsCOMPtr childWin = win->GetChildWindow(str); if (childWin && ShouldExposeChildWindow(str, childWin)) { @@ -178,10 +178,10 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx, } // Grab the DOM window. - nsGlobalWindow* win = xpc::WindowOrNull(JS_GetGlobalForObject(aCx, aProxy)); + nsGlobalWindowInner* win = xpc::WindowOrNull(JS_GetGlobalForObject(aCx, aProxy)); nsTArray names; // The names live on the outer window, which might be null - nsGlobalWindow* outer = win->GetOuterWindowInternal(); + nsGlobalWindowOuter* outer = win->GetOuterWindowInternal(); if (outer) { nsDOMWindowList* childWindows = outer->GetWindowList(); if (childWindows) { diff --git a/dom/base/WindowOrientationObserver.cpp b/dom/base/WindowOrientationObserver.cpp index d168cdd6887f..d4a2cbf177f0 100644 --- a/dom/base/WindowOrientationObserver.cpp +++ b/dom/base/WindowOrientationObserver.cpp @@ -12,13 +12,13 @@ using namespace mozilla::dom; /** - * This class is used by nsGlobalWindow to implement window.orientation + * This class is used by nsGlobalWindowInner to implement window.orientation * and window.onorientationchange. This class is defined in its own file * because Hal.h pulls in windows.h and can't be included from * nsGlobalWindow.cpp */ WindowOrientationObserver::WindowOrientationObserver( - nsGlobalWindow* aGlobalWindow) + nsGlobalWindowInner* aGlobalWindow) : mWindow(aGlobalWindow) { MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow()); diff --git a/dom/base/WindowOrientationObserver.h b/dom/base/WindowOrientationObserver.h index b544f202bae5..d8cb30618d79 100644 --- a/dom/base/WindowOrientationObserver.h +++ b/dom/base/WindowOrientationObserver.h @@ -9,7 +9,7 @@ #include "mozilla/HalScreenConfiguration.h" -class nsGlobalWindow; +class nsGlobalWindowInner; namespace mozilla { namespace dom { @@ -18,14 +18,14 @@ class WindowOrientationObserver final : public mozilla::hal::ScreenConfigurationObserver { public: - explicit WindowOrientationObserver(nsGlobalWindow* aGlobalWindow); + explicit WindowOrientationObserver(nsGlobalWindowInner* aGlobalWindow); ~WindowOrientationObserver(); void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) override; static int16_t OrientationAngle(); private: // Weak pointer, instance is owned by mWindow. - nsGlobalWindow* MOZ_NON_OWNING_REF mWindow; + nsGlobalWindowInner* MOZ_NON_OWNING_REF mWindow; uint16_t mAngle; }; diff --git a/dom/base/nsCCUncollectableMarker.cpp b/dom/base/nsCCUncollectableMarker.cpp index a0acf3df1cbe..bf88fa6a380d 100644 --- a/dom/base/nsCCUncollectableMarker.cpp +++ b/dom/base/nsCCUncollectableMarker.cpp @@ -212,7 +212,7 @@ MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS, if (elm) { elm->MarkForCC(); } - static_cast(win.get())->AsInner()-> + static_cast(win.get())->AsInner()-> TimeoutManager().UnmarkGrayTimers(); } } else if (aPrepareForCC) { @@ -503,12 +503,12 @@ mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber, bool aIsShutdownG } // Mark globals of active windows black. - nsGlobalWindow::WindowByIdTable* windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowOuter::OuterWindowByIdTable* windowsById = + nsGlobalWindowOuter::GetWindowsTable(); if (windowsById) { for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { - nsGlobalWindow* window = iter.Data(); - if (!window->IsCleanedUp() && window->IsOuterWindow()) { + nsGlobalWindowOuter* window = iter.Data(); + if (!window->IsCleanedUp()) { window->TraceGlobalJSObject(aTrc); EventListenerManager* elm = window->GetExistingListenerManager(); if (elm) { diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 181b454ca701..81f26ae45489 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -71,6 +71,7 @@ #include "mozilla/ManualNAC.h" #include "mozilla/MouseEvents.h" #include "mozilla/Preferences.h" +#include "mozilla/ResultExtensions.h" #include "mozilla/dom/Selection.h" #include "mozilla/TextEvents.h" #include "nsArrayUtils.h" @@ -164,6 +165,7 @@ #include "nsIParser.h" #include "nsIPermissionManager.h" #include "nsIPluginHost.h" +#include "nsIRemoteBrowser.h" #include "nsIRequest.h" #include "nsIRunnable.h" #include "nsIScriptContext.h" @@ -4739,7 +4741,8 @@ nsContentUtils::GetSubdocumentWithOuterWindowId(nsIDocument *aDocument, return nullptr; } - RefPtr window = nsGlobalWindow::GetOuterWindowWithId(aOuterWindowId); + RefPtr window = + nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowId); if (!window) { return nullptr; } @@ -9891,7 +9894,7 @@ nsContentUtils::IsSpecificAboutPage(JSObject* aGlobal, const char* aUri) MOZ_ASSERT(strncmp(aUri, "about:", 6) == 0); // Make sure the global is a window - nsGlobalWindow* win = xpc::WindowGlobalOrNull(aGlobal); + nsGlobalWindowInner* win = xpc::WindowGlobalOrNull(aGlobal); if (!win) { return false; } @@ -10588,6 +10591,40 @@ nsContentUtils::CreateJSValueFromSequenceOfObject(JSContext* aCx, return NS_OK; } +/* static */ +bool +nsContentUtils::ShouldBlockReservedKeys(WidgetKeyboardEvent* aKeyEvent) +{ + nsCOMPtr principal; + nsCOMPtr targetBrowser = do_QueryInterface(aKeyEvent->mOriginalTarget); + if (targetBrowser) { + targetBrowser->GetContentPrincipal(getter_AddRefs(principal)); + } + else { + // Get the top-level document. + nsCOMPtr content = do_QueryInterface(aKeyEvent->mOriginalTarget); + if (content) { + nsIDocument* doc = content->GetUncomposedDoc(); + if (doc) { + nsCOMPtr docShell = doc->GetDocShell(); + if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeContent) { + nsCOMPtr rootItem; + docShell->GetSameTypeRootTreeItem(getter_AddRefs(rootItem)); + if (rootItem && rootItem->GetDocument()) { + principal = rootItem->GetDocument()->NodePrincipal(); + } + } + } + } + } + + if (principal) { + return nsContentUtils::IsSitePermDeny(principal, "shortcuts"); + } + + return false; +} + /* static */ Element* nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement) { @@ -10733,7 +10770,8 @@ nsContentUtils::GetEventTargetByLoadInfo(nsILoadInfo* aLoadInfo, TaskCategory aC // something else. return nullptr; } - RefPtr window = nsGlobalWindow::GetOuterWindowWithId(outerWindowId); + RefPtr window = + nsGlobalWindowOuter::GetOuterWindowWithId(outerWindowId); if (!window) { return nullptr; } @@ -10910,6 +10948,42 @@ nsContentUtils::IsOverridingWindowName(const nsAString& aName) !aName.LowerCaseEqualsLiteral("_self"); } +// Unfortunately, we can't unwrap an IDL object using only a concrete type. +// We need to calculate type data based on the IDL typename. Which means +// wrapping our templated function in a macro. +#define EXTRACT_EXN_VALUES(T, ...) \ + ExtractExceptionValues(__VA_ARGS__).isOk() + +template +static Result +ExtractExceptionValues(JSContext* aCx, + JS::HandleObject aObj, + nsACString& aSourceSpecOut, + uint32_t* aLineOut, + uint32_t* aColumnOut, + nsString& aMessageOut) +{ + RefPtr exn; + MOZ_TRY((UnwrapObject(aObj, exn))); + + nsAutoString filename; + exn->GetFilename(aCx, filename); + if (!filename.IsEmpty()) { + CopyUTF16toUTF8(filename, aSourceSpecOut); + *aLineOut = exn->LineNumber(aCx); + *aColumnOut = exn->ColumnNumber(); + } + + exn->GetName(aMessageOut); + aMessageOut.AppendLiteral(": "); + + nsAutoString message; + exn->GetMessageMoz(message); + aMessageOut.Append(message); + return Ok(); +} + /* static */ void nsContentUtils::ExtractErrorValues(JSContext* aCx, JS::Handle aValue, @@ -10923,7 +10997,6 @@ nsContentUtils::ExtractErrorValues(JSContext* aCx, if (aValue.isObject()) { JS::Rooted obj(aCx, &aValue.toObject()); - RefPtr domException; // Try to process as an Error object. Use the file/line/column values // from the Error as they will be more specific to the root cause of @@ -10947,22 +11020,15 @@ nsContentUtils::ExtractErrorValues(JSContext* aCx, } // Next, try to unwrap the rejection value as a DOMException. - else if(NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException))) { + else if (EXTRACT_EXN_VALUES(DOMException, aCx, obj, aSourceSpecOut, + aLineOut, aColumnOut, aMessageOut)) { + return; + } - nsAutoString filename; - domException->GetFilename(aCx, filename); - if (!filename.IsEmpty()) { - CopyUTF16toUTF8(filename, aSourceSpecOut); - *aLineOut = domException->LineNumber(aCx); - *aColumnOut = domException->ColumnNumber(); - } - - domException->GetName(aMessageOut); - aMessageOut.AppendLiteral(": "); - - nsAutoString message; - domException->GetMessageMoz(message); - aMessageOut.Append(message); + // Next, try to unwrap the rejection value as an XPC Exception. + else if (EXTRACT_EXN_VALUES(Exception, aCx, obj, aSourceSpecOut, + aLineOut, aColumnOut, aMessageOut)) { + return; } } @@ -10979,6 +11045,8 @@ nsContentUtils::ExtractErrorValues(JSContext* aCx, } } +#undef EXTRACT_EXN_VALUES + /* static */ bool nsContentUtils::DevToolsEnabled(JSContext* aCx) { diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 82deb33f805f..0427906610a6 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -3128,6 +3128,12 @@ public: static bool IsWebComponentsEnabled() { return sIsWebComponentsEnabled; } + /** + * Returns true if reserved key events should be prevented from being sent + * to their target. Instead, the key event should be handled by chrome only. + */ + static bool ShouldBlockReservedKeys(mozilla::WidgetKeyboardEvent* aKeyEvent); + /** * Walks up the tree from aElement until it finds an element that is * not native anonymous content. aElement must be NAC itself. @@ -3411,6 +3417,7 @@ private: static int32_t sBytecodeCacheStrategy; static uint32_t sCookiesLifetimePolicy; static uint32_t sCookiesBehavior; + static bool sShortcutsCustomized; static int32_t sPrivacyMaxInnerWidth; static int32_t sPrivacyMaxInnerHeight; diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 689deee350df..7732c7ce6158 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -226,7 +226,7 @@ FindObjectClass(JSContext* cx, JSObject* aGlobalObject) // Helper to handle torn-down inner windows. static inline nsresult -SetParentToWindow(nsGlobalWindow *win, JSObject **parent) +SetParentToWindow(nsGlobalWindowInner *win, JSObject **parent) { MOZ_ASSERT(win); MOZ_ASSERT(win->IsInnerWindow()); @@ -724,7 +724,7 @@ nsDOMClassInfo::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } static nsresult -ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, +ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindowInner *aWin, JSContext *cx, JS::Handle obj, const char16_t *name, const nsDOMClassInfoData *ci_data, const nsGlobalNameStruct *name_struct, @@ -781,7 +781,7 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto) JS::Rooted global(cx, ::JS_GetGlobalForObject(cx, proto)); // Only do this if the global object is a window. - nsGlobalWindow* win; + nsGlobalWindowInner* win; if (NS_FAILED(UNWRAP_OBJECT(Window, &global, win))) { // Not a window. return NS_OK; @@ -803,9 +803,9 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto) NS_ENSURE_TRUE(nameSpaceManager, NS_OK); JS::Rooted desc(cx); - nsresult rv = ResolvePrototype(sXPConnect, win, cx, global, mData->mNameUTF16, - mData, nullptr, nameSpaceManager, proto, - &desc); + nsresult rv = ResolvePrototype(sXPConnect, win->AssertInner(), cx, global, + mData->mNameUTF16, mData, nullptr, + nameSpaceManager, proto, &desc); NS_ENSURE_SUCCESS(rv, rv); if (!contentDefinedProperty && desc.object() && !desc.value().isUndefined()) { desc.attributesRef() |= JSPROP_RESOLVING; @@ -1077,7 +1077,7 @@ nsDOMConstructor::PreCreate(JSContext *cx, JSObject *globalObj, JSObject **paren return NS_OK; } - nsGlobalWindow *win = nsGlobalWindow::Cast(owner); + nsGlobalWindowInner *win = nsGlobalWindowInner::Cast(owner); return SetParentToWindow(win, parentObj); } @@ -1273,7 +1273,7 @@ nsDOMConstructor::ToString(nsAString &aResult) static nsresult -GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin, +GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindowInner *aWin, const nsGlobalNameStruct *aNameStruct, JS::MutableHandle aProto) { @@ -1298,7 +1298,7 @@ GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin, // Either ci_data must be non-null or name_struct must be non-null and of type // eTypeClassProto. static nsresult -ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, +ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindowInner *aWin, JSContext *cx, JS::Handle obj, const char16_t *name, const nsDOMClassInfoData *ci_data, const nsGlobalNameStruct *name_struct, @@ -1462,7 +1462,7 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, static bool OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct, - nsGlobalWindow *aWin, JSContext *cx) + nsGlobalWindowInner *aWin, JSContext *cx) { MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeProperty || aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor); @@ -1491,7 +1491,7 @@ LookupComponentsShim(JSContext *cx, JS::Handle global, // static bool -nsWindowSH::NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin, +nsWindowSH::NameStructEnabled(JSContext* aCx, nsGlobalWindowInner *aWin, const nsAString& aName, const nsGlobalNameStruct& aNameStruct) { @@ -1521,7 +1521,7 @@ static const JSClass XULControllersShimClass = { // static nsresult -nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, +nsWindowSH::GlobalResolve(nsGlobalWindowInner *aWin, JSContext *cx, JS::Handle obj, JS::Handle id, JS::MutableHandle desc) { diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index d73246190416..74a7bacd5045 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -21,6 +21,7 @@ struct nsGlobalNameStruct; class nsGlobalWindow; +class nsGlobalWindowInner; struct nsDOMClassInfoData; @@ -140,13 +141,13 @@ public: class nsWindowSH { protected: - static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, + static nsresult GlobalResolve(nsGlobalWindowInner *aWin, JSContext *cx, JS::Handle obj, JS::Handle id, JS::MutableHandle desc); friend class nsGlobalWindow; public: - static bool NameStructEnabled(JSContext* aCx, nsGlobalWindow *aWin, + static bool NameStructEnabled(JSContext* aCx, nsGlobalWindowInner *aWin, const nsAString& aName, const nsGlobalNameStruct& aNameStruct); }; diff --git a/dom/base/nsDOMMutationObserver.h b/dom/base/nsDOMMutationObserver.h index cc73942daec0..c3a4582b3098 100644 --- a/dom/base/nsDOMMutationObserver.h +++ b/dom/base/nsDOMMutationObserver.h @@ -626,7 +626,7 @@ protected: bool Suppressed() { - return mOwner && nsGlobalWindow::Cast(mOwner)->IsInSyncOperation(); + return mOwner && nsGlobalWindowInner::Cast(mOwner)->IsInSyncOperation(); } static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso); diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index bc0276699723..65ab138eda46 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -208,7 +208,7 @@ NS_INTERFACE_MAP_END NS_IMPL_ADDREF(nsDOMWindowUtils) NS_IMPL_RELEASE(nsDOMWindowUtils) -nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow) +nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindowOuter *aWindow) { nsCOMPtr supports = do_QueryObject(aWindow); mWindow = do_GetWeakReference(supports); @@ -2357,7 +2357,7 @@ nsDOMWindowUtils::IsInModalState(bool *retval) nsCOMPtr window = do_QueryReferent(mWindow); NS_ENSURE_STATE(window); - *retval = nsGlobalWindow::Cast(window)->IsInModalState(); + *retval = nsGlobalWindowOuter::Cast(window)->IsInModalState(); return NS_OK; } @@ -2389,8 +2389,8 @@ nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID) NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE); NS_ASSERTION(window->IsOuterWindow(), "How did that happen?"); - nsGlobalWindow* inner = - nsGlobalWindow::Cast(window)->GetCurrentInnerWindowInternal(); + nsGlobalWindowInner* inner = + nsGlobalWindowOuter::Cast(window)->GetCurrentInnerWindowInternal(); if (!inner) { return NS_ERROR_NOT_AVAILABLE; } @@ -3268,7 +3268,7 @@ nsDOMWindowUtils::EnableDialogs() nsCOMPtr window = do_QueryReferent(mWindow); NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); - nsGlobalWindow::Cast(window)->EnableDialogs(); + nsGlobalWindowOuter::Cast(window)->EnableDialogs(); return NS_OK; } @@ -3278,7 +3278,7 @@ nsDOMWindowUtils::DisableDialogs() nsCOMPtr window = do_QueryReferent(mWindow); NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); - nsGlobalWindow::Cast(window)->DisableDialogs(); + nsGlobalWindowOuter::Cast(window)->DisableDialogs(); return NS_OK; } @@ -3288,7 +3288,7 @@ nsDOMWindowUtils::AreDialogsEnabled(bool* aResult) nsCOMPtr window = do_QueryReferent(mWindow); NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); - *aResult = nsGlobalWindow::Cast(window)->AreDialogsEnabled(); + *aResult = nsGlobalWindowOuter::Cast(window)->AreDialogsEnabled(); return NS_OK; } @@ -3796,7 +3796,7 @@ nsDOMWindowUtils::AllowScriptsToClose() { nsCOMPtr window = do_QueryReferent(mWindow); NS_ENSURE_STATE(window); - nsGlobalWindow::Cast(window)->AllowScriptsToClose(); + nsGlobalWindowOuter::Cast(window)->AllowScriptsToClose(); return NS_OK; } diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h index 21550792f4a2..76f07a4596a0 100644 --- a/dom/base/nsDOMWindowUtils.h +++ b/dom/base/nsDOMWindowUtils.h @@ -13,7 +13,7 @@ #include "mozilla/Attributes.h" #include "mozilla/BasicEvents.h" -class nsGlobalWindow; +class nsGlobalWindowOuter; class nsIPresShell; class nsIWidget; class nsPresContext; @@ -62,7 +62,7 @@ class nsDOMWindowUtils final : public nsIDOMWindowUtils, typedef mozilla::widget::TextEventDispatcher TextEventDispatcher; public: - explicit nsDOMWindowUtils(nsGlobalWindow *aWindow); + explicit nsDOMWindowUtils(nsGlobalWindowOuter *aWindow); NS_DECL_ISUPPORTS NS_DECL_NSIDOMWINDOWUTILS diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index e2da1785ad33..9679acda0f8e 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -91,7 +91,6 @@ #include "nsContentCID.h" #include "nsError.h" #include "nsPresContext.h" -#include "nsIJSON.h" #include "nsThreadUtils.h" #include "nsNodeInfoManager.h" #include "nsIFileChannel.h" @@ -2490,7 +2489,7 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup, // Refresh the principal on the compartment. if (nsPIDOMWindowInner* win = GetInnerWindow()) { - nsGlobalWindow::Cast(win)->RefreshCompartmentPrincipal(); + nsGlobalWindowInner::Cast(win)->RefreshCompartmentPrincipal(); } } @@ -6378,7 +6377,7 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* JS::Rooted global(aCx, JS_GetGlobalForObject(aCx, &args.callee())); - RefPtr window; + RefPtr window; UNWRAP_OBJECT(Window, global, window); MOZ_ASSERT(window, "Should have a non-null window"); @@ -7201,7 +7200,7 @@ nsIDocument::GetLocation() const return nullptr; } - nsGlobalWindow* window = nsGlobalWindow::Cast(w); + nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(w); RefPtr loc = window->GetLocation(); return loc.forget(); } @@ -8470,7 +8469,7 @@ nsDocument::GetEventTargetParent(EventChainPreVisitor& aVisitor) // Load events must not propagate to |window| object, see bug 335251. if (aVisitor.mEvent->mMessage != eLoad) { - nsGlobalWindow* window = nsGlobalWindow::Cast(GetWindow()); + nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(GetWindow()); aVisitor.mParentTarget = window ? window->GetTargetForEventTargetChain() : nullptr; } @@ -9158,7 +9157,7 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest) if (win) { - auto* globalWindow = nsGlobalWindow::Cast(win); + auto* globalWindow = nsGlobalWindowInner::Cast(win); #ifdef MOZ_WEBSPEECH if (globalWindow->HasActiveSpeechSynthesis()) { return false; @@ -10886,7 +10885,7 @@ nsDocument::NotifyMediaFeatureValuesChanged() } already_AddRefed -nsIDocument::CreateTouch(nsGlobalWindow* aView, +nsIDocument::CreateTouch(nsGlobalWindowInner* aView, EventTarget* aTarget, int32_t aIdentifier, int32_t aPageX, int32_t aPageY, @@ -14322,7 +14321,7 @@ nsIDocument::GetSelection(ErrorResult& aRv) return nullptr; } - return nsGlobalWindow::Cast(window)->GetSelection(aRv); + return nsGlobalWindowInner::Cast(window)->GetSelection(aRv); } void diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index fcf693864397..a211910b3c52 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -1602,7 +1602,7 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther, #ifdef XP_WIN // Native plugin windows used by this remote content need to be reparented. if (nsPIDOMWindowOuter* newWin = ourDoc->GetWindow()) { - RefPtr newParent = nsGlobalWindow::Cast(newWin)->GetMainWidget(); + RefPtr newParent = nsGlobalWindowOuter::Cast(newWin)->GetMainWidget(); const ManagedContainer& plugins = aOther->mRemoteBrowser->ManagedPPluginWidgetParent(); for (auto iter = plugins.ConstIter(); !iter.Done(); iter.Next()) { @@ -3840,8 +3840,8 @@ nsFrameLoader::Print(uint64_t aOuterWindowID, return success ? NS_OK : NS_ERROR_FAILURE; } - nsGlobalWindow* outerWindow = - nsGlobalWindow::GetOuterWindowWithId(aOuterWindowID); + nsGlobalWindowOuter* outerWindow = + nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowID); if (NS_WARN_IF(!outerWindow)) { return NS_ERROR_FAILURE; } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 93872247c27d..b8c680c88c1b 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -288,7 +288,8 @@ using mozilla::dom::cache::CacheStorage; static LazyLogModule gDOMLeakPRLog("DOMLeak"); -nsGlobalWindow::WindowByIdTable *nsGlobalWindow::sWindowsById = nullptr; +nsGlobalWindowInner::InnerWindowByIdTable *nsGlobalWindowInner::sInnerWindowsById = nullptr; +nsGlobalWindowOuter::OuterWindowByIdTable *nsGlobalWindowOuter::sOuterWindowsById = nullptr; bool nsGlobalWindow::sIdleObserversAPIFuzzTimeDisabled = false; static int32_t gRefCnt = 0; @@ -891,7 +892,7 @@ public: nsresult Call() override { - return nsGlobalWindow::Cast(mWindow)->RunIdleRequest(mIdleRequest, 0.0, true); + return nsGlobalWindowInner::Cast(mWindow)->RunIdleRequest(mIdleRequest, 0.0, true); } private: @@ -1016,7 +1017,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow) { if (aOuterWindow) { mTimeoutManager = - MakeUnique(*nsGlobalWindow::Cast(AsInner())); + MakeUnique(*nsGlobalWindowInner::Cast(AsInner())); } } @@ -1426,7 +1427,7 @@ nsOuterWindowProxy::GetSubframeWindow(JSContext *cx, found = true; // Just return the window's global - nsGlobalWindow* global = nsGlobalWindow::Cast(frame); + nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(frame); frame->EnsureInnerWindow(); JSObject* obj = global->FastGetGlobalJSObject(); // This null check fixes a hard-to-reproduce crash that occurs when we @@ -1672,14 +1673,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) MOZ_LOG(gDOMLeakPRLog, LogLevel::Debug, ("DOMWINDOW %p created outer=%p", this, aOuterWindow)); - - NS_ASSERTION(sWindowsById, "Windows hash table must be created!"); - NS_ASSERTION(!sWindowsById->Get(mWindowID), - "This window shouldn't be in the hash table yet!"); - // We seem to see crashes in release builds because of null |sWindowsById|. - if (sWindowsById) { - sWindowsById->Put(mWindowID, this); - } } #ifdef DEBUG @@ -1701,7 +1694,10 @@ nsGlobalWindow::Init() NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!"); - sWindowsById = new WindowByIdTable(); + nsGlobalWindowOuter::sOuterWindowsById = + new nsGlobalWindowOuter::OuterWindowByIdTable(); + nsGlobalWindowInner::sInnerWindowsById = + new nsGlobalWindowInner::InnerWindowByIdTable(); } nsGlobalWindow::~nsGlobalWindow() @@ -1724,12 +1720,18 @@ nsGlobalWindow::~nsGlobalWindow() DisconnectEventTargetObjects(); - // We have to check if sWindowsById isn't null because ::Shutdown might have - // been called. - if (sWindowsById) { - NS_ASSERTION(sWindowsById->Get(mWindowID), + if (IsOuterWindow()) { + if (nsGlobalWindowOuter::sOuterWindowsById) { + MOZ_ASSERT(nsGlobalWindowOuter::sOuterWindowsById->Get(mWindowID), "This window should be in the hash table"); - sWindowsById->Remove(mWindowID); + nsGlobalWindowOuter::sOuterWindowsById->Remove(mWindowID); + } + } else { + if (nsGlobalWindowInner::sInnerWindowsById) { + MOZ_ASSERT(nsGlobalWindowInner::sInnerWindowsById->Get(mWindowID), + "This window should be in the hash table"); + nsGlobalWindowInner::sInnerWindowsById->Remove(mWindowID); + } } --gRefCnt; @@ -1747,7 +1749,7 @@ nsGlobalWindow::~nsGlobalWindow() } } - nsGlobalWindow* outer = nsGlobalWindow::Cast(mOuterWindow); + nsGlobalWindowOuter* outer = nsGlobalWindowOuter::Cast(mOuterWindow); printf_stderr("--DOMWINDOW == %d (%p) [pid = %d] [serial = %d] [outer = %p] [url = %s]\n", gRefCnt, static_cast(ToCanonicalSupports(this)), @@ -1858,8 +1860,10 @@ nsGlobalWindow::ShutDown() } gDumpFile = nullptr; - delete sWindowsById; - sWindowsById = nullptr; + delete nsGlobalWindowInner::sInnerWindowsById; + nsGlobalWindowInner::sInnerWindowsById = nullptr; + delete nsGlobalWindowOuter::sOuterWindowsById; + nsGlobalWindowOuter::sOuterWindowsById = nullptr; } // static @@ -2064,7 +2068,7 @@ nsGlobalWindow::FreeInnerObjects() // re-create. NotifyDOMWindowDestroyed(this); if (auto* reporter = nsWindowMemoryReporter::Get()) { - reporter->ObserveDOMWindowDetached(this); + reporter->ObserveDOMWindowDetached(AssertInner()); } mInnerObjectsFreed = true; @@ -2354,7 +2358,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow) #endif if (tmp->mOuterWindow) { - nsGlobalWindow::Cast(tmp->mOuterWindow)->MaybeClearInnerWindow(tmp); + nsGlobalWindowOuter::Cast(tmp->mOuterWindow)->MaybeClearInnerWindow(tmp); NS_IMPL_CYCLE_COLLECTION_UNLINK(mOuterWindow) } @@ -2791,7 +2795,7 @@ nsGlobalWindow::ComputeIsSecureContext(nsIDocument* aDocument, SecureContextFlag nsPIDOMWindowOuter* parentOuterWin = GetScriptableParent(); MOZ_ASSERT(parentOuterWin, "How can we get here? No docShell somehow?"); - if (nsGlobalWindow::Cast(parentOuterWin) != this) { + if (nsGlobalWindowOuter::Cast(parentOuterWin) != this) { // There may be a small chance that parentOuterWin has navigated in // the time that it took us to start loading this sub-document. If that // were the case then parentOuterWin->GetCurrentInnerWindow() wouldn't @@ -2803,13 +2807,13 @@ nsGlobalWindow::ComputeIsSecureContext(nsIDocument* aDocument, SecureContextFlag if (!creatorDoc) { return false; // we must be tearing down } - nsGlobalWindow* parentWin = - nsGlobalWindow::Cast(creatorDoc->GetInnerWindow()); + nsGlobalWindowInner* parentWin = + nsGlobalWindowInner::Cast(creatorDoc->GetInnerWindow()); if (!parentWin) { return false; // we must be tearing down } MOZ_ASSERT(parentWin == - nsGlobalWindow::Cast(parentOuterWin->GetCurrentInnerWindow()), + nsGlobalWindowInner::Cast(parentOuterWin->GetCurrentInnerWindow()), "Creator window mismatch while setting Secure Context state"); if (aFlags != SecureContextFlags::eIgnoreOpener) { hadNonSecureContextCreator = !parentWin->IsSecureContext(); @@ -2882,7 +2886,7 @@ SelectZoneGroup(nsGlobalWindow* aNewInner, // go through one iteration of this loop. RefPtr tabGroup = aNewInner->TabGroup(); for (nsPIDOMWindowOuter* outer : tabGroup->GetWindows()) { - nsGlobalWindow* window = nsGlobalWindow::Cast(outer); + nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(outer); if (JSObject* global = window->GetGlobalJSObject()) { return aOptions.setNewZoneInExistingZoneGroup(global); } @@ -2898,7 +2902,7 @@ SelectZoneGroup(nsGlobalWindow* aNewInner, */ static nsresult CreateNativeGlobalForInner(JSContext* aCx, - nsGlobalWindow* aNewInner, + nsGlobalWindowInner* aNewInner, nsIURI* aURI, nsIPrincipal* aPrincipal, JS::MutableHandle aGlobal, @@ -3138,7 +3142,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, mCreatingInnerWindow = true; // Every script context we are initialized with must create a // new global. - rv = CreateNativeGlobalForInner(cx, newInnerWindow, + rv = CreateNativeGlobalForInner(cx, newInnerWindow->AssertInner(), aDocument->GetDocumentURI(), aDocument->NodePrincipal(), &newInnerGlobal, @@ -3489,7 +3493,8 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell) mDocShell = aDocShell; // Weak Reference nsCOMPtr parentWindow = GetScriptableParentOrNull(); - MOZ_RELEASE_ASSERT(!parentWindow || !mTabGroup || mTabGroup == Cast(parentWindow)->mTabGroup); + MOZ_RELEASE_ASSERT(!parentWindow || !mTabGroup || + mTabGroup == nsGlobalWindowOuter::Cast(parentWindow)->mTabGroup); mTopLevelOuterContentWindow = !mIsChrome && GetScriptableTopInternal() == this; @@ -3547,9 +3552,8 @@ nsGlobalWindow::DetachFromDocShell() inner->FreeInnerObjects(); } - if (auto* reporter = nsWindowMemoryReporter::Get()) { - reporter->ObserveDOMWindowDetached(this); - } + // Don't report that we were detached to the nsWindowMemoryReporter, as it + // only tracks inner windows. NotifyWindowIDDestroyed("outer-window-destroyed"); @@ -3622,7 +3626,7 @@ nsGlobalWindow::SetOpenerWindow(nsPIDOMWindowOuter* aOpener, // contentOpener is not used when the DIAGNOSTIC_ASSERT is compiled out. mozilla::Unused << contentOpener; MOZ_DIAGNOSTIC_ASSERT(!contentOpener || !mTabGroup || - mTabGroup == Cast(contentOpener)->mTabGroup); + mTabGroup == nsGlobalWindowOuter::Cast(contentOpener)->mTabGroup); if (aOriginalOpener) { MOZ_ASSERT(!mHadOriginalOpener, @@ -4203,16 +4207,16 @@ nsPIDOMWindowInner::UnmuteAudioContexts() } } -nsGlobalWindow* +nsGlobalWindowInner* nsGlobalWindow::Window() { - return this; + return AssertInner(); } -nsGlobalWindow* +nsGlobalWindowInner* nsGlobalWindow::Self() { - return this; + return AssertInner(); } Navigator* @@ -4324,43 +4328,43 @@ nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded() bool nsPIDOMWindowInner::IsSecureContext() const { - return nsGlobalWindow::Cast(this)->IsSecureContext(); + return nsGlobalWindowInner::Cast(this)->IsSecureContext(); } bool nsPIDOMWindowInner::IsSecureContextIfOpenerIgnored() const { - return nsGlobalWindow::Cast(this)->IsSecureContextIfOpenerIgnored(); + return nsGlobalWindowInner::Cast(this)->IsSecureContextIfOpenerIgnored(); } void nsPIDOMWindowInner::Suspend() { - nsGlobalWindow::Cast(this)->Suspend(); + nsGlobalWindowInner::Cast(this)->Suspend(); } void nsPIDOMWindowInner::Resume() { - nsGlobalWindow::Cast(this)->Resume(); + nsGlobalWindowInner::Cast(this)->Resume(); } void nsPIDOMWindowInner::Freeze() { - nsGlobalWindow::Cast(this)->Freeze(); + nsGlobalWindowInner::Cast(this)->Freeze(); } void nsPIDOMWindowInner::Thaw() { - nsGlobalWindow::Cast(this)->Thaw(); + nsGlobalWindowInner::Cast(this)->Thaw(); } void nsPIDOMWindowInner::SyncStateFromParentWindow() { - nsGlobalWindow::Cast(this)->SyncStateFromParentWindow(); + nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow(); } void @@ -4453,7 +4457,7 @@ nsPIDOMWindowInner::TryToCacheTopInnerWindow() mHasTriedToCacheTopInnerWindow = true; - nsGlobalWindow* window = nsGlobalWindow::Cast(AsInner()); + nsGlobalWindow* window = nsGlobalWindowInner::Cast(AsInner()); MOZ_ASSERT(window); @@ -4795,7 +4799,7 @@ nsGlobalWindow::GetScriptableParentOrNull() FORWARD_TO_OUTER(GetScriptableParentOrNull, (), nullptr); nsPIDOMWindowOuter* parent = GetScriptableParent(); - return (Cast(parent) == this) ? nullptr : parent; + return (nsGlobalWindowOuter::Cast(parent) == this) ? nullptr : parent; } /** @@ -5023,7 +5027,7 @@ nsGlobalWindow::GetMenubar(ErrorResult& aError) MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mMenubar) { - mMenubar = new MenubarProp(this); + mMenubar = new MenubarProp(AssertInner()); } return mMenubar; @@ -5035,7 +5039,7 @@ nsGlobalWindow::GetToolbar(ErrorResult& aError) MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mToolbar) { - mToolbar = new ToolbarProp(this); + mToolbar = new ToolbarProp(AssertInner()); } return mToolbar; @@ -5047,7 +5051,7 @@ nsGlobalWindow::GetLocationbar(ErrorResult& aError) MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mLocationbar) { - mLocationbar = new LocationbarProp(this); + mLocationbar = new LocationbarProp(AssertInner()); } return mLocationbar; } @@ -5058,7 +5062,7 @@ nsGlobalWindow::GetPersonalbar(ErrorResult& aError) MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mPersonalbar) { - mPersonalbar = new PersonalbarProp(this); + mPersonalbar = new PersonalbarProp(AssertInner()); } return mPersonalbar; } @@ -5069,7 +5073,7 @@ nsGlobalWindow::GetStatusbar(ErrorResult& aError) MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mStatusbar) { - mStatusbar = new StatusbarProp(this); + mStatusbar = new StatusbarProp(AssertInner()); } return mStatusbar; } @@ -5080,7 +5084,7 @@ nsGlobalWindow::GetScrollbars(ErrorResult& aError) MOZ_RELEASE_ASSERT(IsInnerWindow()); if (!mScrollbars) { - mScrollbars = new ScrollbarsProp(this); + mScrollbars = new ScrollbarsProp(AssertInner()); } return mScrollbars; @@ -5171,7 +5175,7 @@ nsGlobalWindow::DoResolve(JSContext* aCx, JS::Handle aObj, return true; } - nsresult rv = nsWindowSH::GlobalResolve(this, aCx, aObj, aId, aDesc); + nsresult rv = nsWindowSH::GlobalResolve(AssertInner(), aCx, aObj, aId, aDesc); if (NS_FAILED(rv)) { return Throw(aCx, rv); } @@ -5262,7 +5266,7 @@ nsGlobalWindow::GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames, for (auto i = nameSpaceManager->GlobalNameIter(); !i.Done(); i.Next()) { const GlobalNameMapEntry* entry = i.Get(); - if (nsWindowSH::NameStructEnabled(aCx, this, entry->mKey, + if (nsWindowSH::NameStructEnabled(aCx, AssertInner(), entry->mKey, entry->mGlobalName)) { // Just append all of these; even if they get deleted our resolve hook // just goes ahead and recreates them. @@ -5427,7 +5431,7 @@ nsGlobalWindow::GetSanitizedOpener(nsPIDOMWindowOuter* aOpener) return nullptr; } - nsGlobalWindow* win = nsGlobalWindow::Cast(aOpener); + nsGlobalWindow* win = nsGlobalWindowOuter::Cast(aOpener); // First, ensure that we're not handing back a chrome window to content: if (win->IsChromeWindow()) { @@ -5470,7 +5474,7 @@ nsGlobalWindow::GetOpenerWindowOuter() if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { // Catch the case where we're chrome but the opener is not... if (GetPrincipal() == nsContentUtils::GetSystemPrincipal() && - nsGlobalWindow::Cast(opener)->GetPrincipal() != nsContentUtils::GetSystemPrincipal()) { + nsGlobalWindowOuter::Cast(opener)->GetPrincipal() != nsContentUtils::GetSystemPrincipal()) { return nullptr; } return opener; @@ -6269,7 +6273,7 @@ nsGlobalWindow::GetDevicePixelRatio(CallerType aCallerType, ErrorResult& aError) float nsPIDOMWindowOuter::GetDevicePixelRatio(CallerType aCallerType) { - return nsGlobalWindow::Cast(this)->GetDevicePixelRatioOuter(aCallerType); + return nsGlobalWindowOuter::Cast(this)->GetDevicePixelRatioOuter(aCallerType); } uint64_t @@ -6542,7 +6546,7 @@ nsGlobalWindow::CheckSecurityLeftAndTop(int32_t* aLeft, int32_t* aTop, nsContentUtils::HidePopupsInDocument(mDoc); #endif - if (nsGlobalWindow* rootWindow = nsGlobalWindow::Cast(GetPrivateRoot())) { + if (nsGlobalWindowOuter* rootWindow = nsGlobalWindowOuter::Cast(GetPrivateRoot())) { rootWindow->FlushPendingNotifications(FlushType::Layout); } @@ -7112,7 +7116,7 @@ FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject, if (strcmp(aTopic, FullscreenTransitionTask::kPaintedTopic) == 0) { nsCOMPtr win(do_QueryInterface(aSubject)); nsCOMPtr widget = win ? - nsGlobalWindow::Cast(win)->GetMainWidget() : nullptr; + nsGlobalWindowInner::Cast(win)->GetMainWidget() : nullptr; if (widget == mTask->mWidget) { // The paint notification arrives first. Cancel the timer. mTask->mTimer->Cancel(); @@ -7395,7 +7399,7 @@ nsGlobalWindow::FullScreen() const nsCOMPtr window = rootItem->GetWindow(); NS_ENSURE_TRUE(window, mFullScreen); - return nsGlobalWindow::Cast(window)->FullScreen(); + return nsGlobalWindowOuter::Cast(window)->FullScreen(); } bool @@ -8786,6 +8790,7 @@ nsGlobalWindow::FirePopupBlockedEvent(nsIDocument* aDoc, const nsAString& aPopupWindowName, const nsAString& aPopupWindowFeatures) { + MOZ_ASSERT(IsOuterWindow(), "All callers seem to assume we're an outer window?"); MOZ_ASSERT(aDoc); // Fire a "DOMPopupBlocked" event so that the UI can hear about @@ -8793,7 +8798,9 @@ nsGlobalWindow::FirePopupBlockedEvent(nsIDocument* aDoc, PopupBlockedEventInit init; init.mBubbles = true; init.mCancelable = true; - init.mRequestingWindow = this; + // XXX: This is a different object, but webidl requires an inner window here + // now. + init.mRequestingWindow = GetCurrentInnerWindowInternal(); init.mPopupWindowURI = aPopupURI; init.mPopupWindowName = aPopupWindowName; init.mPopupWindowFeatures = aPopupWindowFeatures; @@ -8835,7 +8842,7 @@ nsGlobalWindow::PopupWhitelisted() return false; } - return nsGlobalWindow::Cast(parent)->PopupWhitelisted(); + return nsGlobalWindowOuter::Cast(parent)->PopupWhitelisted(); } /* @@ -8891,6 +8898,7 @@ nsGlobalWindow::FireAbuseEvents(const nsAString &aPopupURL, const nsAString &aPopupWindowName, const nsAString &aPopupWindowFeatures) { + MOZ_ASSERT(IsOuterWindow()); // fetch the URI of the window requesting the opened window nsCOMPtr window = GetTop(); @@ -9076,7 +9084,7 @@ nsGlobalWindow::GetFrames(ErrorResult& aError) FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, nullptr); } -nsGlobalWindow* +nsGlobalWindowInner* nsGlobalWindow::CallerInnerWindow() { JSContext *cx = nsContentUtils::GetCurrentJSContext(); @@ -9108,7 +9116,7 @@ nsGlobalWindow::CallerInnerWindow() // The calling window must be holding a reference, so we can return a weak // pointer. nsCOMPtr win = do_QueryInterface(global); - return nsGlobalWindow::Cast(win); + return nsGlobalWindowInner::Cast(win); } void @@ -9245,7 +9253,7 @@ nsGlobalWindow::PostMessageMozOuter(JSContext* aCx, JS::Handle aMessa ? nullptr : callerInnerWin->GetOuterWindowInternal(), origin, - this, + AssertOuter(), providedPrincipal, callerInnerWin ? callerInnerWin->GetDoc() @@ -10693,7 +10701,7 @@ nsGlobalWindow::EnableGamepadUpdates() if (mHasGamepad) { RefPtr gamepadManager(GamepadManager::GetService()); if (gamepadManager) { - gamepadManager->AddListener(this); + gamepadManager->AddListener(AssertInner()); } } } @@ -10706,7 +10714,7 @@ nsGlobalWindow::DisableGamepadUpdates() if (mHasGamepad) { RefPtr gamepadManager(GamepadManager::GetService()); if (gamepadManager) { - gamepadManager->RemoveListener(this); + gamepadManager->RemoveListener(AssertInner()); } } } @@ -10717,7 +10725,7 @@ nsGlobalWindow::EnableVRUpdates() MOZ_ASSERT(IsInnerWindow()); if (mHasVREvents && !mVREventObserver) { - mVREventObserver = new VREventObserver(this); + mVREventObserver = new VREventObserver(AssertInner()); } } @@ -11215,7 +11223,7 @@ nsGlobalWindow::GetComputedStyleHelperOuter(Element& aElt, if (!presShell) { // Try flushing frames on our parent in case there's a pending // style change that will create the presshell. - auto* parent = nsGlobalWindow::Cast(GetPrivateParent()); + auto* parent = nsGlobalWindowOuter::Cast(GetPrivateParent()); if (!parent) { return nullptr; } @@ -11444,7 +11452,7 @@ nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink) } #endif else if (aIID.Equals(NS_GET_IID(nsIDOMWindowUtils))) { - nsGlobalWindow* outer = GetOuterWindowInternal(); + nsGlobalWindowOuter* outer = GetOuterWindowInternal(); NS_ENSURE_TRUE(outer, NS_ERROR_NOT_INITIALIZED); if (!mWindowUtils) { @@ -12621,8 +12629,8 @@ nsGlobalWindow::SyncStateFromParentWindow() nsCOMPtr frame = outer->GetFrameElementInternal(); nsPIDOMWindowOuter* parentOuter = frame ? frame->OwnerDoc()->GetWindow() : nullptr; - nsGlobalWindow* parentInner = - parentOuter ? nsGlobalWindow::Cast(parentOuter->GetCurrentInnerWindow()) + nsGlobalWindowInner* parentInner = + parentOuter ? nsGlobalWindowInner::Cast(parentOuter->GetCurrentInnerWindow()) : nullptr; // If our outer is in a modal state, but our parent is not in a modal @@ -12678,8 +12686,8 @@ nsGlobalWindow::CallOnChildren(Method aMethod) continue; } - auto* win = nsGlobalWindow::Cast(pWin); - nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal(); + auto* win = nsGlobalWindowOuter::Cast(pWin); + nsGlobalWindowInner* inner = win->GetCurrentInnerWindowInternal(); // This is a bit hackish. Only freeze/suspend windows which are truly our // subwindows. @@ -12725,7 +12733,7 @@ nsGlobalWindow::FireDelayedDOMEvents() NS_ASSERTION(childShell, "null child shell"); if (nsCOMPtr pWin = childShell->GetWindow()) { - auto* win = nsGlobalWindow::Cast(pWin); + auto* win = nsGlobalWindowOuter::Cast(pWin); win->FireDelayedDOMEvents(); } } @@ -12995,7 +13003,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName, // nsGlobalWindow: Timeout Functions //***************************************************************************** -nsGlobalWindow* +nsGlobalWindowInner* nsGlobalWindow::InnerForSetTimeoutOrInterval(ErrorResult& aError) { nsGlobalWindow* currentInner; @@ -13035,14 +13043,16 @@ nsGlobalWindow::InnerForSetTimeoutOrInterval(ErrorResult& aError) return nullptr; } - return currentInner; + return static_cast(currentInner); } } // If forwardTo is not the window with an active document then we want the // call to setTimeout/Interval to be a noop, so return null but don't set an // error. - return forwardTo->AsInner()->HasActiveDocument() ? currentInner : nullptr; + return forwardTo->AsInner()->HasActiveDocument() + ? static_cast(currentInner) + : nullptr; } int32_t @@ -13118,7 +13128,7 @@ nsGlobalWindow::SetTimeoutOrInterval(JSContext *aCx, Function& aFunction, } nsCOMPtr handler = - NS_CreateJSTimeoutHandler(aCx, this, aFunction, aArguments, aError); + NS_CreateJSTimeoutHandler(aCx, AssertInner(), aFunction, aArguments, aError); if (!handler) { return 0; } @@ -13146,7 +13156,7 @@ nsGlobalWindow::SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler, } nsCOMPtr handler = - NS_CreateJSTimeoutHandler(aCx, this, aHandler, aError); + NS_CreateJSTimeoutHandler(aCx, AssertInner(), aHandler, aError); if (!handler) { return 0; } @@ -13350,7 +13360,7 @@ nsGlobalWindow::SecurityCheckURL(const char *aURL) sourceWindow = AsOuter()->GetCurrentInnerWindow(); } AutoJSContext cx; - nsGlobalWindow* sourceWin = nsGlobalWindow::Cast(sourceWindow); + nsGlobalWindowInner* sourceWin = nsGlobalWindowInner::Cast(sourceWindow); JSAutoCompartment ac(cx, sourceWin->GetGlobalJSObject()); // Resolve the baseURI, which could be relative to the calling window. @@ -13402,7 +13412,7 @@ nsGlobalWindow::EnsureSizeAndPositionUpToDate() // If we're a subframe, make sure our size is up to date. It's OK that this // crosses the content/chrome boundary, since chrome can have pending reflows // too. - nsGlobalWindow *parent = nsGlobalWindow::Cast(GetPrivateParent()); + nsGlobalWindow *parent = nsGlobalWindowOuter::Cast(GetPrivateParent()); if (parent) { parent->FlushPendingNotifications(FlushType::Layout); } @@ -13539,7 +13549,7 @@ nsGlobalWindow::EnableOrientationChangeListener() if (!nsContentUtils::ShouldResistFingerprinting(mDocShell) && !mOrientationChangeObserver) { mOrientationChangeObserver = - MakeUnique(this); + MakeUnique(AssertInner()); } } @@ -14008,7 +14018,13 @@ nsGlobalWindow::DispatchVRDisplayPresentChange(uint32_t aDisplayID) /* static */ already_AddRefed nsGlobalWindow::CreateChrome(nsGlobalWindow *aOuterWindow) { - RefPtr window = new nsGlobalWindow(aOuterWindow); + RefPtr window; + if (aOuterWindow) { + window = new nsGlobalWindowInner( + static_cast(aOuterWindow)); + } else { + window = new nsGlobalWindowOuter(); + } window->mIsChrome = true; window->mCleanMessageManager = true; @@ -14399,7 +14415,13 @@ nsGlobalWindow::TakeOpenerForInitialContentBrowser(mozIDOMWindowProxy** aOpenerW /* static */ already_AddRefed nsGlobalWindow::Create(nsGlobalWindow *aOuterWindow) { - RefPtr window = new nsGlobalWindow(aOuterWindow); + RefPtr window; + if (aOuterWindow) { + window = new nsGlobalWindowInner( + static_cast(aOuterWindow)); + } else { + window = new nsGlobalWindowOuter(); + } window->InitWasOffline(); return window.forget(); } @@ -14503,8 +14525,8 @@ nsGlobalWindow::ClearDocumentDependentSlots(JSContext* aCx) MOZ_ASSERT(IsInnerWindow()); // If JSAPI OOMs here, there is basically nothing we can do to recover safely. - if (!WindowBinding::ClearCachedDocumentValue(aCx, this) || - !WindowBinding::ClearCachedPerformanceValue(aCx, this)) { + if (!WindowBinding::ClearCachedDocumentValue(aCx, AssertInner()) || + !WindowBinding::ClearCachedPerformanceValue(aCx, AssertInner())) { MOZ_CRASH("Unhandlable OOM while clearing document dependent slots."); } } @@ -14534,13 +14556,13 @@ nsPIDOMWindowOuter::SetLargeAllocStatus(LargeAllocStatus aStatus) bool nsPIDOMWindowOuter::IsTopLevelWindow() { - return nsGlobalWindow::Cast(this)->IsTopLevelWindow(); + return nsGlobalWindowOuter::Cast(this)->IsTopLevelWindow(); } bool nsPIDOMWindowOuter::HadOriginalOpener() const { - return nsGlobalWindow::Cast(this)->HadOriginalOpener(); + return nsGlobalWindowOuter::Cast(this)->HadOriginalOpener(); } void @@ -14873,7 +14895,8 @@ nsGlobalWindow::TabGroupOuter() MOZ_ASSERT_IF(parent, parent->TabGroup() == mTabGroup); nsCOMPtr piOpener = do_QueryReferent(mOpener); nsPIDOMWindowOuter* opener = GetSanitizedOpener(piOpener); - MOZ_ASSERT_IF(opener && Cast(opener) != this, opener->TabGroup() == mTabGroup); + MOZ_ASSERT_IF(opener && nsGlobalWindowOuter::Cast(opener) != this, + opener->TabGroup() == mTabGroup); } mIsValidatingTabGroup = false; } @@ -15056,6 +15079,51 @@ nsGlobalWindow::GetIntlUtils(ErrorResult& aError) return mIntlUtils; } +nsGlobalWindowOuter::nsGlobalWindowOuter() + : nsGlobalWindow(nullptr) +{ + // Add ourselves to the outer windows list. + MOZ_ASSERT(sOuterWindowsById, "Outer Windows hash table must be created!"); + + // |this| is an outer window, add to the outer windows list. + MOZ_ASSERT(!sOuterWindowsById->Get(mWindowID), + "This window shouldn't be in the hash table yet!"); + // We seem to see crashes in release builds because of null |sOuterWindowsById|. + if (sOuterWindowsById) { + sOuterWindowsById->Put(mWindowID, AssertOuter()); + } +} + +nsGlobalWindowOuter::~nsGlobalWindowOuter() +{ + // NOTE: We remove ourselves from the sOuterWindowsById table in + // nsGlobalWindow::~nsGlobalWindow. We can't do it here because we have to + // remove ourselves before running some cleanup in that function. +} + +nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow) + : nsGlobalWindow(aOuterWindow) +{ + // Add ourselves to the inner windows list. + MOZ_ASSERT(sInnerWindowsById, "Inner Windows hash table must be created!"); + MOZ_ASSERT(!sInnerWindowsById->Get(mWindowID), + "This window shouldn't be in the hash table yet!"); + // We seem to see crashes in release builds because of null |sInnerWindowsById|. + if (sInnerWindowsById) { + sInnerWindowsById->Put(mWindowID, AssertInner()); + // NOTE: We remove ourselves from this table in + // nsGlobalWindow::~nsGlobalWindow. We can't do it here because we have to + // remove ourselves before running some cleanup in that function. + } +} + +nsGlobalWindowInner::~nsGlobalWindowInner() +{ + // NOTE: We remove ourselves from the sInnerWindowsById table in + // nsGlobalWindow::~nsGlobalWindow. We can't do it here because we have to + // remove ourselves before running some cleanup in that function. +} + template class nsPIDOMWindow; template class nsPIDOMWindow; template class nsPIDOMWindow; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 67e17956e009..deaf84ccdf71 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -154,13 +154,13 @@ class IDBFactory; } // namespace mozilla extern already_AddRefed -NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow, +NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindowInner *aWindow, mozilla::dom::Function& aFunction, const mozilla::dom::Sequence& aArguments, mozilla::ErrorResult& aError); extern already_AddRefed -NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow, +NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindowInner *aWindow, const nsAString& aExpression, mozilla::ErrorResult& aError); @@ -228,6 +228,9 @@ private: nsCOMPtr mValue; }; +class nsGlobalWindowInner; +class nsGlobalWindowOuter; + //***************************************************************************** // nsGlobalWindow: Global Object for Scripting //***************************************************************************** @@ -272,7 +275,6 @@ class nsGlobalWindow : public mozilla::dom::EventTarget, public: typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeDuration TimeDuration; - typedef nsDataHashtable WindowByIdTable; static void AssertIsOnMainThread() @@ -282,28 +284,8 @@ public: { } #endif - static nsGlobalWindow* Cast(nsPIDOMWindowInner* aPIWin) { - return static_cast( - reinterpret_cast*>(aPIWin)); - } - static const nsGlobalWindow* Cast(const nsPIDOMWindowInner* aPIWin) { - return static_cast( - reinterpret_cast*>(aPIWin)); - } - static nsGlobalWindow* Cast(mozIDOMWindow* aWin) { - return Cast(nsPIDOMWindowInner::From(aWin)); - } - static nsGlobalWindow* Cast(nsPIDOMWindowOuter* aPIWin) { - return static_cast( - reinterpret_cast*>(aPIWin)); - } - static const nsGlobalWindow* Cast(const nsPIDOMWindowOuter* aPIWin) { - return static_cast( - reinterpret_cast*>(aPIWin)); - } - static nsGlobalWindow* Cast(mozIDOMWindowProxy* aWin) { - return Cast(nsPIDOMWindowOuter::From(aWin)); - } + nsGlobalWindowInner* AssertInner(); + nsGlobalWindowOuter* AssertOuter(); // public methods nsPIDOMWindowOuter* GetPrivateParent(); @@ -373,14 +355,7 @@ public: mozilla::ErrorResult& aRv) override; virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override; - virtual nsIGlobalObject* GetOwnerGlobal() const override - { - if (IsOuterWindow()) { - return GetCurrentInnerWindowInternal(); - } - - return const_cast(this); - } + virtual nsIGlobalObject* GetOwnerGlobal() const override; // nsPIDOMWindow virtual nsPIDOMWindowOuter* GetPrivateRoot() override; @@ -506,21 +481,9 @@ public: } already_AddRefed GetTop() override; nsPIDOMWindowOuter* GetScriptableTop() override; - inline nsGlobalWindow *GetTopInternal() - { - nsGlobalWindow* outer = IsOuterWindow() ? this : GetOuterWindowInternal(); - nsCOMPtr top = outer ? outer->GetTop() : nullptr; - if (top) { - return nsGlobalWindow::Cast(top); - } - return nullptr; - } + inline nsGlobalWindowOuter *GetTopInternal(); - inline nsGlobalWindow* GetScriptableTopInternal() - { - nsPIDOMWindowOuter* top = GetScriptableTop(); - return nsGlobalWindow::Cast(top); - } + inline nsGlobalWindowOuter* GetScriptableTopInternal(); nsPIDOMWindowOuter* GetChildWindow(const nsAString& aName); @@ -569,30 +532,13 @@ public: }; friend class TemporarilyDisableDialogs; - nsIScriptContext *GetContextInternal() - { - if (mOuterWindow) { - return GetOuterWindowInternal()->mContext; - } + nsIScriptContext *GetContextInternal(); - return mContext; - } + nsGlobalWindowOuter *GetOuterWindowInternal(); - nsGlobalWindow *GetOuterWindowInternal() - { - return nsGlobalWindow::Cast(GetOuterWindow()); - } + nsGlobalWindowInner* GetCurrentInnerWindowInternal() const; - nsGlobalWindow* GetCurrentInnerWindowInternal() const - { - MOZ_ASSERT(IsOuterWindow()); - return nsGlobalWindow::Cast(mInnerWindow); - } - - nsGlobalWindow* EnsureInnerWindowInternal() - { - return nsGlobalWindow::Cast(AsOuter()->EnsureInnerWindow()); - } + nsGlobalWindowInner* EnsureInnerWindowInternal(); bool IsCreatingInnerWindow() const { @@ -682,13 +628,7 @@ public: return mHadOriginalOpener; } - bool - IsTopLevelWindow() - { - MOZ_ASSERT(IsOuterWindow()); - nsPIDOMWindowOuter* parentWindow = GetScriptableTop(); - return parentWindow == this->AsOuter(); - } + bool IsTopLevelWindow(); virtual void FirePopupBlockedEvent(nsIDocument* aDoc, @@ -700,34 +640,6 @@ public: return mSerial; } - static nsGlobalWindow* GetOuterWindowWithId(uint64_t aWindowID) { - AssertIsOnMainThread(); - - if (!sWindowsById) { - return nullptr; - } - - nsGlobalWindow* outerWindow = sWindowsById->Get(aWindowID); - return outerWindow && !outerWindow->IsInnerWindow() ? outerWindow : nullptr; - } - - static nsGlobalWindow* GetInnerWindowWithId(uint64_t aInnerWindowID) { - AssertIsOnMainThread(); - - if (!sWindowsById) { - return nullptr; - } - - nsGlobalWindow* innerWindow = sWindowsById->Get(aInnerWindowID); - return innerWindow && innerWindow->IsInnerWindow() ? innerWindow : nullptr; - } - - static WindowByIdTable* GetWindowsTable() { - AssertIsOnMainThread(); - - return sWindowsById; - } - void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const; // Inner windows only. @@ -855,8 +767,8 @@ public: static JSObject* CreateNamedPropertiesObject(JSContext *aCx, JS::Handle aProto); - nsGlobalWindow* Window(); - nsGlobalWindow* Self(); + nsGlobalWindowInner* Window(); + nsGlobalWindowInner* Self(); nsIDocument* GetDocument() { return GetDoc(); @@ -1473,7 +1385,7 @@ protected: } void FreeInnerObjects(); - nsGlobalWindow *CallerInnerWindow(); + nsGlobalWindowInner *CallerInnerWindow(); // Only to be called on an inner window. // aDocument must not be null. @@ -1487,14 +1399,7 @@ protected: public: // popup tracking - bool IsPopupSpamWindow() - { - if (IsInnerWindow() && !mOuterWindow) { - return false; - } - - return GetOuterWindowInternal()->mIsPopupSpam; - } + bool IsPopupSpamWindow(); // Outer windows only. void SetIsPopupSpamWindow(bool aIsPopupSpam); @@ -1669,10 +1574,7 @@ public: void ScrollTo(const mozilla::CSSIntPoint& aScroll, const mozilla::dom::ScrollOptions& aOptions); - bool IsFrame() - { - return GetParentInternal() != nullptr; - } + bool IsFrame(); // Outer windows only. // If aLookForCallerOnJSStack is true, this method will look at the JS stack @@ -1759,7 +1661,7 @@ protected: mozilla::CSSIntPoint GetScreenXY(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError); - nsGlobalWindow* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError); + nsGlobalWindowInner* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError); void PostMessageMozOuter(JSContext* aCx, JS::Handle aMessage, const nsAString& aTargetOrigin, @@ -2088,8 +1990,6 @@ protected: friend class DesktopNotification; friend class mozilla::dom::TimeoutManager; friend class IdleRequestExecutor; - - static WindowByIdTable* sWindowsById; }; inline nsISupports* @@ -2104,8 +2004,198 @@ ToCanonicalSupports(nsGlobalWindow *p) return static_cast(p); } +class nsGlobalWindowOuter : public nsGlobalWindow +{ +public: + typedef nsDataHashtable OuterWindowByIdTable; + + friend class nsGlobalWindow; + + static nsGlobalWindowOuter* Cast(nsPIDOMWindowOuter* aPIWin) { + return static_cast( + reinterpret_cast*>(aPIWin)); + } + static const nsGlobalWindowOuter* Cast(const nsPIDOMWindowOuter* aPIWin) { + return static_cast( + reinterpret_cast*>(aPIWin)); + } + static nsGlobalWindowOuter* Cast(mozIDOMWindowProxy* aWin) { + return Cast(nsPIDOMWindowOuter::From(aWin)); + } + + static nsGlobalWindowOuter* + GetOuterWindowWithId(uint64_t aWindowID) + { + AssertIsOnMainThread(); + + if (!sOuterWindowsById) { + return nullptr; + } + + nsGlobalWindowOuter* outerWindow = sOuterWindowsById->Get(aWindowID); + MOZ_ASSERT(!outerWindow || outerWindow->IsOuterWindow(), + "Inner window in sOuterWindowsById?"); + return outerWindow; + } + + static OuterWindowByIdTable* GetWindowsTable() { + AssertIsOnMainThread(); + + return sOuterWindowsById; + } + +private: + nsGlobalWindowOuter(); + ~nsGlobalWindowOuter(); + + static OuterWindowByIdTable* sOuterWindowsById; +}; + +class nsGlobalWindowInner : public nsGlobalWindow +{ +public: + typedef nsDataHashtable InnerWindowByIdTable; + + friend class nsGlobalWindow; + + static nsGlobalWindowInner* Cast(nsPIDOMWindowInner* aPIWin) { + return static_cast( + reinterpret_cast*>(aPIWin)); + } + static const nsGlobalWindowInner* Cast(const nsPIDOMWindowInner* aPIWin) { + return static_cast( + reinterpret_cast*>(aPIWin)); + } + static nsGlobalWindowInner* Cast(mozIDOMWindow* aWin) { + return Cast(nsPIDOMWindowInner::From(aWin)); + } + + static nsGlobalWindowInner* + GetInnerWindowWithId(uint64_t aInnerWindowID) + { + AssertIsOnMainThread(); + + if (!sInnerWindowsById) { + return nullptr; + } + + nsGlobalWindowInner* innerWindow = + sInnerWindowsById->Get(aInnerWindowID); + MOZ_ASSERT(!innerWindow || innerWindow->IsInnerWindow(), + "Outer window in sInnerWindowsById?"); + return innerWindow; + } + + static InnerWindowByIdTable* GetWindowsTable() { + AssertIsOnMainThread(); + + return sInnerWindowsById; + } + +private: + explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuter); + ~nsGlobalWindowInner(); + + static InnerWindowByIdTable* sInnerWindowsById; +}; + +inline nsIGlobalObject* +nsGlobalWindow::GetOwnerGlobal() const +{ + if (IsOuterWindow()) { + return GetCurrentInnerWindowInternal(); + } + + return const_cast(this); +} + +inline nsGlobalWindowOuter* +nsGlobalWindow::GetTopInternal() +{ + nsGlobalWindow* outer = IsOuterWindow() ? this : GetOuterWindowInternal(); + nsCOMPtr top = outer ? outer->GetTop() : nullptr; + if (top) { + return nsGlobalWindowOuter::Cast(top); + } + return nullptr; +} + +inline nsGlobalWindowOuter* +nsGlobalWindow::GetScriptableTopInternal() +{ + nsPIDOMWindowOuter* top = GetScriptableTop(); + return nsGlobalWindowOuter::Cast(top); +} + +inline nsIScriptContext* +nsGlobalWindow::GetContextInternal() + { + if (mOuterWindow) { + return GetOuterWindowInternal()->mContext; + } + + return mContext; + } + +inline nsGlobalWindowOuter* +nsGlobalWindow::GetOuterWindowInternal() +{ + return nsGlobalWindowOuter::Cast(GetOuterWindow()); +} + +inline nsGlobalWindowInner* +nsGlobalWindow::GetCurrentInnerWindowInternal() const +{ + MOZ_ASSERT(IsOuterWindow()); + return nsGlobalWindowInner::Cast(mInnerWindow); +} + +inline nsGlobalWindowInner* +nsGlobalWindow::EnsureInnerWindowInternal() +{ + return nsGlobalWindowInner::Cast(AsOuter()->EnsureInnerWindow()); +} + +inline bool +nsGlobalWindow::IsTopLevelWindow() +{ + MOZ_ASSERT(IsOuterWindow()); + nsPIDOMWindowOuter* parentWindow = GetScriptableTop(); + return parentWindow == this->AsOuter(); +} + +inline bool +nsGlobalWindow::IsPopupSpamWindow() +{ + if (IsInnerWindow() && !mOuterWindow) { + return false; + } + + return GetOuterWindowInternal()->mIsPopupSpam; +} + +inline bool +nsGlobalWindow::IsFrame() +{ + return GetParentInternal() != nullptr; +} + +inline nsGlobalWindowInner* +nsGlobalWindow::AssertInner() +{ + MOZ_RELEASE_ASSERT(IsInnerWindow()); + return static_cast(this); +} + +inline nsGlobalWindowOuter* +nsGlobalWindow::AssertOuter() +{ + MOZ_RELEASE_ASSERT(IsOuterWindow()); + return static_cast(this); +} + /* factory function */ -inline already_AddRefed +inline already_AddRefed NS_NewScriptGlobalObject(bool aIsChrome) { RefPtr global; @@ -2116,7 +2206,7 @@ NS_NewScriptGlobalObject(bool aIsChrome) global = nsGlobalWindow::Create(nullptr); } - return global.forget(); + return global.forget().downcast(); } #endif /* nsGlobalWindow_h___ */ diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 64cd27035576..4cb738a474bb 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -62,6 +62,7 @@ class nsIDocShell; class nsDocShell; class nsDOMNavigationTiming; class nsFrameLoader; +class nsGlobalWindowInner; class nsHTMLCSSStyleSheet; class nsHTMLDocument; class nsHTMLStyleSheet; @@ -3045,7 +3046,7 @@ public: JS::Handle aResult, mozilla::ErrorResult& rv); // Touch event handlers already on nsINode already_AddRefed - CreateTouch(nsGlobalWindow* aView, mozilla::dom::EventTarget* aTarget, + CreateTouch(nsGlobalWindowInner* aView, mozilla::dom::EventTarget* aTarget, int32_t aIdentifier, int32_t aPageX, int32_t aPageY, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY, diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index c1907129b371..001ce57a90c8 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -1386,7 +1386,7 @@ nsPIDOMWindowOuter* nsINode::GetOwnerGlobalForBindings() { bool dummy; - auto* window = static_cast(OwnerDoc()->GetScriptHandlingObject(dummy)); + auto* window = static_cast(OwnerDoc()->GetScriptHandlingObject(dummy)); return window ? nsPIDOMWindowOuter::GetFromCurrentInner(window->AsInner()) : nullptr; } diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 95e6d4b336bb..46682e7210ac 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -411,7 +411,7 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal, // Dispatch() must be synchronous for the recursion block // (errorDepth) to work. RefPtr event = - ErrorEvent::Constructor(nsGlobalWindow::Cast(win), + ErrorEvent::Constructor(nsGlobalWindowInner::Cast(win), NS_LITERAL_STRING("error"), aErrorEventInit); event->SetTrusted(true); @@ -472,7 +472,7 @@ public: } RefPtr event = - ErrorEvent::Constructor(nsGlobalWindow::Cast(win), + ErrorEvent::Constructor(nsGlobalWindowInner::Cast(win), NS_LITERAL_STRING("error"), init); event->SetTrusted(true); @@ -514,14 +514,15 @@ DispatchScriptErrorEvent(nsPIDOMWindowInner *win, JS::RootingContext* rootingCx, #ifdef DEBUG // A couple of useful functions to call when you're debugging. -nsGlobalWindow * +nsGlobalWindowInner * JSObject2Win(JSObject *obj) { return xpc::WindowOrNull(obj); } +template void -PrintWinURI(nsGlobalWindow *win) +PrintWinURI(T *win) { if (!win) { printf("No window passed in.\n"); @@ -544,7 +545,20 @@ PrintWinURI(nsGlobalWindow *win) } void -PrintWinCodebase(nsGlobalWindow *win) +PrintWinURIInner(nsGlobalWindowInner* aWin) +{ + return PrintWinURI(aWin); +} + +void +PrintWinURIOuter(nsGlobalWindowOuter* aWin) +{ + return PrintWinURI(aWin); +} + +template +void +PrintWinCodebase(T *win) { if (!win) { printf("No window passed in.\n"); @@ -567,6 +581,18 @@ PrintWinCodebase(nsGlobalWindow *win) printf("%s\n", uri->GetSpecOrDefault().get()); } +void +PrintWinCodebaseInner(nsGlobalWindowInner* aWin) +{ + return PrintWinCodebase(aWin); +} + +void +PrintWinCodebaseOuter(nsGlobalWindowOuter* aWin) +{ + return PrintWinCodebase(aWin); +} + void DumpString(const nsAString &str) { diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp index bdcc5eda6e5b..da4b7c68013f 100644 --- a/dom/base/nsJSTimeoutHandler.cpp +++ b/dom/base/nsJSTimeoutHandler.cpp @@ -35,11 +35,11 @@ public: nsJSScriptTimeoutHandler(); // This will call SwapElements on aArguments with an empty array. - nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow* aWindow, + nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindowInner* aWindow, Function& aFunction, nsTArray>&& aArguments, ErrorResult& aError); - nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow* aWindow, + nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindowInner* aWindow, const nsAString& aExpression, bool* aAllowEval, ErrorResult& aError); nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate, @@ -165,7 +165,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSScriptTimeoutHandler) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSScriptTimeoutHandler) static bool -CheckCSPForEval(JSContext* aCx, nsGlobalWindow* aWindow, ErrorResult& aError) +CheckCSPForEval(JSContext* aCx, nsGlobalWindowInner* aWindow, ErrorResult& aError) { // if CSP is enabled, and setTimeout/setInterval was called with a string, // disable the registration and log an error @@ -219,7 +219,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler() } nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx, - nsGlobalWindow *aWindow, + nsGlobalWindowInner *aWindow, Function& aFunction, nsTArray>&& aArguments, ErrorResult& aError) @@ -238,7 +238,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx, } nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx, - nsGlobalWindow *aWindow, + nsGlobalWindowInner *aWindow, const nsAString& aExpression, bool* aAllowEval, ErrorResult& aError) @@ -328,7 +328,7 @@ nsJSScriptTimeoutHandler::GetHandlerText() } already_AddRefed -NS_CreateJSTimeoutHandler(JSContext *aCx, nsGlobalWindow *aWindow, +NS_CreateJSTimeoutHandler(JSContext *aCx, nsGlobalWindowInner *aWindow, Function& aFunction, const Sequence& aArguments, ErrorResult& aError) @@ -345,7 +345,7 @@ NS_CreateJSTimeoutHandler(JSContext *aCx, nsGlobalWindow *aWindow, } already_AddRefed -NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow, +NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindowInner *aWindow, const nsAString& aExpression, ErrorResult& aError) { bool allowEval = false; diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index 6d5d03bfaacb..8236d11e799b 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -83,7 +83,7 @@ nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext) if (!aContext) return 0; - nsGlobalWindow* win = xpc::CurrentWindowOrNull(aContext); + nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aContext); return win ? win->WindowID() : 0; } diff --git a/dom/base/nsWindowMemoryReporter.cpp b/dom/base/nsWindowMemoryReporter.cpp index bdc18ec9232b..693dba09d626 100644 --- a/dom/base/nsWindowMemoryReporter.cpp +++ b/dom/base/nsWindowMemoryReporter.cpp @@ -49,7 +49,7 @@ NS_IMPL_ISUPPORTS(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver, nsISupportsWeakReference) static nsresult -AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow, +AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindowOuter* aWindow, nsTabSizes* aSizes) { // Measure the window. @@ -58,8 +58,7 @@ AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow, aWindow->AddSizeOfIncludingThis(windowSizes); // Measure the inner window, if there is one. - nsGlobalWindow* inner = aWindow->IsOuterWindow() ? aWindow->GetCurrentInnerWindowInternal() - : nullptr; + nsGlobalWindowInner* inner = aWindow->GetCurrentInnerWindowInternal(); if (inner) { inner->AddSizeOfIncludingThis(windowSizes); } @@ -79,7 +78,7 @@ AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow, NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_STATE(child); - nsGlobalWindow* childWin = nsGlobalWindow::Cast(child); + nsGlobalWindowOuter* childWin = nsGlobalWindowOuter::Cast(child); rv = AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes); NS_ENSURE_SUCCESS(rv, rv); @@ -90,7 +89,7 @@ AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow, static nsresult NonJSSizeOfTab(nsPIDOMWindowOuter* aWindow, size_t* aDomSize, size_t* aStyleSize, size_t* aOtherSize) { - nsGlobalWindow* window = nsGlobalWindow::Cast(aWindow); + nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(aWindow); nsTabSizes sizes; nsresult rv = AddNonJSSizeOfWindowAndItsDescendents(window, &sizes); @@ -131,7 +130,7 @@ nsWindowMemoryReporter::Get() } static already_AddRefed -GetWindowURI(nsGlobalWindow* aWindow) +GetWindowURI(nsGlobalWindowInner* aWindow) { NS_ENSURE_TRUE(aWindow, nullptr); @@ -162,8 +161,16 @@ GetWindowURI(nsGlobalWindow* aWindow) return uri.forget(); } +// Forward to the inner window if we need to when getting the window's URI. +static already_AddRefed +GetWindowURI(nsGlobalWindowOuter* aWindow) +{ + NS_ENSURE_TRUE(aWindow, nullptr); + return GetWindowURI(aWindow->GetCurrentInnerWindowInternal()); +} + static void -AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr, bool aAnonymize) +AppendWindowURI(nsGlobalWindowInner *aWindow, nsACString& aStr, bool aAnonymize) { nsCOMPtr uri = GetWindowURI(aWindow); @@ -233,7 +240,7 @@ ReportCount(const nsCString& aBasePath, const char* aPathTail, } static void -CollectWindowReports(nsGlobalWindow *aWindow, +CollectWindowReports(nsGlobalWindowInner *aWindow, amIAddonManager *addonManager, nsWindowSizes *aWindowTotalSizes, nsTHashtable *aGhostWindowIDs, @@ -247,7 +254,7 @@ CollectWindowReports(nsGlobalWindow *aWindow, // Avoid calling aWindow->GetTop() if there's no outer window. It will work // just fine, but will spew a lot of warnings. - nsGlobalWindow *top = nullptr; + nsGlobalWindowOuter *top = nullptr; nsCOMPtr location; if (aWindow->GetOuterWindow()) { // Our window should have a null top iff it has a null docshell. @@ -276,7 +283,7 @@ CollectWindowReports(nsGlobalWindow *aWindow, if (top) { windowPath += NS_LITERAL_CSTRING("top("); - AppendWindowURI(top, windowPath, aAnonymize); + AppendWindowURI(top->GetCurrentInnerWindowInternal(), windowPath, aAnonymize); windowPath.AppendPrintf(", id=%" PRIu64 ")", top->WindowID()); aTopWindowPaths->Put(aWindow->WindowID(), windowPath); @@ -538,14 +545,14 @@ CollectWindowReports(nsGlobalWindow *aWindow, #undef REPORT_COUNT } -typedef nsTArray< RefPtr > WindowArray; +typedef nsTArray< RefPtr > WindowArray; NS_IMETHODIMP nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) { - nsGlobalWindow::WindowByIdTable* windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowInner::InnerWindowByIdTable* windowsById = + nsGlobalWindowInner::GetWindowsTable(); NS_ENSURE_TRUE(windowsById, NS_OK); // Hold on to every window in memory so that window objects can't be @@ -560,14 +567,14 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport, nsTHashtable ghostWindows; CheckForGhostWindows(&ghostWindows); for (auto iter = ghostWindows.ConstIter(); !iter.Done(); iter.Next()) { - nsGlobalWindow::WindowByIdTable* windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowInner::InnerWindowByIdTable* windowsById = + nsGlobalWindowInner::GetWindowsTable(); if (!windowsById) { NS_WARNING("Couldn't get window-by-id hashtable?"); continue; } - nsGlobalWindow* window = windowsById->Get(iter.Get()->GetKey()); + nsGlobalWindowInner* window = windowsById->Get(iter.Get()->GetKey()); if (!window) { NS_WARNING("Could not look up window?"); continue; @@ -784,7 +791,7 @@ nsWindowMemoryReporter::Observe(nsISupports *aSubject, const char *aTopic, } void -nsWindowMemoryReporter::ObserveDOMWindowDetached(nsGlobalWindow* aWindow) +nsWindowMemoryReporter::ObserveDOMWindowDetached(nsGlobalWindowInner* aWindow) { nsWeakPtr weakWindow = do_GetWeakReference(static_cast(aWindow)); if (!weakWindow) { @@ -881,8 +888,8 @@ nsWindowMemoryReporter::CheckForGhostWindows( return; } - nsGlobalWindow::WindowByIdTable *windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowInner::InnerWindowByIdTable *windowsById = + nsGlobalWindowInner::GetWindowsTable(); if (!windowsById) { NS_WARNING("GetWindowsTable returned null"); return; @@ -898,7 +905,7 @@ nsWindowMemoryReporter::CheckForGhostWindows( for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { // Null outer window implies null top, but calling GetTop() when there's no // outer window causes us to spew debug warnings. - nsGlobalWindow* window = iter.UserData(); + nsGlobalWindowInner* window = iter.UserData(); if (!window->GetOuterWindow() || !window->GetTopInternal()) { // This window is detached, so we don't care about its domain. continue; @@ -948,7 +955,7 @@ nsWindowMemoryReporter::CheckForGhostWindows( continue; } - nsCOMPtr uri = GetWindowURI(nsGlobalWindow::Cast(window)); + nsCOMPtr uri = GetWindowURI(nsGlobalWindowInner::Cast(window)); nsAutoCString domain; if (uri) { @@ -1004,8 +1011,8 @@ nsWindowMemoryReporter::UnlinkGhostWindows() return; } - nsGlobalWindow::WindowByIdTable* windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowInner::InnerWindowByIdTable* windowsById = + nsGlobalWindowInner::GetWindowsTable(); if (!windowsById) { return; } @@ -1021,13 +1028,13 @@ nsWindowMemoryReporter::UnlinkGhostWindows() nsTHashtable ghostWindows; sWindowReporter->CheckForGhostWindows(&ghostWindows); for (auto iter = ghostWindows.ConstIter(); !iter.Done(); iter.Next()) { - nsGlobalWindow::WindowByIdTable* windowsById = - nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowInner::InnerWindowByIdTable* windowsById = + nsGlobalWindowInner::GetWindowsTable(); if (!windowsById) { continue; } - RefPtr window = windowsById->Get(iter.Get()->GetKey()); + RefPtr window = windowsById->Get(iter.Get()->GetKey()); if (window) { window->RiskyUnlink(); } diff --git a/dom/base/nsWindowMemoryReporter.h b/dom/base/nsWindowMemoryReporter.h index 7e7df370fe5e..4c3d0c992458 100644 --- a/dom/base/nsWindowMemoryReporter.h +++ b/dom/base/nsWindowMemoryReporter.h @@ -101,7 +101,7 @@ public: #endif static nsWindowMemoryReporter* Get(); - void ObserveDOMWindowDetached(nsGlobalWindow* aWindow); + void ObserveDOMWindowDetached(nsGlobalWindowInner* aWindow); static int64_t GhostWindowsDistinguishedAmount(); diff --git a/dom/base/nsWindowRoot.cpp b/dom/base/nsWindowRoot.cpp index 22b56b9bf22f..26363ad345fa 100644 --- a/dom/base/nsWindowRoot.cpp +++ b/dom/base/nsWindowRoot.cpp @@ -295,7 +295,7 @@ nsWindowRoot::GetControllerForCommand(const char* aCommand, } // XXXndeakin P3 is this casting safe? - nsGlobalWindow *win = nsGlobalWindow::Cast(focusedWindow); + nsGlobalWindowOuter *win = nsGlobalWindowOuter::Cast(focusedWindow); focusedWindow = win->GetPrivateParent(); } @@ -367,7 +367,7 @@ nsWindowRoot::GetEnabledDisabledCommands(nsTArray& aEnabledCommands, aEnabledCommands, aDisabledCommands); } - nsGlobalWindow* win = nsGlobalWindow::Cast(focusedWindow); + nsGlobalWindowOuter* win = nsGlobalWindowOuter::Cast(focusedWindow); focusedWindow = win->GetPrivateParent(); } } diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 41e9a5d9021e..96ad690d280f 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -2860,7 +2860,7 @@ EnforceNotInPrerendering(JSContext* aCx, JSObject* aObj) // Without a this object, we cannot check the safety. return true; } - nsGlobalWindow* window = xpc::WindowGlobalOrNull(thisObj); + nsGlobalWindowInner* window = xpc::WindowGlobalOrNull(thisObj); if (!window) { // Without a window, we cannot check the safety. return true; @@ -3151,7 +3151,7 @@ ConvertExceptionToPromise(JSContext* cx, /* static */ void -CreateGlobalOptions::TraceGlobal(JSTracer* aTrc, JSObject* aObj) +CreateGlobalOptions::TraceGlobal(JSTracer* aTrc, JSObject* aObj) { xpc::TraceXPCGlobal(aTrc, aObj); } @@ -3181,8 +3181,8 @@ RegisterDOMNames() /* static */ bool -CreateGlobalOptions::PostCreateGlobal(JSContext* aCx, - JS::Handle aGlobal) +CreateGlobalOptions::PostCreateGlobal(JSContext* aCx, + JS::Handle aGlobal) { nsresult rv = RegisterDOMNames(); if (NS_FAILED(rv)) { @@ -3534,7 +3534,7 @@ GetCustomElementReactionsStack(JS::Handle aObj) return nullptr; } - nsGlobalWindow* window = xpc::WindowGlobalOrNull(obj); + nsGlobalWindowInner* window = xpc::WindowGlobalOrNull(obj); if (!window) { return nullptr; } @@ -3732,7 +3732,7 @@ AssertReflectorHasGivenProto(JSContext* aCx, JSObject* aReflector, void SetDocumentAndPageUseCounter(JSObject* aObject, UseCounter aUseCounter) { - nsGlobalWindow* win = xpc::WindowGlobalOrNull(js::UncheckedUnwrap(aObject)); + nsGlobalWindowInner* win = xpc::WindowGlobalOrNull(js::UncheckedUnwrap(aObject)); if (win && win->GetDocument()) { win->GetDocument()->SetDocumentAndPageUseCounter(aUseCounter); } diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index a04c66cf9a4a..49a2f8281f03 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -3097,7 +3097,7 @@ struct CreateGlobalOptions }; template <> -struct CreateGlobalOptions +struct CreateGlobalOptions { static constexpr ProtoAndIfaceCache::Kind ProtoAndIfaceCacheKind = ProtoAndIfaceCache::WindowLike; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index b22891936d12..1e89b10237a1 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1361,7 +1361,8 @@ DOMInterfaces = { }, 'Window': { - 'nativeType': 'nsGlobalWindow', + 'nativeType': 'nsGlobalWindowInner', + 'headerFile': 'nsGlobalWindow.h', 'binaryNames': { 'postMessage': 'postMessageMoz', }, diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp index 19980d39b117..7113ac4cd973 100644 --- a/dom/bindings/CallbackObject.cpp +++ b/dom/bindings/CallbackObject.cpp @@ -182,7 +182,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, // Now get the global for this callback. Note that for the case of // JS-implemented WebIDL we never have a window here. - nsGlobalWindow* win = mIsMainThread && !aIsJSImplementedWebIDL + nsGlobalWindowInner* win = mIsMainThread && !aIsJSImplementedWebIDL ? xpc::WindowGlobalOrNull(realCallback) : nullptr; if (win) { diff --git a/dom/bindings/WebIDLGlobalNameHash.cpp b/dom/bindings/WebIDLGlobalNameHash.cpp index c88ecaee9321..95b85bfc1874 100644 --- a/dom/bindings/WebIDLGlobalNameHash.cpp +++ b/dom/bindings/WebIDLGlobalNameHash.cpp @@ -228,7 +228,7 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx, // appearance of mutating things that opt code uses. #ifdef DEBUG JS::Rooted temp(aCx, global); - DebugOnly win; + DebugOnly win; MOZ_ASSERT(NS_SUCCEEDED(UNWRAP_OBJECT(Window, &temp, win))); #endif } diff --git a/dom/bindings/nsScriptError.cpp b/dom/bindings/nsScriptError.cpp index d77b8f9eba1e..5b96082eade0 100644 --- a/dom/bindings/nsScriptError.cpp +++ b/dom/bindings/nsScriptError.cpp @@ -61,8 +61,8 @@ nsScriptErrorBase::InitializeOnMainThread() MOZ_ASSERT(!mInitializedOnMainThread); if (mInnerWindowID) { - nsGlobalWindow* window = - nsGlobalWindow::GetInnerWindowWithId(mInnerWindowID); + nsGlobalWindowInner* window = + nsGlobalWindowInner::GetInnerWindowWithId(mInnerWindowID); if (window) { nsPIDOMWindowOuter* outer = window->GetOuterWindow(); if (outer) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index bf94cd9579f3..0ae1a0731571 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -5501,7 +5501,7 @@ CanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& aOp, } void -CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& aWindow, double aX, +CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow, double aX, double aY, double aW, double aH, const nsAString& aBgColor, uint32_t aFlags, ErrorResult& aError) @@ -6015,6 +6015,7 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t aX, int32_t aY, uint32_t return NS_ERROR_FAILURE; } + DataSourceSurface::MappedSurface map; RefPtr sourceSurface; uint8_t* lockedBits = nullptr; uint8_t* dstData; @@ -6036,11 +6037,15 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t aX, int32_t aY, uint32_t if (!sourceSurface) { return NS_ERROR_FAILURE; } - dstData = sourceSurface->GetData(); + if (!sourceSurface->Map(DataSourceSurface::READ_WRITE, &map)) { + return NS_ERROR_FAILURE; + } + + dstData = map.mData; if (!dstData) { return NS_ERROR_OUT_OF_MEMORY; } - dstStride = sourceSurface->Stride(); + dstStride = map.mStride; dstFormat = sourceSurface->GetFormat(); } @@ -6055,6 +6060,7 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t aX, int32_t aY, uint32_t if (lockedBits) { mTarget->ReleaseBits(lockedBits); } else if (sourceSurface) { + sourceSurface->Unmap(); mTarget->CopySurface(sourceSurface, dirtyRect - dirtyRect.TopLeft(), dirtyRect.TopLeft()); } diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index 6925c3390b43..e29163a8d0b9 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -31,7 +31,7 @@ #include "Layers.h" #include "nsBidi.h" -class nsGlobalWindow; +class nsGlobalWindowInner; class nsXULElement; namespace mozilla { @@ -408,7 +408,7 @@ public: } } - void DrawWindow(nsGlobalWindow& aWindow, double aX, double aY, + void DrawWindow(nsGlobalWindowInner& aWindow, double aX, double aY, double aW, double aH, const nsAString& aBgColor, uint32_t aFlags, mozilla::ErrorResult& aError); diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp index f02b977ce0e9..a8e6d0fd9f76 100644 --- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -223,17 +223,19 @@ CreateImageFromRawData(const gfx::IntSize& aSize, } // Convert RGBA to BGRA + DataSourceSurface::MappedSurface rgbaMap; RefPtr rgbaDataSurface = rgbaSurface->GetDataSurface(); + if (NS_WARN_IF(!rgbaDataSurface->Map(DataSourceSurface::MapType::READ, &rgbaMap))) { + return nullptr; + } + RefPtr bgraDataSurface = Factory::CreateDataSourceSurfaceWithStride(rgbaDataSurface->GetSize(), SurfaceFormat::B8G8R8A8, - rgbaDataSurface->Stride()); + rgbaMap.mStride); - DataSourceSurface::MappedSurface rgbaMap; DataSourceSurface::MappedSurface bgraMap; - - if (NS_WARN_IF(!rgbaDataSurface->Map(DataSourceSurface::MapType::READ, &rgbaMap)) || - NS_WARN_IF(!bgraDataSurface->Map(DataSourceSurface::MapType::WRITE, &bgraMap))) { + if (NS_WARN_IF(!bgraDataSurface->Map(DataSourceSurface::MapType::WRITE, &bgraMap))) { return nullptr; } diff --git a/dom/canvas/ImageUtils.cpp b/dom/canvas/ImageUtils.cpp index ff8e59abfb76..3964b22d6a00 100644 --- a/dom/canvas/ImageUtils.cpp +++ b/dom/canvas/ImageUtils.cpp @@ -117,7 +117,8 @@ public: virtual uint32_t GetBufferLength() const { - const uint32_t stride = Surface()->Stride(); + DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ); + const uint32_t stride = map.GetStride(); const IntSize size = Surface()->GetSize(); return (uint32_t)(size.height * stride); } diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp index 53dcf56bf67d..ad9cba92b57e 100644 --- a/dom/console/Console.cpp +++ b/dom/console/Console.cpp @@ -375,7 +375,7 @@ protected: AutoJSAPI jsapi; MOZ_ASSERT(aWindow); - RefPtr win = nsGlobalWindow::Cast(aWindow); + RefPtr win = nsGlobalWindowInner::Cast(aWindow); if (NS_WARN_IF(!jsapi.Init(win))) { return; } @@ -1296,7 +1296,7 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName, aMethodName == MethodTimeEnd || aMethodName == MethodTimeStamp) { if (mWindow) { - nsGlobalWindow *win = nsGlobalWindow::Cast(mWindow); + nsGlobalWindowInner *win = nsGlobalWindowInner::Cast(mWindow); MOZ_ASSERT(win); RefPtr performance = win->GetPerformance(); @@ -2458,7 +2458,7 @@ Console::GetConsoleInternal(const GlobalObject& aGlobal, ErrorResult& aRv) return nullptr; } - nsGlobalWindow* window = nsGlobalWindow::Cast(innerWindow); + nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(innerWindow); return window->GetConsole(aRv); } diff --git a/dom/events/CompositionEvent.cpp b/dom/events/CompositionEvent.cpp index dd61e594e03e..feb82cdba900 100644 --- a/dom/events/CompositionEvent.cpp +++ b/dom/events/CompositionEvent.cpp @@ -81,7 +81,7 @@ void CompositionEvent::InitCompositionEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, const nsAString& aData, const nsAString& aLocale) { diff --git a/dom/events/CompositionEvent.h b/dom/events/CompositionEvent.h index fb3b55c2a3e1..569bf3b2cd41 100644 --- a/dom/events/CompositionEvent.h +++ b/dom/events/CompositionEvent.h @@ -42,7 +42,7 @@ public: void InitCompositionEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, const nsAString& aData, const nsAString& aLocale); void GetData(nsAString&) const; diff --git a/dom/events/DOMEventTargetHelper.cpp b/dom/events/DOMEventTargetHelper.cpp index a89d88564aac..54af519f8aee 100644 --- a/dom/events/DOMEventTargetHelper.cpp +++ b/dom/events/DOMEventTargetHelper.cpp @@ -90,7 +90,7 @@ NS_IMPL_DOMTARGET_DEFAULTS(DOMEventTargetHelper) DOMEventTargetHelper::~DOMEventTargetHelper() { if (nsPIDOMWindowInner* owner = GetOwner()) { - nsGlobalWindow::Cast(owner)->RemoveEventTargetObject(this); + nsGlobalWindowInner::Cast(owner)->RemoveEventTargetObject(this); } if (mListenerManager) { mListenerManager->Disconnect(); @@ -111,7 +111,7 @@ DOMEventTargetHelper::BindToOwner(nsIGlobalObject* aOwner) nsCOMPtr parentObject = do_QueryReferent(mParentObject); if (parentObject) { if (mOwnerWindow) { - nsGlobalWindow::Cast(mOwnerWindow)->RemoveEventTargetObject(this); + nsGlobalWindowInner::Cast(mOwnerWindow)->RemoveEventTargetObject(this); mOwnerWindow = nullptr; } mParentObject = nullptr; @@ -124,7 +124,7 @@ DOMEventTargetHelper::BindToOwner(nsIGlobalObject* aOwner) mOwnerWindow = nsCOMPtr(do_QueryInterface(aOwner)).get(); if (mOwnerWindow) { mHasOrHasHadOwnerWindow = true; - nsGlobalWindow::Cast(mOwnerWindow)->AddEventTargetObject(this); + nsGlobalWindowInner::Cast(mOwnerWindow)->AddEventTargetObject(this); } } } @@ -133,7 +133,7 @@ void DOMEventTargetHelper::BindToOwner(DOMEventTargetHelper* aOther) { if (mOwnerWindow) { - nsGlobalWindow::Cast(mOwnerWindow)->RemoveEventTargetObject(this); + nsGlobalWindowInner::Cast(mOwnerWindow)->RemoveEventTargetObject(this); mOwnerWindow = nullptr; mParentObject = nullptr; mHasOrHasHadOwnerWindow = false; @@ -147,7 +147,7 @@ DOMEventTargetHelper::BindToOwner(DOMEventTargetHelper* aOther) mOwnerWindow = nsCOMPtr(do_QueryInterface(aOther->GetParentObject())).get(); if (mOwnerWindow) { mHasOrHasHadOwnerWindow = true; - nsGlobalWindow::Cast(mOwnerWindow)->AddEventTargetObject(this); + nsGlobalWindowInner::Cast(mOwnerWindow)->AddEventTargetObject(this); } } } @@ -341,7 +341,7 @@ DOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv) return nullptr; } nsPIDOMWindowInner* owner = GetOwner(); - return owner ? nsGlobalWindow::Cast(owner)->GetContextInternal() + return owner ? nsGlobalWindowInner::Cast(owner)->GetContextInternal() : nullptr; } diff --git a/dom/events/DragEvent.cpp b/dom/events/DragEvent.cpp index 1074c80d8783..a7437e07822c 100644 --- a/dom/events/DragEvent.cpp +++ b/dom/events/DragEvent.cpp @@ -41,7 +41,7 @@ void DragEvent::InitDragEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/DragEvent.h b/dom/events/DragEvent.h index 552b4b7f2f34..58f519c58872 100644 --- a/dom/events/DragEvent.h +++ b/dom/events/DragEvent.h @@ -40,7 +40,7 @@ public: void InitDragEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, int32_t aDetail, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, bool aCtrlKey, bool aAltKey, bool aShiftKey, diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index 0d1285929de4..c0ab4178719e 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -52,7 +52,7 @@ Event::Event(EventTarget* aOwner, Event::Event(nsPIDOMWindowInner* aParent) { - ConstructorInit(nsGlobalWindow::Cast(aParent), nullptr, nullptr); + ConstructorInit(nsGlobalWindowInner::Cast(aParent), nullptr, nullptr); } void diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index a631183e8b42..441036b5c5bf 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -2084,7 +2084,8 @@ EventStateManager::GetContentViewer(nsIContentViewer** aCv) if (!tabChild->ParentIsActive()) return NS_OK; } - nsCOMPtr contentWindow = nsGlobalWindow::Cast(rootWindow)->GetContent(); + nsCOMPtr contentWindow = + nsGlobalWindowOuter::Cast(rootWindow)->GetContent(); if (!contentWindow) return NS_ERROR_FAILURE; nsIDocument *doc = contentWindow->GetDoc(); diff --git a/dom/events/FocusEvent.cpp b/dom/events/FocusEvent.cpp index db6796d3dfd1..b4f46c6749f7 100644 --- a/dom/events/FocusEvent.cpp +++ b/dom/events/FocusEvent.cpp @@ -46,7 +46,7 @@ void FocusEvent::InitFocusEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, EventTarget* aRelatedTarget) { diff --git a/dom/events/FocusEvent.h b/dom/events/FocusEvent.h index 7d6a0b4d110d..13c8b5cb70c3 100644 --- a/dom/events/FocusEvent.h +++ b/dom/events/FocusEvent.h @@ -45,7 +45,7 @@ protected: void InitFocusEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, EventTarget* aRelatedTarget); }; diff --git a/dom/events/KeyboardEvent.cpp b/dom/events/KeyboardEvent.cpp index eac87d0f2d28..0da1396e00a4 100644 --- a/dom/events/KeyboardEvent.cpp +++ b/dom/events/KeyboardEvent.cpp @@ -345,7 +345,7 @@ void KeyboardEvent::InitKeyboardEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, const nsAString& aKey, uint32_t aLocation, bool aCtrlKey, diff --git a/dom/events/KeyboardEvent.h b/dom/events/KeyboardEvent.h index bd0ebc02546e..91c85b4e8f37 100644 --- a/dom/events/KeyboardEvent.h +++ b/dom/events/KeyboardEvent.h @@ -63,7 +63,7 @@ public: void GetInitDict(KeyboardEventInit& aParam); void InitKeyEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, bool aCtrlKey, bool aAltKey, + nsGlobalWindowInner* aView, bool aCtrlKey, bool aAltKey, bool aShiftKey, bool aMetaKey, uint32_t aKeyCode, uint32_t aCharCode) { @@ -74,7 +74,7 @@ public: void InitKeyboardEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, const nsAString& aKey, + nsGlobalWindowInner* aView, const nsAString& aKey, uint32_t aLocation, bool aCtrlKey, bool aAltKey, bool aShiftKey, bool aMetaKey, ErrorResult& aRv); diff --git a/dom/events/MouseEvent.cpp b/dom/events/MouseEvent.cpp index 28cdbf8e7125..8cec896799f9 100644 --- a/dom/events/MouseEvent.cpp +++ b/dom/events/MouseEvent.cpp @@ -54,7 +54,7 @@ void MouseEvent::InitMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, @@ -116,7 +116,7 @@ MouseEvent::InitMouseEvent(const nsAString& aType, nsIDOMEventTarget* aRelatedTarget) { MouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable, - nsGlobalWindow::Cast(aView), aDetail, + nsGlobalWindowInner::Cast(aView), aDetail, aScreenX, aScreenY, aClientX, aClientY, aCtrlKey, aAltKey, aShiftKey, @@ -130,7 +130,7 @@ void MouseEvent::InitMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, @@ -199,7 +199,7 @@ void MouseEvent::InitNSMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/MouseEvent.h b/dom/events/MouseEvent.h index 8ec9a7773f82..07fd11e0b730 100644 --- a/dom/events/MouseEvent.h +++ b/dom/events/MouseEvent.h @@ -58,7 +58,7 @@ public: already_AddRefed GetRelatedTarget(); void GetRegion(nsAString& aRegion); void InitMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, int32_t aDetail, int32_t aScreenX, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, bool aCtrlKey, bool aAltKey, bool aShiftKey, bool aMetaKey, uint16_t aButton, @@ -87,7 +87,7 @@ public: uint16_t MozInputSource() const; void InitNSMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, int32_t aDetail, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, bool aCtrlKey, bool aAltKey, bool aShiftKey, @@ -101,7 +101,7 @@ protected: void InitMouseEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/MouseScrollEvent.cpp b/dom/events/MouseScrollEvent.cpp index 4007c0b516e4..5e1264466508 100644 --- a/dom/events/MouseScrollEvent.cpp +++ b/dom/events/MouseScrollEvent.cpp @@ -42,7 +42,7 @@ void MouseScrollEvent::InitMouseScrollEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/MouseScrollEvent.h b/dom/events/MouseScrollEvent.h index 5cfa03911df3..9453cd1a7717 100644 --- a/dom/events/MouseScrollEvent.h +++ b/dom/events/MouseScrollEvent.h @@ -33,7 +33,7 @@ public: int32_t Axis(); void InitMouseScrollEvent(const nsAString& aType, bool aCanBubble, - bool aCancelable, nsGlobalWindow* aView, + bool aCancelable, nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, bool aCtrlKey, bool aAltKey, bool aShiftKey, diff --git a/dom/events/ScrollAreaEvent.cpp b/dom/events/ScrollAreaEvent.cpp index d3275a4c1d15..7049ee65e425 100644 --- a/dom/events/ScrollAreaEvent.cpp +++ b/dom/events/ScrollAreaEvent.cpp @@ -35,7 +35,7 @@ void ScrollAreaEvent::InitScrollAreaEvent(const nsAString& aEventType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, float aX, float aY, diff --git a/dom/events/ScrollAreaEvent.h b/dom/events/ScrollAreaEvent.h index f672818d35aa..d4327e5a3859 100644 --- a/dom/events/ScrollAreaEvent.h +++ b/dom/events/ScrollAreaEvent.h @@ -63,7 +63,7 @@ public: void InitScrollAreaEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, float aX, float aY, float aWidth, float aHeight); diff --git a/dom/events/SimpleGestureEvent.cpp b/dom/events/SimpleGestureEvent.cpp index 16b2ecc26d2b..b4b83197739a 100644 --- a/dom/events/SimpleGestureEvent.cpp +++ b/dom/events/SimpleGestureEvent.cpp @@ -107,7 +107,7 @@ void SimpleGestureEvent::InitSimpleGestureEvent(const nsAString& aTypeArg, bool aCanBubbleArg, bool aCancelableArg, - nsGlobalWindow* aViewArg, + nsGlobalWindowInner* aViewArg, int32_t aDetailArg, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/SimpleGestureEvent.h b/dom/events/SimpleGestureEvent.h index b394753f6e1c..0a7222956e76 100644 --- a/dom/events/SimpleGestureEvent.h +++ b/dom/events/SimpleGestureEvent.h @@ -45,7 +45,7 @@ public: void InitSimpleGestureEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/TouchEvent.cpp b/dom/events/TouchEvent.cpp index c52971903c7b..e0034315d294 100644 --- a/dom/events/TouchEvent.cpp +++ b/dom/events/TouchEvent.cpp @@ -84,7 +84,7 @@ void TouchEvent::InitTouchEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, bool aCtrlKey, bool aAltKey, @@ -171,7 +171,7 @@ TouchEvent::PrefEnabled(JSContext* aCx, JSObject* aGlobal) { nsIDocShell* docShell = nullptr; if (aGlobal) { - nsGlobalWindow* win = xpc::WindowOrNull(aGlobal); + nsGlobalWindowInner* win = xpc::WindowOrNull(aGlobal); if (win) { docShell = win->GetDocShell(); } diff --git a/dom/events/TouchEvent.h b/dom/events/TouchEvent.h index 5b95abb2d281..bcf4a9a30a8a 100644 --- a/dom/events/TouchEvent.h +++ b/dom/events/TouchEvent.h @@ -107,7 +107,7 @@ public: void InitTouchEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, bool aCtrlKey, bool aAltKey, diff --git a/dom/events/UIEvent.cpp b/dom/events/UIEvent.cpp index fbd6d24f8f21..f80968cebde8 100644 --- a/dom/events/UIEvent.cpp +++ b/dom/events/UIEvent.cpp @@ -155,7 +155,7 @@ void UIEvent::InitUIEvent(const nsAString& typeArg, bool canBubbleArg, bool cancelableArg, - nsGlobalWindow* viewArg, + nsGlobalWindowInner* viewArg, int32_t detailArg) { auto* view = viewArg ? viewArg->AsInner() : nullptr; diff --git a/dom/events/UIEvent.h b/dom/events/UIEvent.h index a57b964b86ea..704eb534ad6b 100644 --- a/dom/events/UIEvent.h +++ b/dom/events/UIEvent.h @@ -54,7 +54,7 @@ public: void InitUIEvent(const nsAString& typeArg, bool canBubbleArg, bool cancelableArg, - nsGlobalWindow* viewArg, + nsGlobalWindowInner* viewArg, int32_t detailArg); nsPIDOMWindowOuter* GetView() const diff --git a/dom/events/WheelEvent.cpp b/dom/events/WheelEvent.cpp index fad1909dbe22..0c74b3e7054c 100644 --- a/dom/events/WheelEvent.cpp +++ b/dom/events/WheelEvent.cpp @@ -46,7 +46,7 @@ void WheelEvent::InitWheelEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, diff --git a/dom/events/WheelEvent.h b/dom/events/WheelEvent.h index fd54606fd824..da05485bb304 100644 --- a/dom/events/WheelEvent.h +++ b/dom/events/WheelEvent.h @@ -47,7 +47,7 @@ public: void InitWheelEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, int32_t aDetail, + nsGlobalWindowInner* aView, int32_t aDetail, int32_t aScreenX, int32_t aScreenY, int32_t aClientX, int32_t aClientY, uint16_t aButton, EventTarget* aRelatedTarget, const nsAString& aModifiersList, diff --git a/dom/events/XULCommandEvent.cpp b/dom/events/XULCommandEvent.cpp index b3011ff2b1a1..c86b3124d2f8 100644 --- a/dom/events/XULCommandEvent.cpp +++ b/dom/events/XULCommandEvent.cpp @@ -130,7 +130,7 @@ XULCommandEvent::InitCommandEvent(const nsAString& aType, { NS_ENSURE_TRUE(!mEvent->mFlags.mIsBeingDispatched, NS_OK); - auto* view = nsGlobalWindow::Cast(nsPIDOMWindowInner::From(aView)); + auto* view = nsGlobalWindowInner::Cast(nsPIDOMWindowInner::From(aView)); UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, view, aDetail); mEvent->AsInputEvent()->InitBasicModifiers(aCtrlKey, aAltKey, diff --git a/dom/events/XULCommandEvent.h b/dom/events/XULCommandEvent.h index 083f72c9182a..b8bf0fa31fa9 100644 --- a/dom/events/XULCommandEvent.h +++ b/dom/events/XULCommandEvent.h @@ -51,7 +51,7 @@ public: void InitCommandEvent(const nsAString& aType, bool aCanBubble, bool aCancelable, - nsGlobalWindow* aView, + nsGlobalWindowInner* aView, int32_t aDetail, bool aCtrlKey, bool aAltKey, bool aShiftKey, bool aMetaKey, diff --git a/dom/flyweb/FlyWebPublishedServer.cpp b/dom/flyweb/FlyWebPublishedServer.cpp index e45b0ae92332..bcd34559c520 100644 --- a/dom/flyweb/FlyWebPublishedServer.cpp +++ b/dom/flyweb/FlyWebPublishedServer.cpp @@ -140,7 +140,7 @@ FlyWebPublishedServer::OnWebSocketAccept(InternalRequest* aConnectRequest, nsCOMPtr window = do_QueryInterface(GetOwner()); AutoJSContext cx; - GlobalObject global(cx, nsGlobalWindow::Cast(window)->FastGetGlobalJSObject()); + GlobalObject global(cx, nsGlobalWindowInner::Cast(window)->FastGetGlobalJSObject()); nsAutoCString extensions, negotiatedExtensions; aConnectRequest->Headers()-> diff --git a/dom/flyweb/FlyWebService.cpp b/dom/flyweb/FlyWebService.cpp index cfe3b5c6756f..0033805add71 100644 --- a/dom/flyweb/FlyWebService.cpp +++ b/dom/flyweb/FlyWebService.cpp @@ -68,7 +68,8 @@ public: { MOZ_ASSERT(NS_IsMainThread()); - nsGlobalWindow* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + nsGlobalWindowInner* globalWindow = + nsGlobalWindowInner::GetInnerWindowWithId(mWindowID); if (!globalWindow) { return Cancel(); } diff --git a/dom/gamepad/GamepadManager.cpp b/dom/gamepad/GamepadManager.cpp index c2887185ad17..141aca258de4 100644 --- a/dom/gamepad/GamepadManager.cpp +++ b/dom/gamepad/GamepadManager.cpp @@ -46,8 +46,8 @@ const char* kGamepadEnabledPref = "dom.gamepad.enabled"; const char* kGamepadEventsEnabledPref = "dom.gamepad.non_standard_events.enabled"; -const nsTArray>::index_type NoIndex = - nsTArray>::NoIndex; +const nsTArray>::index_type NoIndex = + nsTArray>::NoIndex; bool sShutdown = false; @@ -132,7 +132,7 @@ GamepadManager::BeginShutdown() } void -GamepadManager::AddListener(nsGlobalWindow* aWindow) +GamepadManager::AddListener(nsGlobalWindowInner* aWindow) { MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsInnerWindow()); @@ -178,7 +178,7 @@ GamepadManager::AddListener(nsGlobalWindow* aWindow) } void -GamepadManager::RemoveListener(nsGlobalWindow* aWindow) +GamepadManager::RemoveListener(nsGlobalWindowInner* aWindow) { MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsInnerWindow()); @@ -349,7 +349,7 @@ GamepadManager::NewConnectionEvent(uint32_t aIndex, bool aConnected) // Hold on to listeners in a separate array because firing events // can mutate the mListeners array. - nsTArray> listeners(mListeners); + nsTArray> listeners(mListeners); if (aConnected) { for (uint32_t i = 0; i < listeners.Length(); i++) { @@ -468,7 +468,7 @@ GamepadManager::IsAPIEnabled() { } bool -GamepadManager::MaybeWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex) +GamepadManager::MaybeWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex) { if (!WindowHasSeenGamepad(aWindow, aIndex)) { // This window hasn't seen this gamepad before, so @@ -480,14 +480,14 @@ GamepadManager::MaybeWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aInd } bool -GamepadManager::WindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex) const +GamepadManager::WindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex) const { RefPtr gamepad = aWindow->GetGamepad(aIndex); return gamepad != nullptr; } void -GamepadManager::SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, +GamepadManager::SetWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex, bool aHasSeen) { @@ -546,7 +546,7 @@ GamepadManager::Update(const GamepadChangeEvent& aEvent) // Hold on to listeners in a separate array because firing events // can mutate the mListeners array. - nsTArray> listeners(mListeners); + nsTArray> listeners(mListeners); for (uint32_t i = 0; i < listeners.Length(); i++) { MOZ_ASSERT(listeners[i]->IsInnerWindow()); @@ -564,7 +564,7 @@ GamepadManager::Update(const GamepadChangeEvent& aEvent) void GamepadManager::MaybeConvertToNonstandardGamepadEvent(const GamepadChangeEvent& aEvent, - nsGlobalWindow* aWindow) + nsGlobalWindowInner* aWindow) { MOZ_ASSERT(aWindow); @@ -598,7 +598,7 @@ GamepadManager::MaybeConvertToNonstandardGamepadEvent(const GamepadChangeEvent& } bool -GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent, nsGlobalWindow *aWindow) +GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent, nsGlobalWindowInner *aWindow) { bool ret = false; bool firstTime = false; diff --git a/dom/gamepad/GamepadManager.h b/dom/gamepad/GamepadManager.h index d9dc7ce7881d..27827a5ad733 100644 --- a/dom/gamepad/GamepadManager.h +++ b/dom/gamepad/GamepadManager.h @@ -12,7 +12,7 @@ #include "mozilla/dom/GamepadBinding.h" #include "mozilla/dom/GamepadServiceType.h" -class nsGlobalWindow; +class nsGlobalWindowInner; namespace mozilla { namespace gfx { @@ -42,9 +42,9 @@ class GamepadManager final : public nsIObserver void StopMonitoring(); // Indicate that |aWindow| wants to receive gamepad events. - void AddListener(nsGlobalWindow* aWindow); + void AddListener(nsGlobalWindowInner* aWindow); // Indicate that |aWindow| should no longer receive gamepad events. - void RemoveListener(nsGlobalWindow* aWindow); + void RemoveListener(nsGlobalWindowInner* aWindow); // Add a gamepad to the list of known gamepads. void AddGamepad(uint32_t aIndex, const nsAString& aID, GamepadMappingType aMapping, @@ -116,18 +116,19 @@ class GamepadManager final : public nsIObserver nsresult Init(); void MaybeConvertToNonstandardGamepadEvent(const GamepadChangeEvent& aEvent, - nsGlobalWindow* aWindow); + nsGlobalWindowInner* aWindow); - bool SetGamepadByEvent(const GamepadChangeEvent& aEvent, nsGlobalWindow* aWindow = nullptr); + bool SetGamepadByEvent(const GamepadChangeEvent& aEvent, + nsGlobalWindowInner* aWindow = nullptr); - bool MaybeWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex); + bool MaybeWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex); // Returns true if we have already sent data from this gamepad // to this window. This should only return true if the user // explicitly interacted with a gamepad while this window // was focused, by pressing buttons or similar actions. - bool WindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex) const; + bool WindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex) const; // Indicate that a window has received data from a gamepad. - void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex, + void SetWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex, bool aHasSeen = true); // Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType // is from VRManager. @@ -138,7 +139,7 @@ class GamepadManager final : public nsIObserver nsRefPtrHashtable mGamepads; // Inner windows that are listening for gamepad events. // has been sent to that window. - nsTArray> mListeners; + nsTArray> mListeners; uint32_t mPromiseID; }; diff --git a/dom/geolocation/nsGeolocation.cpp b/dom/geolocation/nsGeolocation.cpp index 648f86fb27d8..c987b53ae71d 100644 --- a/dom/geolocation/nsGeolocation.cpp +++ b/dom/geolocation/nsGeolocation.cpp @@ -1195,7 +1195,7 @@ Geolocation::ShouldBlockInsecureRequests() const return false; } - if (!nsGlobalWindow::Cast(win)->IsSecureContextIfOpenerIgnored()) { + if (!nsGlobalWindowInner::Cast(win)->IsSecureContextIfOpenerIgnored()) { nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("DOM"), doc, nsContentUtils::eDOM_PROPERTIES, diff --git a/dom/html/HTMLBodyElement.cpp b/dom/html/HTMLBodyElement.cpp index d86d8028d0b2..c33101254d73 100644 --- a/dom/html/HTMLBodyElement.cpp +++ b/dom/html/HTMLBodyElement.cpp @@ -348,7 +348,7 @@ HTMLBodyElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, HTMLBodyElement::GetOn##name_() \ { \ if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) { \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ return globalWin->GetOn##name_(); \ } \ return nullptr; \ @@ -361,7 +361,7 @@ HTMLBodyElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, return; \ } \ \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ return globalWin->SetOn##name_(handler); \ } #define WINDOW_EVENT(name_, id_, type_, struct_) \ diff --git a/dom/html/HTMLFrameSetElement.cpp b/dom/html/HTMLFrameSetElement.cpp index f5ad32655abe..113ec47a18cd 100644 --- a/dom/html/HTMLFrameSetElement.cpp +++ b/dom/html/HTMLFrameSetElement.cpp @@ -319,7 +319,7 @@ HTMLFrameSetElement::IsEventAttributeNameInternal(nsAtom *aName) HTMLFrameSetElement::GetOn##name_() \ { \ if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) { \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ return globalWin->GetOn##name_(); \ } \ return nullptr; \ @@ -332,7 +332,7 @@ HTMLFrameSetElement::IsEventAttributeNameInternal(nsAtom *aName) return; \ } \ \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ return globalWin->SetOn##name_(handler); \ } #define WINDOW_EVENT(name_, id_, type_, struct_) \ diff --git a/dom/html/TextTrackManager.cpp b/dom/html/TextTrackManager.cpp index 4e09f7edbb84..1ce18c96d0ff 100644 --- a/dom/html/TextTrackManager.cpp +++ b/dom/html/TextTrackManager.cpp @@ -638,7 +638,7 @@ TextTrackManager::DispatchUpdateCueDisplay() WEBVTT_LOG("DispatchUpdateCueDisplay"); nsPIDOMWindowInner* win = mMediaElement->OwnerDoc()->GetInnerWindow(); if (win) { - nsGlobalWindow::Cast(win)->Dispatch( + nsGlobalWindowInner::Cast(win)->Dispatch( TaskCategory::Other, NewRunnableMethod("dom::TextTrackManager::UpdateCueDisplay", this, @@ -660,7 +660,7 @@ TextTrackManager::DispatchTimeMarchesOn() WEBVTT_LOG("DispatchTimeMarchesOn"); nsPIDOMWindowInner* win = mMediaElement->OwnerDoc()->GetInnerWindow(); if (win) { - nsGlobalWindow::Cast(win)->Dispatch( + nsGlobalWindowInner::Cast(win)->Dispatch( TaskCategory::Other, NewRunnableMethod("dom::TextTrackManager::TimeMarchesOn", this, diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index 187804af837d..ba1886796010 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -847,7 +847,7 @@ nsGenericHTMLElement::GetOn##name_() \ if (IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset)) { \ /* XXXbz note to self: add tests for this! */ \ if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) { \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ return globalWin->GetOn##name_(); \ } \ return nullptr; \ @@ -864,7 +864,7 @@ nsGenericHTMLElement::SetOn##name_(EventHandlerNonNull* handler) \ return; \ } \ \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ return globalWin->SetOn##name_(handler); \ } \ \ @@ -877,7 +877,7 @@ nsGenericHTMLElement::GetOn##name_() \ if (IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset)) { \ /* XXXbz note to self: add tests for this! */ \ if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) { \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ OnErrorEventHandlerNonNull* errorHandler = globalWin->GetOn##name_(); \ if (errorHandler) { \ RefPtr handler = \ @@ -900,7 +900,7 @@ nsGenericHTMLElement::SetOn##name_(EventHandlerNonNull* handler) \ return; \ } \ \ - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win); \ + nsGlobalWindowInner* globalWin = nsGlobalWindowInner::Cast(win); \ RefPtr errorHandler; \ if (handler) { \ errorHandler = new OnErrorEventHandlerNonNull(handler); \ diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index b9ee34d16bbf..4b05c23c1baa 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -1478,7 +1478,7 @@ nsHTMLDocument::Open(JSContext* /* unused */, rv.Throw(NS_ERROR_NOT_INITIALIZED); return nullptr; } - RefPtr win = nsGlobalWindow::Cast(outer); + RefPtr win = nsGlobalWindowOuter::Cast(outer); nsCOMPtr newWindow; // XXXbz We ignore aReplace for now. rv = win->OpenJS(aURL, aName, aFeatures, getter_AddRefs(newWindow)); diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index c4b47aeef87f..5f2855e9d56d 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -143,7 +143,7 @@ IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow, factory->mWindow = aWindow; factory->mTabChild = TabChild::GetFrom(aWindow); factory->mEventTarget = - nsGlobalWindow::Cast(aWindow)->EventTargetFor(TaskCategory::Other); + nsGlobalWindowInner::Cast(aWindow)->EventTargetFor(TaskCategory::Other); factory->mInnerWindowID = aWindow->WindowID(); factory->mPrivateBrowsingMode = loadContext && loadContext->UsePrivateBrowsing(); @@ -741,7 +741,7 @@ IDBFactory::OpenInternal(JSContext* aCx, if (mWindow) { JS::Rooted scriptOwner(aCx, - nsGlobalWindow::Cast(mWindow.get())->FastGetGlobalJSObject()); + nsGlobalWindowInner::Cast(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(aCx, this, mWindow, scriptOwner); diff --git a/dom/interfaces/base/nsIRemoteBrowser.idl b/dom/interfaces/base/nsIRemoteBrowser.idl index 25ab5d737716..0deddb4bc4a1 100644 --- a/dom/interfaces/base/nsIRemoteBrowser.idl +++ b/dom/interfaces/base/nsIRemoteBrowser.idl @@ -4,6 +4,8 @@ #include "nsISupports.idl" +interface nsIPrincipal; + [scriptable, uuid(C8379366-F79F-4D25-89A6-22BEC0A93D16)] interface nsIRemoteBrowser : nsISupports { @@ -22,4 +24,6 @@ interface nsIRemoteBrowser : nsISupports [array, size_is(enabledLength)] in string enabledCommands, in unsigned long disabledLength, [array, size_is(disabledLength)] in string disabledCommands); + + readonly attribute nsIPrincipal contentPrincipal; }; diff --git a/dom/interfaces/json/moz.build b/dom/interfaces/json/moz.build deleted file mode 100644 index a977d8cdc69c..000000000000 --- a/dom/interfaces/json/moz.build +++ /dev/null @@ -1,15 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -with Files("**"): - BUG_COMPONENT = ("Core", "JavaScript Engine") - -XPIDL_SOURCES += [ - 'nsIJSON.idl', -] - -XPIDL_MODULE = 'dom_json' - diff --git a/dom/interfaces/json/nsIJSON.idl b/dom/interfaces/json/nsIJSON.idl deleted file mode 100644 index d8a0e21a6e78..000000000000 --- a/dom/interfaces/json/nsIJSON.idl +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "domstubs.idl" - -interface nsIInputStream; -interface nsIScriptGlobalObject; - -[ptr] native JSValPtr(JS::Value); -[ptr] native JSContext(JSContext); - -%{C++ -#include "js/TypeDecls.h" -%} - -/** - * Don't use this! Use JSON.parse and JSON.stringify directly. - */ -[scriptable, uuid(083aebb0-7790-43b2-ae81-9e404e626236)] -interface nsIJSON : nsISupports -{ - [implicit_jscontext] - jsval decodeFromStream(in nsIInputStream stream, - in long contentLength); - - [noscript] AString encodeFromJSVal(in JSValPtr value, in JSContext cx); - - // Make sure you GCroot the result of this function before using it. - [noscript] jsval decodeToJSVal(in AString str, in JSContext cx); -}; diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 327d51136f93..1712d2d375c6 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -549,14 +549,14 @@ mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit, const StructuredCloneData& aInitialData, nsTArray&& aLookAndFeelIntCache, - nsTArray&& aFontFamilyList) + nsTArray&& aFontList) { if (!sShutdownCanary) { return IPC_OK(); } mLookAndFeelCache = Move(aLookAndFeelIntCache); - mFontFamilies = Move(aFontFamilyList); + mFontList = Move(aFontList); gfx::gfxVars::SetValuesForInitialize(aXPCOMInit.gfxNonDefaultVarUpdates()); InitXPCOM(aXPCOMInit, aInitialData); InitGraphicsDeviceData(aXPCOMInit.contentDeviceData()); @@ -2541,6 +2541,14 @@ ContentChild::RecvUpdateDictionaryList(InfallibleTArray&& aDictionarie return IPC_OK(); } +mozilla::ipc::IPCResult +ContentChild::RecvUpdateFontList(InfallibleTArray&& aFontList) +{ + mFontList = Move(aFontList); + gfxPlatform::GetPlatform()->UpdateFontList(); + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentChild::RecvUpdateAppLocales(nsTArray&& aAppLocales) { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 9dd16234a8dd..9453e497b1df 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -399,6 +399,8 @@ public: virtual mozilla::ipc::IPCResult RecvUpdateDictionaryList(InfallibleTArray&& aDictionaries) override; + virtual mozilla::ipc::IPCResult RecvUpdateFontList(InfallibleTArray&& aFontList) override; + virtual mozilla::ipc::IPCResult RecvUpdateAppLocales(nsTArray&& aAppLocales) override; virtual mozilla::ipc::IPCResult RecvUpdateRequestedLocales(nsTArray&& aRequestedLocales) override; @@ -603,7 +605,7 @@ public: RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit, const StructuredCloneData& aInitialData, nsTArray&& aLookAndFeelIntCache, - nsTArray&& aFontFamilyList) override; + nsTArray&& aFontList) override; virtual mozilla::ipc::IPCResult RecvProvideAnonymousTemporaryFile(const uint64_t& aID, const FileDescOrError& aFD) override; @@ -641,11 +643,11 @@ public: SendGetA11yContentId(); #endif // defined(XP_WIN) && defined(ACCESSIBILITY) - // Get a reference to the font family list passed from the chrome process, + // Get a reference to the font list passed from the chrome process, // for use during gfx initialization. - InfallibleTArray& - SystemFontFamilyList() { - return mFontFamilies; + InfallibleTArray& + SystemFontList() { + return mFontList; } // PURLClassifierChild @@ -749,10 +751,10 @@ private: InfallibleTArray mAvailableDictionaries; - // Temporary storage for a list of available font families, passed from the + // Temporary storage for a list of available fonts, passed from the // parent process and used to initialize gfx in the child. Currently used - // only on MacOSX. - InfallibleTArray mFontFamilies; + // only on MacOSX and Linux. + InfallibleTArray mFontList; // Temporary storage for nsXPLookAndFeel flags. nsTArray mLookAndFeelCache; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 33c0481895a5..fecdb086bc7d 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -171,6 +171,7 @@ #include "nsDocShell.h" #include "nsOpenURIInFrameParams.h" #include "mozilla/net/NeckoMessageUtils.h" +#include "gfxPlatform.h" #include "gfxPrefs.h" #include "prio.h" #include "private/pprio.h" @@ -2224,9 +2225,10 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority, } } } - // This is only implemented (returns a non-empty list) by MacOSX at present. - nsTArray fontFamilies; - gfxPlatform::GetPlatform()->GetSystemFontFamilyList(&fontFamilies); + // This is only implemented (returns a non-empty list) by MacOSX and Linux + // at present. + nsTArray fontList; + gfxPlatform::GetPlatform()->ReadSystemFontList(&fontList); nsTArray lnfCache = LookAndFeel::GetIntCache(); // Content processes have no permission to access profile directory, so we @@ -2269,7 +2271,7 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority, screenManager.CopyScreensToRemote(this); Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache, - fontFamilies); + fontList); if (aSendRegisteredChrome) { nsCOMPtr registrySvc = nsChromeRegistry::GetService(); @@ -4263,6 +4265,17 @@ ContentParent::NotifyUpdatedDictionaries() } } +void +ContentParent::NotifyUpdatedFonts() +{ + InfallibleTArray fontList; + gfxPlatform::GetPlatform()->ReadSystemFontList(&fontList); + + for (auto* cp : AllProcesses(eLive)) { + Unused << cp->SendUpdateFontList(fontList); + } +} + /*static*/ void ContentParent::UnregisterRemoteFrame(const TabId& aTabId, const ContentParentId& aCpId, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 256b11e4e3ba..e45e32e618a0 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -269,6 +269,8 @@ public: static void NotifyUpdatedDictionaries(); + static void NotifyUpdatedFonts(); + #if defined(XP_WIN) /** * Windows helper for firing off an update window request to a plugin diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index c5c3e057a6e8..1760826ca7d9 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -132,6 +132,19 @@ struct FontFamilyListEntry { uint8_t entryType; }; +// Used on Linux to pass list of font patterns from chrome to content. +struct FontPatternListEntry { + nsCString pattern; + bool appFontFamily; +}; + +// Wrap the Font*ListEntry records in a union so the SetXPCOMProcessAttributes +// message can pass an array of either type. +union SystemFontListEntry { + FontFamilyListEntry; + FontPatternListEntry; +}; + union PrefValue { nsCString; int32_t; @@ -429,6 +442,8 @@ child: async UpdateDictionaryList(nsString[] dictionaries); + async UpdateFontList(SystemFontListEntry[] fontList); + async UpdateAppLocales(nsCString[] appLocales); async UpdateRequestedLocales(nsCString[] requestedLocales); @@ -476,8 +491,8 @@ child: async SetXPCOMProcessAttributes(XPCOMInitData xpcomInit, StructuredCloneData initialData, LookAndFeelInt[] lookAndFeelIntCache, - /* used on MacOSX only: */ - FontFamilyListEntry[] fontFamilyList); + /* used on MacOSX and Linux only: */ + SystemFontListEntry[] systemFontList); // Notify child that last-pb-context-exited notification was observed async LastPrivateDocShellDestroyed(); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 2cd11e8c97c5..3cf4c4831b6d 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2555,8 +2555,8 @@ mozilla::ipc::IPCResult TabChild::RecvPrint(const uint64_t& aOuterWindowID, const PrintData& aPrintData) { #ifdef NS_PRINTING - nsGlobalWindow* outerWindow = - nsGlobalWindow::GetOuterWindowWithId(aOuterWindowID); + nsGlobalWindowOuter* outerWindow = + nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowID); if (NS_WARN_IF(!outerWindow)) { return IPC_OK(); } diff --git a/dom/json/moz.build b/dom/json/moz.build deleted file mode 100644 index 7e7e85f16f5c..000000000000 --- a/dom/json/moz.build +++ /dev/null @@ -1,25 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -with Files("**"): - BUG_COMPONENT = ("Core", "JavaScript Engine") - -EXPORTS += [ - 'nsJSON.h', -] - -UNIFIED_SOURCES += [ - 'nsJSON.cpp', -] - -LOCAL_INCLUDES += [ - '/dom/base', -] - -FINAL_LIBRARY = 'xul' - -XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] -MOCHITEST_MANIFESTS += ['test/mochitest.ini'] diff --git a/dom/json/nsJSON.cpp b/dom/json/nsJSON.cpp deleted file mode 100644 index 772809a436b7..000000000000 --- a/dom/json/nsJSON.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsJSON.h" - -#include "jsapi.h" -#include "js/CharacterEncoding.h" -#include "nsIXPConnect.h" -#include "nsIXPCScriptable.h" -#include "nsStreamUtils.h" -#include "nsIInputStream.h" -#include "nsStringStream.h" -#include "nsNetUtil.h" -#include "nsIURI.h" -#include "nsComponentManagerUtils.h" -#include "nsContentUtils.h" -#include "nsIScriptError.h" -#include "nsCRTGlue.h" -#include "nsIScriptSecurityManager.h" -#include "NullPrincipal.h" -#include "mozilla/Maybe.h" -#include - -using namespace mozilla; - -#define JSON_STREAM_BUFSIZE 4096 - -NS_INTERFACE_MAP_BEGIN(nsJSON) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJSON) - NS_INTERFACE_MAP_ENTRY(nsIJSON) -NS_INTERFACE_MAP_END - -NS_IMPL_ADDREF(nsJSON) -NS_IMPL_RELEASE(nsJSON) - -nsJSON::nsJSON() -{ -} - -nsJSON::~nsJSON() -{ -} - -static bool -WriteCallback(const char16_t *buf, uint32_t len, void *data) -{ - nsJSONWriter *writer = static_cast(data); - nsresult rv = writer->Write((const char16_t*)buf, (uint32_t)len); - if (NS_FAILED(rv)) - return false; - - return true; -} - -NS_IMETHODIMP -nsJSON::EncodeFromJSVal(JS::Value *value, JSContext *cx, nsAString &result) -{ - result.Truncate(); - - mozilla::Maybe ac; - if (value->isObject()) { - JS::Rooted obj(cx, &value->toObject()); - ac.emplace(cx, obj); - } - - nsJSONWriter writer; - JS::Rooted vp(cx, *value); - if (!JS_Stringify(cx, &vp, nullptr, JS::NullHandleValue, WriteCallback, &writer)) { - return NS_ERROR_XPC_BAD_CONVERT_JS; - } - *value = vp; - - NS_ENSURE_TRUE(writer.DidWrite(), NS_ERROR_UNEXPECTED); - writer.FlushBuffer(); - result.Assign(writer.mOutputString); - return NS_OK; -} - - -nsJSONWriter::nsJSONWriter() : mStream(nullptr), - mBuffer(nullptr), - mBufferCount(0), - mDidWrite(false), - mEncoder(nullptr) -{ -} - -nsJSONWriter::nsJSONWriter(nsIOutputStream* aStream) - : mStream(aStream) - , mBuffer(nullptr) - , mBufferCount(0) - , mDidWrite(false) - , mEncoder(UTF_8_ENCODING->NewEncoder()) -{ -} - -nsJSONWriter::~nsJSONWriter() -{ - delete [] mBuffer; -} - -nsresult -nsJSONWriter::Write(const char16_t *aBuffer, uint32_t aLength) -{ - if (mStream) { - return WriteToStream(mStream, mEncoder.get(), aBuffer, aLength); - } - - if (!mDidWrite) { - mBuffer = new char16_t[JSON_STREAM_BUFSIZE]; - mDidWrite = true; - } - - if (JSON_STREAM_BUFSIZE <= aLength + mBufferCount) { - mOutputString.Append(mBuffer, mBufferCount); - mBufferCount = 0; - } - - if (JSON_STREAM_BUFSIZE <= aLength) { - // we know mBufferCount is 0 because we know we hit the if above - mOutputString.Append(aBuffer, aLength); - } else { - memcpy(&mBuffer[mBufferCount], aBuffer, aLength * sizeof(char16_t)); - mBufferCount += aLength; - } - - return NS_OK; -} - -bool nsJSONWriter::DidWrite() -{ - return mDidWrite; -} - -void -nsJSONWriter::FlushBuffer() -{ - mOutputString.Append(mBuffer, mBufferCount); -} - -nsresult -nsJSONWriter::WriteToStream(nsIOutputStream* aStream, - Encoder* encoder, - const char16_t* aBuffer, - uint32_t aLength) -{ - uint8_t buffer[1024]; - auto dst = MakeSpan(buffer); - auto src = MakeSpan(aBuffer, aLength); - - for (;;) { - uint32_t result; - size_t read; - size_t written; - bool hadErrors; - Tie(result, read, written, hadErrors) = - encoder->EncodeFromUTF16(src, dst, false); - Unused << hadErrors; - src = src.From(read); - uint32_t ignored; - nsresult rv = - aStream->Write(reinterpret_cast(buffer), written, &ignored); - if (NS_FAILED(rv)) { - return rv; - } - if (result == kInputEmpty) { - mDidWrite = true; - return NS_OK; - } - } -} - -NS_IMETHODIMP -nsJSON::DecodeFromStream(nsIInputStream *aStream, int32_t aContentLength, - JSContext* cx, JS::MutableHandle aRetval) -{ - return DecodeInternal(cx, aStream, aContentLength, true, aRetval); -} - -NS_IMETHODIMP -nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx, - JS::MutableHandle result) -{ - if (!JS_ParseJSON(cx, static_cast(PromiseFlatString(str).get()), - str.Length(), result)) { - return NS_ERROR_UNEXPECTED; - } - return NS_OK; -} - -nsresult -nsJSON::DecodeInternal(JSContext* cx, - nsIInputStream *aStream, - int32_t aContentLength, - bool aNeedsConverter, - JS::MutableHandle aRetval) -{ - // Consume the stream - nsCOMPtr jsonChannel; - if (!mURI) { - NS_NewURI(getter_AddRefs(mURI), NS_LITERAL_CSTRING("about:blank"), 0, 0 ); - if (!mURI) - return NS_ERROR_OUT_OF_MEMORY; - } - - nsresult rv; - nsCOMPtr nullPrincipal = NullPrincipal::Create(); - - // The ::Decode function is deprecated [Bug 675797] and the following - // channel is never openend, so it does not matter what securityFlags - // we pass to NS_NewInputStreamChannel here. - rv = NS_NewInputStreamChannel(getter_AddRefs(jsonChannel), - mURI, - aStream, - nullPrincipal, - nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("application/json")); - - if (!jsonChannel || NS_FAILED(rv)) - return NS_ERROR_FAILURE; - - RefPtr jsonListener = - new nsJSONListener(cx, aRetval.address(), aNeedsConverter); - - //XXX this stream pattern should be consolidated in netwerk - rv = jsonListener->OnStartRequest(jsonChannel, nullptr); - if (NS_FAILED(rv)) { - jsonChannel->Cancel(rv); - return rv; - } - - nsresult status; - jsonChannel->GetStatus(&status); - uint64_t offset = 0; - while (NS_SUCCEEDED(status)) { - uint64_t available; - rv = aStream->Available(&available); - if (rv == NS_BASE_STREAM_CLOSED) { - rv = NS_OK; - break; - } - if (NS_FAILED(rv)) { - jsonChannel->Cancel(rv); - break; - } - if (!available) - break; // blocking input stream has none available when done - - if (available > UINT32_MAX) - available = UINT32_MAX; - - rv = jsonListener->OnDataAvailable(jsonChannel, nullptr, - aStream, - offset, - (uint32_t)available); - if (NS_FAILED(rv)) { - jsonChannel->Cancel(rv); - break; - } - - offset += available; - jsonChannel->GetStatus(&status); - } - NS_ENSURE_SUCCESS(rv, rv); - - rv = jsonListener->OnStopRequest(jsonChannel, nullptr, status); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -nsresult -NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - nsJSON* json = new nsJSON(); - NS_ADDREF(json); - *aResult = json; - - return NS_OK; -} - -nsJSONListener::nsJSONListener(JSContext *cx, JS::Value *rootVal, - bool needsConverter) - : mNeedsConverter(needsConverter), - mCx(cx), - mRootVal(rootVal) -{ -} - -nsJSONListener::~nsJSONListener() -{ -} - -NS_INTERFACE_MAP_BEGIN(nsJSONListener) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsJSONListener) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) -NS_INTERFACE_MAP_END - -NS_IMPL_ADDREF(nsJSONListener) -NS_IMPL_RELEASE(nsJSONListener) - -NS_IMETHODIMP -nsJSONListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) -{ - mDecoder = nullptr; - - return NS_OK; -} - -NS_IMETHODIMP -nsJSONListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext, - nsresult aStatusCode) -{ - JS::Rooted reviver(mCx, JS::NullValue()), value(mCx); - - JS::ConstTwoByteChars chars(reinterpret_cast(mBufferedChars.Elements()), - mBufferedChars.Length()); - bool ok = JS_ParseJSONWithReviver(mCx, chars.begin().get(), - uint32_t(mBufferedChars.Length()), - reviver, &value); - - *mRootVal = value; - mBufferedChars.TruncateLength(0); - return ok ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsJSONListener::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext, - nsIInputStream *aStream, - uint64_t aOffset, uint32_t aLength) -{ - nsresult rv = NS_OK; - - char buffer[JSON_STREAM_BUFSIZE]; - unsigned long bytesRemaining = aLength; - while (bytesRemaining) { - unsigned int bytesRead; - rv = aStream->Read(buffer, - std::min((unsigned long)sizeof(buffer), bytesRemaining), - &bytesRead); - NS_ENSURE_SUCCESS(rv, rv); - rv = ProcessBytes(buffer, bytesRead); - NS_ENSURE_SUCCESS(rv, rv); - bytesRemaining -= bytesRead; - } - - return rv; -} - -nsresult -nsJSONListener::ProcessBytes(const char* aBuffer, uint32_t aByteLength) -{ - if (mNeedsConverter && !mDecoder) { - // BOM sniffing is built into the decoder. - mDecoder = UTF_8_ENCODING->NewDecoder(); - } - - if (!aBuffer) - return NS_OK; - - nsresult rv; - if (mNeedsConverter) { - rv = ConsumeConverted(aBuffer, aByteLength); - } else { - uint32_t unichars = aByteLength / sizeof(char16_t); - rv = Consume((char16_t *) aBuffer, unichars); - } - - return rv; -} - -nsresult -nsJSONListener::ConsumeConverted(const char* aBuffer, uint32_t aByteLength) -{ - CheckedInt needed = mDecoder->MaxUTF16BufferLength(aByteLength); - if (!needed.isValid()) { - return NS_ERROR_OUT_OF_MEMORY; - } - - CheckedInt total(needed); - total += mBufferedChars.Length(); - if (!total.isValid()) { - return NS_ERROR_OUT_OF_MEMORY; - } - - char16_t* endelems = mBufferedChars.AppendElements(needed.value(), fallible); - if (!endelems) { - return NS_ERROR_OUT_OF_MEMORY; - } - - auto src = AsBytes(MakeSpan(aBuffer, aByteLength)); - auto dst = MakeSpan(endelems, needed.value()); - uint32_t result; - size_t read; - size_t written; - bool hadErrors; - // Ignoring EOF like the old code - Tie(result, read, written, hadErrors) = - mDecoder->DecodeToUTF16(src, dst, false); - MOZ_ASSERT(result == kInputEmpty); - MOZ_ASSERT(read == src.Length()); - MOZ_ASSERT(written <= needed.value()); - Unused << hadErrors; - mBufferedChars.TruncateLength(total.value() - (needed.value() - written)); - return NS_OK; -} - -nsresult -nsJSONListener::Consume(const char16_t* aBuffer, uint32_t aByteLength) -{ - if (!mBufferedChars.AppendElements(aBuffer, aByteLength)) - return NS_ERROR_FAILURE; - - return NS_OK; -} diff --git a/dom/json/nsJSON.h b/dom/json/nsJSON.h deleted file mode 100644 index c407d2347aaf..000000000000 --- a/dom/json/nsJSON.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsJSON_h__ -#define nsJSON_h__ - -#include "nsIJSON.h" -#include "nsString.h" -#include "nsCOMPtr.h" -#include "nsIOutputStream.h" -#include "mozilla/Encoding.h" -#include "nsIRequestObserver.h" -#include "nsIStreamListener.h" -#include "nsTArray.h" - -class nsIURI; - -class MOZ_STACK_CLASS nsJSONWriter -{ -public: - nsJSONWriter(); - explicit nsJSONWriter(nsIOutputStream* aStream); - virtual ~nsJSONWriter(); - nsCOMPtr mStream; - nsresult Write(const char16_t *aBuffer, uint32_t aLength); - nsString mOutputString; - bool DidWrite(); - void FlushBuffer(); - -protected: - char16_t *mBuffer; - uint32_t mBufferCount; - bool mDidWrite; - nsresult WriteToStream(nsIOutputStream* aStream, - mozilla::Encoder* encoder, - const char16_t* aBuffer, - uint32_t aLength); - - mozilla::UniquePtr mEncoder; -}; - -class nsJSON final : public nsIJSON -{ -public: - nsJSON(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIJSON - -protected: - virtual ~nsJSON(); - - nsresult DecodeInternal(JSContext* cx, - nsIInputStream* aStream, - int32_t aContentLength, - bool aNeedsConverter, - JS::MutableHandle aRetVal); - nsCOMPtr mURI; -}; - -nsresult -NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult); - -class nsJSONListener : public nsIStreamListener -{ -public: - nsJSONListener(JSContext *cx, JS::Value *rootVal, bool needsConverter); - - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - -protected: - virtual ~nsJSONListener(); - - bool mNeedsConverter; - JSContext *mCx; - JS::Value *mRootVal; - mozilla::UniquePtr mDecoder; - nsTArray mBufferedChars; - nsresult ProcessBytes(const char* aBuffer, uint32_t aByteLength); - nsresult ConsumeConverted(const char* aBuffer, uint32_t aByteLength); - nsresult Consume(const char16_t *data, uint32_t len); -}; - -#endif diff --git a/dom/json/test/mochitest.ini b/dom/json/test/mochitest.ini deleted file mode 100644 index f09974d3ffa7..000000000000 --- a/dom/json/test/mochitest.ini +++ /dev/null @@ -1 +0,0 @@ -[test_json.html] diff --git a/dom/json/test/test_json.html b/dom/json/test/test_json.html deleted file mode 100644 index 23e41e179c60..000000000000 --- a/dom/json/test/test_json.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - Test for Bug 408838 - - - - -Mozilla Bug 408838 -

- -
-
-
- - - diff --git a/dom/json/test/unit/decodeFromStream-01.json b/dom/json/test/unit/decodeFromStream-01.json deleted file mode 100644 index 258658753a05..000000000000 --- a/dom/json/test/unit/decodeFromStream-01.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "JSON Test Pattern pass3": { - "The outermost value": "must be an object or array.", - "In this test": "It is an object." - } -} - diff --git a/dom/json/test/unit/decodeFromStream-small.json b/dom/json/test/unit/decodeFromStream-small.json deleted file mode 100644 index 9e26dfeeb6e6..000000000000 --- a/dom/json/test/unit/decodeFromStream-small.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/dom/json/test/unit/test_decodeFromStream.js b/dom/json/test/unit/test_decodeFromStream.js deleted file mode 100644 index eb30d26196ab..000000000000 --- a/dom/json/test/unit/test_decodeFromStream.js +++ /dev/null @@ -1,29 +0,0 @@ -var Ci = Components.interfaces; -var Cc = Components.classes; - -var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); - -function run_test() -{ - function read_file(path) - { - try - { - var f = do_get_file(path); - var istream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); - istream.init(f, -1, -1, false); - return nativeJSON.decodeFromStream(istream, istream.available()); - } - finally - { - istream.close(); - } - } - - var x = read_file("decodeFromStream-01.json"); - do_check_eq(x["JSON Test Pattern pass3"]["The outermost value"], "must be an object or array."); - do_check_eq(x["JSON Test Pattern pass3"]["In this test"], "It is an object."); - - x = read_file("decodeFromStream-small.json"); - do_check_eq(x.toSource(), "({})", "empty object parsed"); -} diff --git a/dom/json/test/unit/xpcshell.ini b/dom/json/test/unit/xpcshell.ini deleted file mode 100644 index 25847ccef25e..000000000000 --- a/dom/json/test/unit/xpcshell.ini +++ /dev/null @@ -1,8 +0,0 @@ -[DEFAULT] -head = -support-files = - decodeFromStream-01.json - decodeFromStream-small.json - -[test_decodeFromStream.js] - diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index 16b8140ede52..6626cb46ea9e 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -417,7 +417,7 @@ public: if (!windowListener) { nsCOMPtr obs = services::GetObserverService(); - auto* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID); if (globalWindow) { RefPtr req = new GetUserMediaRequest(globalWindow->AsInner(), @@ -472,7 +472,7 @@ public: if (revokeVideoPermission) { nsCOMPtr obs = services::GetObserverService(); - auto* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID); nsPIDOMWindowInner* window = globalWindow ? globalWindow->AsInner() : nullptr; RefPtr req = @@ -500,7 +500,7 @@ public: if (revokeAudioPermission) { nsCOMPtr obs = services::GetObserverService(); - auto* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID); nsPIDOMWindowInner* window = globalWindow ? globalWindow->AsInner() : nullptr; RefPtr req = @@ -668,7 +668,7 @@ public: } // This is safe since we're on main-thread, and the windowlist can only // be invalidated from the main-thread (see OnNavigation) - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID)) { + if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID)) { RefPtr error = new MediaStreamError(window->AsInner(), *mError); onFailure->OnError(error); @@ -1041,7 +1041,7 @@ public: Run() override { MOZ_ASSERT(NS_IsMainThread()); - nsGlobalWindow* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + nsGlobalWindowInner* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID); nsPIDOMWindowInner* window = globalWindow ? globalWindow->AsInner() : nullptr; // We're on main-thread, and the windowlist can only @@ -1191,7 +1191,7 @@ public: nsCOMPtr onFailure = mOnFailure.forget(); LOG(("Returning error for getUserMedia() - no stream")); - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID)) { + if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID)) { RefPtr error = new MediaStreamError(window->AsInner(), NS_LITERAL_STRING("InternalError"), sInShutdown ? NS_LITERAL_STRING("In shutdown") : @@ -1589,7 +1589,7 @@ public: nsCOMPtr onSuccess = mOnSuccess.forget(); nsCOMPtr onFailure = mOnFailure.forget(); - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(mWindowID)) { + if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID)) { RefPtr error = new MediaStreamError(window->AsInner(), aName, aMessage); onFailure->OnError(error); @@ -2095,13 +2095,12 @@ void MediaManager::OnDeviceChange() { for (auto& id : self->mDeviceIDs) { if (!deviceIDs.Contains(id)) { // Stop the coresponding SourceListener - nsGlobalWindow::WindowByIdTable* windowsById = nsGlobalWindow::GetWindowsTable(); + nsGlobalWindowInner::InnerWindowByIdTable* windowsById = + nsGlobalWindowInner::GetWindowsTable(); if (windowsById) { for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { - nsGlobalWindow* window = iter.Data(); - if (window->IsInnerWindow()) { - self->IterateWindowListeners(window->AsInner(), StopRawIDCallback, &id); - } + nsGlobalWindowInner* window = iter.Data(); + self->IterateWindowListeners(window->AsInner(), StopRawIDCallback, &id); } } } @@ -2152,7 +2151,7 @@ static bool IsFullyActive(nsPIDOMWindowInner* aWindow) return true; } nsCOMPtr frameElement = - nsGlobalWindow::Cast(context)->GetRealFrameElementOuter(); + nsGlobalWindowOuter::Cast(context)->GetRealFrameElementOuter(); if (!frameElement) { return false; } @@ -2268,7 +2267,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow, } nsCOMPtr principal = - nsGlobalWindow::Cast(aWindow)->GetPrincipal(); + nsGlobalWindowInner::Cast(aWindow)->GetPrincipal(); if (NS_WARN_IF(!principal)) { return NS_ERROR_FAILURE; } @@ -2515,7 +2514,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow, auto devices = MakeRefPtr>>(aDevices); // Ensure that our windowID is still good. - if (!nsGlobalWindow::GetInnerWindowWithId(windowID)) { + if (!nsGlobalWindowInner::GetInnerWindowWithId(windowID)) { return; } @@ -2528,7 +2527,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow, ](const char*& badConstraint) mutable { // Ensure that the captured 'this' pointer and our windowID are still good. - auto* globalWindow = nsGlobalWindow::GetInnerWindowWithId(windowID); + auto* globalWindow = nsGlobalWindowInner::GetInnerWindowWithId(windowID); RefPtr window = globalWindow ? globalWindow->AsInner() : nullptr; if (!MediaManager::Exists() || !window) { @@ -2706,7 +2705,7 @@ MediaManager::EnumerateDevicesImpl(uint64_t aWindowId, { MOZ_ASSERT(NS_IsMainThread()); nsPIDOMWindowInner* window = - nsGlobalWindow::GetInnerWindowWithId(aWindowId)->AsInner(); + nsGlobalWindowInner::GetInnerWindowWithId(aWindowId)->AsInner(); // This function returns a pledge, a promise-like object with the future result RefPtr pledge = new PledgeSourceSet(); @@ -2718,7 +2717,7 @@ MediaManager::EnumerateDevicesImpl(uint64_t aWindowId, // 3. Anonymize the raw list with the origin-key. nsCOMPtr principal = - nsGlobalWindow::Cast(window)->GetPrincipal(); + nsGlobalWindowInner::Cast(window)->GetPrincipal(); MOZ_ASSERT(principal); ipc::PrincipalInfo principalInfo; @@ -2936,7 +2935,7 @@ MediaManager::OnNavigation(uint64_t aWindowID) // This is safe since we're on main-thread, and the windowlist can only // be added to from the main-thread - auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowID); + auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowID); if (window) { IterateWindowListeners(window->AsInner(), StopSharingCallback, nullptr); } else { @@ -2989,7 +2988,7 @@ MediaManager::RemoveWindowID(uint64_t aWindowId) mActiveWindows.Remove(aWindowId); // get outer windowID - auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowId); + auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId); if (!window) { LOG(("No inner window for %" PRIu64, aWindowId)); return; @@ -3345,7 +3344,7 @@ MediaManager::GetActiveMediaCaptureWindows(nsIArray** aArray) } nsPIDOMWindowInner* window = - nsGlobalWindow::GetInnerWindowWithId(id)->AsInner(); + nsGlobalWindowInner::GetInnerWindowWithId(id)->AsInner(); MOZ_ASSERT(window); // XXXkhuey ... if (!window) { @@ -3469,7 +3468,7 @@ MediaManager::StopScreensharing(uint64_t aWindowID) // We need to stop window/screensharing for all streams in all innerwindows that // correspond to that outerwindow. - auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowID); + auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowID); if (!window) { return; } @@ -3549,7 +3548,7 @@ MediaManager::IsActivelyCapturingOrHasAPermission(uint64_t aWindowId) // Or are persistent permissions (audio or video) granted? - auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowId); + auto* window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowId); if (NS_WARN_IF(!window)) { return false; } @@ -3785,7 +3784,7 @@ SourceListener::StopSharing() if (mAudioDevice && mAudioDevice->GetMediaSource() == MediaSourceEnum::AudioCapture) { uint64_t windowID = mWindowListener->WindowID(); - nsCOMPtr window = nsGlobalWindow::GetInnerWindowWithId(windowID)->AsInner(); + nsCOMPtr window = nsGlobalWindowInner::GetInnerWindowWithId(windowID)->AsInner(); MOZ_RELEASE_ASSERT(window); window->SetAudioCapture(false); MediaStreamGraph* graph = @@ -4049,7 +4048,7 @@ SourceListener::ApplyConstraintsToTrack( if (NS_SUCCEEDED(rv)) { p->Resolve(false); } else { - auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId); + auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowId); if (window) { if (badConstraint) { nsString constraint; @@ -4194,7 +4193,7 @@ GetUserMediaNotificationEvent::Run() break; } - RefPtr window = nsGlobalWindow::GetInnerWindowWithId(mWindowID); + RefPtr window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID); NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); return MediaManager::NotifyRecordingStatusChange(window->AsInner(), msg); diff --git a/dom/media/TextTrack.cpp b/dom/media/TextTrack.cpp index 69b1406697a8..6858a952f6d5 100644 --- a/dom/media/TextTrack.cpp +++ b/dom/media/TextTrack.cpp @@ -336,7 +336,7 @@ TextTrack::DispatchAsyncTrustedEvent(const nsString& aEventName) return; } RefPtr self = this; - nsGlobalWindow::Cast(win)->Dispatch( + nsGlobalWindowInner::Cast(win)->Dispatch( TaskCategory::Other, NS_NewRunnableFunction( "dom::TextTrack::DispatchAsyncTrustedEvent", diff --git a/dom/media/TextTrackList.cpp b/dom/media/TextTrackList.cpp index 94569702388c..f3b89ef64fc7 100644 --- a/dom/media/TextTrackList.cpp +++ b/dom/media/TextTrackList.cpp @@ -193,7 +193,7 @@ TextTrackList::CreateAndDispatchChangeEvent() event->SetTrusted(true); nsCOMPtr eventRunner = new ChangeEventRunner(this, event); - nsGlobalWindow::Cast(win)->Dispatch(TaskCategory::Other, eventRunner.forget()); + nsGlobalWindowInner::Cast(win)->Dispatch(TaskCategory::Other, eventRunner.forget()); } } diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index f73b7a26353b..062496334424 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -952,58 +952,58 @@ skip-if = toolkit == 'android' # bug 1300330, android(bug 1232305) [test_play_events_2.html] skip-if = toolkit == 'android' # bug 1302614, bug 1328749, android(bug 1232305) [test_play_promise_1.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_2.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_3.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_4.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_5.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_6.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_7.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_8.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_9.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_10.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_11.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_12.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_13.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_14.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_15.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_16.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_17.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_promise_18.html] -skip-if = android_version == '17' # bug 1392196 +skip-if = android_version == '17' || android_version == '23' # bug 1392196, bug 1415061 tags=promise-play [test_play_twice.html] skip-if = appname == "seamonkey" || toolkit == 'android' # Seamonkey: Bug 598252, bug 1307337, bug 1143695, android(bug 1232305) @@ -1041,6 +1041,7 @@ skip-if = toolkit == 'android' # android(bug 1232305) [test_video_dimensions.html] skip-if = toolkit == 'android' # bug 1298238, bug 1304535, android(bug 1232305) [test_resolution_change.html] +skip-if = android_version == '19' # bug 1393866 tags=capturestream [test_resume.html] skip-if = true # bug 1021673 diff --git a/dom/media/webrtc/MediaEngineTabVideoSource.cpp b/dom/media/webrtc/MediaEngineTabVideoSource.cpp index 6f9dd5f5ea9d..a574874e0eb2 100644 --- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp @@ -89,8 +89,8 @@ nsresult MediaEngineTabVideoSource::InitRunnable::Run() { if (mVideoSource->mWindowId != -1) { - nsGlobalWindow* globalWindow = - nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId); + nsGlobalWindowOuter* globalWindow = + nsGlobalWindowOuter::GetOuterWindowWithId(mVideoSource->mWindowId); if (!globalWindow) { // We can't access the window, just send a blacked out screen. mVideoSource->mWindow = nullptr; diff --git a/dom/moz.build b/dom/moz.build index de58a20bb05c..19b33f2f4e1e 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -29,7 +29,6 @@ interfaces = [ 'xul', 'security', 'storage', - 'json', 'offline', 'geolocation', 'notification', @@ -65,7 +64,6 @@ DIRS += [ 'geolocation', 'grid', 'html', - 'json', 'jsurl', 'asmjscache', 'mathml', diff --git a/dom/performance/PerformanceTiming.cpp b/dom/performance/PerformanceTiming.cpp index ccb4f0941e5a..08a0ae314fbf 100644 --- a/dom/performance/PerformanceTiming.cpp +++ b/dom/performance/PerformanceTiming.cpp @@ -144,8 +144,8 @@ PerformanceTiming::FetchStartHighRes() MOZ_ASSERT(!mAsyncOpen.IsNull(), "The fetch start time stamp should always be " "valid if the performance timing is enabled"); if (!mAsyncOpen.IsNull()) { - if (!mWorkerStart.IsNull() && mWorkerStart > mAsyncOpen) { - mFetchStart = TimeStampToDOMHighRes(mWorkerStart); + if (!mWorkerRequestStart.IsNull() && mWorkerRequestStart > mAsyncOpen) { + mFetchStart = TimeStampToDOMHighRes(mWorkerRequestStart); } else { mFetchStart = TimeStampToDOMHighRes(mAsyncOpen); } diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp index 254d858b0438..210320e8e481 100644 --- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -700,7 +700,7 @@ _getwindowobject(NPP npp) NS_ENSURE_TRUE(outer, nullptr); JS::Rooted global(dom::RootingCx(), - nsGlobalWindow::Cast(outer)->GetGlobalJSObject()); + nsGlobalWindowOuter::Cast(outer)->GetGlobalJSObject()); return nsJSObjWrapper::GetNewOrUsed(npp, global); } @@ -976,7 +976,7 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result) nsIDocument *doc = GetDocumentFromNPP(npp); NS_ENSURE_TRUE(doc, false); - nsGlobalWindow* win = nsGlobalWindow::Cast(doc->GetInnerWindow()); + nsGlobalWindowInner* win = nsGlobalWindowInner::Cast(doc->GetInnerWindow()); if (NS_WARN_IF(!win || !win->FastGetGlobalJSObject())) { return false; } diff --git a/dom/presentation/PresentationRequest.cpp b/dom/presentation/PresentationRequest.cpp index 5546531207ea..4c00150a359d 100644 --- a/dom/presentation/PresentationRequest.cpp +++ b/dom/presentation/PresentationRequest.cpp @@ -188,7 +188,7 @@ PresentationRequest::StartWithDevice(const nsAString& aDeviceId, return promise.forget(); } - RefPtr navigator = nsGlobalWindow::Cast(GetOwner())->Navigator(); + RefPtr navigator = nsGlobalWindowInner::Cast(GetOwner())->Navigator(); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } @@ -488,7 +488,7 @@ PresentationRequest::NotifyPromiseSettled() return; } - RefPtr navigator = nsGlobalWindow::Cast(GetOwner())->Navigator(); + RefPtr navigator = nsGlobalWindowInner::Cast(GetOwner())->Navigator(); if (!navigator) { return; } diff --git a/dom/presentation/PresentationService.cpp b/dom/presentation/PresentationService.cpp index 356cbcdfcc2a..9d0dc6f48c35 100644 --- a/dom/presentation/PresentationService.cpp +++ b/dom/presentation/PresentationService.cpp @@ -1123,7 +1123,7 @@ PresentationService::UntrackSessionInfo(const nsAString& aSessionId, "dom::PresentationService::UntrackSessionInfo", [windowId]() -> void { PRES_DEBUG("Attempt to close window[%" PRIu64 "]\n", windowId); - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) { + if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowId)) { window->Close(); } })); diff --git a/dom/presentation/PresentationSessionInfo.cpp b/dom/presentation/PresentationSessionInfo.cpp index 233eb88bf670..88449e206000 100644 --- a/dom/presentation/PresentationSessionInfo.cpp +++ b/dom/presentation/PresentationSessionInfo.cpp @@ -395,7 +395,7 @@ PresentationSessionInfo::GetWindow() return nullptr; } - auto window = nsGlobalWindow::GetInnerWindowWithId(windowId); + auto window = nsGlobalWindowInner::GetInnerWindowWithId(windowId); if (!window) { return nullptr; } diff --git a/dom/presentation/ipc/PresentationBuilderChild.cpp b/dom/presentation/ipc/PresentationBuilderChild.cpp index aa9a0bdaff1c..70cd24d6b22d 100644 --- a/dom/presentation/ipc/PresentationBuilderChild.cpp +++ b/dom/presentation/ipc/PresentationBuilderChild.cpp @@ -47,7 +47,7 @@ nsresult PresentationBuilderChild::Init() return NS_ERROR_NOT_AVAILABLE; } - nsPIDOMWindowInner* window = nsGlobalWindow::GetInnerWindowWithId(windowId)->AsInner(); + nsPIDOMWindowInner* window = nsGlobalWindowInner::GetInnerWindowWithId(windowId)->AsInner(); if (NS_WARN_IF(!window)) { return NS_ERROR_NOT_AVAILABLE; } diff --git a/dom/presentation/ipc/PresentationIPCService.cpp b/dom/presentation/ipc/PresentationIPCService.cpp index 3062db79bfcc..3ae25f1f764f 100644 --- a/dom/presentation/ipc/PresentationIPCService.cpp +++ b/dom/presentation/ipc/PresentationIPCService.cpp @@ -73,7 +73,7 @@ PresentationIPCService::StartSession( } nsPIDOMWindowInner* window = - nsGlobalWindow::GetInnerWindowWithId(aWindowId)->AsInner(); + nsGlobalWindowInner::GetInnerWindowWithId(aWindowId)->AsInner(); TabId tabId = TabParent::GetTabIdFrom(window->GetDocShell()); return SendRequest(aCallback, StartSessionRequest(aUrls, @@ -490,7 +490,7 @@ PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId, [windowId]() -> void { PRES_DEBUG("Attempt to close window[%" PRIu64 "]\n", windowId); - if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) { + if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowId)) { window->Close(); } })); diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp index 9c237deaea27..0fb242c22699 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -497,7 +497,9 @@ Promise::ReportRejectedPromise(JSContext* aCx, JS::HandleObject aPromise) bool isMainThread = MOZ_LIKELY(NS_IsMainThread()); bool isChrome = isMainThread ? nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aPromise)) : GetCurrentThreadWorkerPrivate()->IsChromeWorker(); - nsGlobalWindow* win = isMainThread ? xpc::WindowGlobalOrNull(aPromise) : nullptr; + nsGlobalWindowInner* win = isMainThread + ? xpc::WindowGlobalOrNull(aPromise) + : nullptr; xpcReport->Init(report.report(), report.toStringResult().c_str(), isChrome, win ? win->AsInner()->WindowID() : 0); diff --git a/dom/script/ScriptSettings.cpp b/dom/script/ScriptSettings.cpp index 4436c6d08670..a3c2bff2e31e 100644 --- a/dom/script/ScriptSettings.cpp +++ b/dom/script/ScriptSettings.cpp @@ -505,23 +505,23 @@ AutoJSAPI::Init(JSObject* aObject) bool AutoJSAPI::Init(nsPIDOMWindowInner* aWindow, JSContext* aCx) { - return Init(nsGlobalWindow::Cast(aWindow), aCx); + return Init(nsGlobalWindowInner::Cast(aWindow), aCx); } bool AutoJSAPI::Init(nsPIDOMWindowInner* aWindow) { - return Init(nsGlobalWindow::Cast(aWindow)); + return Init(nsGlobalWindowInner::Cast(aWindow)); } bool -AutoJSAPI::Init(nsGlobalWindow* aWindow, JSContext* aCx) +AutoJSAPI::Init(nsGlobalWindowInner* aWindow, JSContext* aCx) { return Init(static_cast(aWindow), aCx); } bool -AutoJSAPI::Init(nsGlobalWindow* aWindow) +AutoJSAPI::Init(nsGlobalWindowInner* aWindow) { return Init(static_cast(aWindow)); } @@ -552,7 +552,7 @@ WarningOnlyErrorReporter(JSContext* aCx, JSErrorReport* aRep) } RefPtr xpcReport = new xpc::ErrorReport(); - nsGlobalWindow* win = xpc::CurrentWindowOrNull(aCx); + nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aCx); if (!win) { // We run addons in a separate privileged compartment, but if we're in an // addon compartment we should log warnings to the console of the associated @@ -592,7 +592,7 @@ AutoJSAPI::ReportException() if (mIsMainThread) { RefPtr xpcReport = new xpc::ErrorReport(); - RefPtr win = xpc::WindowGlobalOrNull(errorGlobal); + RefPtr win = xpc::WindowGlobalOrNull(errorGlobal); if (!win) { // We run addons in a separate privileged compartment, but they still // expect to trigger the onerror handler of their associated DOM Window. diff --git a/dom/script/ScriptSettings.h b/dom/script/ScriptSettings.h index 58c3d1a5aecf..f26df97ec1fa 100644 --- a/dom/script/ScriptSettings.h +++ b/dom/script/ScriptSettings.h @@ -19,7 +19,7 @@ #include "js/Debug.h" class nsPIDOMWindowInner; -class nsGlobalWindow; +class nsGlobalWindowInner; class nsIScriptContext; class nsIDocument; class nsIDocShell; @@ -246,8 +246,8 @@ public: MOZ_MUST_USE bool Init(nsPIDOMWindowInner* aWindow); MOZ_MUST_USE bool Init(nsPIDOMWindowInner* aWindow, JSContext* aCx); - MOZ_MUST_USE bool Init(nsGlobalWindow* aWindow); - MOZ_MUST_USE bool Init(nsGlobalWindow* aWindow, JSContext* aCx); + MOZ_MUST_USE bool Init(nsGlobalWindowInner* aWindow); + MOZ_MUST_USE bool Init(nsGlobalWindowInner* aWindow, JSContext* aCx); JSContext* cx() const { MOZ_ASSERT(mCx, "Must call Init before using an AutoJSAPI"); diff --git a/dom/smil/TimeEvent.cpp b/dom/smil/TimeEvent.cpp index 72bc34df5b23..d13f67221cbc 100644 --- a/dom/smil/TimeEvent.cpp +++ b/dom/smil/TimeEvent.cpp @@ -53,7 +53,7 @@ TimeEvent::GetDetail(int32_t* aDetail) } void -TimeEvent::InitTimeEvent(const nsAString& aType, nsGlobalWindow* aView, +TimeEvent::InitTimeEvent(const nsAString& aType, nsGlobalWindowInner* aView, int32_t aDetail) { NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched); diff --git a/dom/smil/TimeEvent.h b/dom/smil/TimeEvent.h index b5af5747ec0d..28548418babb 100644 --- a/dom/smil/TimeEvent.h +++ b/dom/smil/TimeEvent.h @@ -11,7 +11,7 @@ #include "mozilla/dom/TimeEventBinding.h" #include "nsIDOMTimeEvent.h" -class nsGlobalWindow; +class nsGlobalWindowInner; namespace mozilla { namespace dom { @@ -39,7 +39,7 @@ public: return TimeEventBinding::Wrap(aCx, this, aGivenProto); } - void InitTimeEvent(const nsAString& aType, nsGlobalWindow* aView, + void InitTimeEvent(const nsAString& aType, nsGlobalWindowInner* aView, int32_t aDetail); diff --git a/dom/vr/VREventObserver.cpp b/dom/vr/VREventObserver.cpp index 5d4c815f28be..a990bc8c9f14 100644 --- a/dom/vr/VREventObserver.cpp +++ b/dom/vr/VREventObserver.cpp @@ -22,7 +22,7 @@ using namespace gfx; * window.onvrdisplaydeactivate, window.onvrdisplayconnected, * window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange. */ -VREventObserver::VREventObserver(nsGlobalWindow* aGlobalWindow) +VREventObserver::VREventObserver(nsGlobalWindowInner* aGlobalWindow) : mWindow(aGlobalWindow) , mIs2DView(true) , mHasReset(false) diff --git a/dom/vr/VREventObserver.h b/dom/vr/VREventObserver.h index ed302ecb90ca..774579228f22 100644 --- a/dom/vr/VREventObserver.h +++ b/dom/vr/VREventObserver.h @@ -10,7 +10,7 @@ #include "mozilla/dom/VRDisplayEventBinding.h" #include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING -class nsGlobalWindow; +class nsGlobalWindowInner; namespace mozilla { namespace dom { @@ -19,7 +19,7 @@ class VREventObserver final { public: NS_INLINE_DECL_REFCOUNTING(VREventObserver) - explicit VREventObserver(nsGlobalWindow* aGlobalWindow); + explicit VREventObserver(nsGlobalWindowInner* aGlobalWindow); void NotifyVRDisplayMounted(uint32_t aDisplayID); void NotifyVRDisplayUnmounted(uint32_t aDisplayID); @@ -35,7 +35,7 @@ public: private: ~VREventObserver(); - RefPtr mWindow; + RefPtr mWindow; // For WebVR telemetry for tracking users who view content // in the 2D view. TimeStamp mSpendTimeIn2DView; diff --git a/dom/workers/ServiceWorkerClient.cpp b/dom/workers/ServiceWorkerClient.cpp index 68d4a7ec5680..1ecc249ed68b 100644 --- a/dom/workers/ServiceWorkerClient.cpp +++ b/dom/workers/ServiceWorkerClient.cpp @@ -43,7 +43,8 @@ ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc, uint32_t aOr NS_WARNING("Failed to get the UUID of the document."); } - RefPtr innerWindow = nsGlobalWindow::Cast(aDoc->GetInnerWindow()); + RefPtr innerWindow = + nsGlobalWindowInner::Cast(aDoc->GetInnerWindow()); if (innerWindow) { // XXXcatalinb: The inner window can be null if the document is navigating // and was detached. @@ -69,7 +70,8 @@ ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc, uint32_t aOr MOZ_ASSERT_IF(mLastFocusTime.IsNull(), !mFocused); MOZ_ASSERT_IF(mFocused, !mLastFocusTime.IsNull()); - RefPtr outerWindow = nsGlobalWindow::Cast(aDoc->GetWindow()); + RefPtr outerWindow = + nsGlobalWindowOuter::Cast(aDoc->GetWindow()); if (!outerWindow) { MOZ_ASSERT(mFrameType == FrameType::None); } else if (!outerWindow->IsTopLevelWindow()) { @@ -150,7 +152,7 @@ public: Run() override { AssertIsOnMainThread(); - nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId); + nsGlobalWindowInner* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowId); if (!window) { return NS_ERROR_FAILURE; } diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index 3ba27b574b3b..025404ed7b7e 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -3093,7 +3093,7 @@ FireControllerChangeOnDocument(nsIDocument* aDocument) return; } - auto* window = nsGlobalWindow::Cast(w.get()); + auto* window = nsGlobalWindowInner::Cast(w.get()); dom::Navigator* navigator = window->Navigator(); if (!navigator) { return; @@ -3784,7 +3784,8 @@ ServiceWorkerManager::ShouldReportToWindow(mozIDOMWindowProxy* aWindow, continue; } - nsCOMPtr win = nsGlobalWindow::GetInnerWindowWithId(id)->AsInner(); + nsCOMPtr win = + nsGlobalWindowInner::GetInnerWindowWithId(id)->AsInner(); if (!win) { continue; } diff --git a/dom/workers/ServiceWorkerWindowClient.cpp b/dom/workers/ServiceWorkerWindowClient.cpp index 5689ac727a18..eb88336e5149 100644 --- a/dom/workers/ServiceWorkerWindowClient.cpp +++ b/dom/workers/ServiceWorkerWindowClient.cpp @@ -122,7 +122,8 @@ public: Run() override { AssertIsOnMainThread(); - nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId); + nsGlobalWindowInner* window = + nsGlobalWindowInner::GetInnerWindowWithId(mWindowId); UniquePtr clientInfo; if (window) { @@ -383,7 +384,7 @@ public: return RejectPromise(NS_ERROR_TYPE_ERR); } - nsGlobalWindow* window; + nsGlobalWindowInner* window; rv = Navigate(url, principal, &window); if (NS_WARN_IF(NS_FAILED(rv))) { return RejectPromise(rv); @@ -471,11 +472,12 @@ private: } nsresult - Navigate(nsIURI* aUrl, nsIPrincipal* aPrincipal, nsGlobalWindow** aWindow) + Navigate(nsIURI* aUrl, nsIPrincipal* aPrincipal, nsGlobalWindowInner** aWindow) { MOZ_ASSERT(aWindow); - nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId); + nsGlobalWindowInner* window = + nsGlobalWindowInner::GetInnerWindowWithId(mWindowId); if (NS_WARN_IF(!window)) { return NS_ERROR_TYPE_ERR; } diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp index e6b6ca775574..1a226514aef2 100644 --- a/dom/workers/WorkerRunnable.cpp +++ b/dom/workers/WorkerRunnable.cpp @@ -303,7 +303,7 @@ WorkerRunnable::Run() } else { kungFuDeathGrip = mWorkerPrivate; if (isMainThread) { - globalObject = nsGlobalWindow::Cast(mWorkerPrivate->GetWindow()); + globalObject = nsGlobalWindowInner::Cast(mWorkerPrivate->GetWindow()); } else { globalObject = mWorkerPrivate->GetParent()->GlobalScope(); } diff --git a/dom/xbl/nsXBLPrototypeHandler.cpp b/dom/xbl/nsXBLPrototypeHandler.cpp index ead9b8a7c449..f3f8580297da 100644 --- a/dom/xbl/nsXBLPrototypeHandler.cpp +++ b/dom/xbl/nsXBLPrototypeHandler.cpp @@ -93,7 +93,7 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(const char16_t* aEvent, uint32_t aLineNumber) : mHandlerText(nullptr), mLineNumber(aLineNumber), - mReserved(false), + mReserved(XBLReservedKey_False), mNextHandler(nullptr), mPrototypeBinding(aBinding) { @@ -104,7 +104,7 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(const char16_t* aEvent, aGroup, aPreventDefault, aAllowUntrusted); } -nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement, bool aReserved) +nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement, XBLReservedKey aReserved) : mHandlerElement(nullptr), mLineNumber(0), mReserved(aReserved), @@ -120,7 +120,7 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsIContent* aHandlerElement, bool a nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding) : mHandlerText(nullptr), mLineNumber(0), - mReserved(false), + mReserved(XBLReservedKey_False), mNextHandler(nullptr), mPrototypeBinding(aBinding) { diff --git a/dom/xbl/nsXBLPrototypeHandler.h b/dom/xbl/nsXBLPrototypeHandler.h index b32072f80edd..ed00ed925916 100644 --- a/dom/xbl/nsXBLPrototypeHandler.h +++ b/dom/xbl/nsXBLPrototypeHandler.h @@ -55,6 +55,15 @@ class KeyboardShortcut; #define NS_PHASE_TARGET 2 #define NS_PHASE_BUBBLING 3 +// Values of the reserved attribute. When unset, the default value depends on +// the permissions.default.shortcuts preference. +enum XBLReservedKey : uint8_t +{ + XBLReservedKey_False = 0, + XBLReservedKey_True = 1, + XBLReservedKey_Unset = 2, +}; + class nsXBLPrototypeHandler { typedef mozilla::IgnoreModifierState IgnoreModifierState; @@ -74,7 +83,7 @@ public: uint32_t aLineNumber); // This constructor is used only by XUL key handlers (e.g., ) - explicit nsXBLPrototypeHandler(nsIContent* aKeyElement, bool aReserved); + explicit nsXBLPrototypeHandler(nsIContent* aKeyElement, XBLReservedKey aReserved); // This constructor is used for handlers loaded from the cache explicit nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding); @@ -118,7 +127,7 @@ public: uint8_t GetPhase() { return mPhase; } uint8_t GetType() { return mType; } - bool GetIsReserved() { return mReserved; } + XBLReservedKey GetIsReserved() { return mReserved; } nsXBLPrototypeHandler* GetNextHandler() { return mNextHandler; } void SetNextHandler(nsXBLPrototypeHandler* aHandler) { mNextHandler = aHandler; } @@ -233,7 +242,7 @@ protected: // stores whether or not we're a key code or char code. // For mouse events, stores the clickCount. - bool mReserved; // is reserved for chrome. Not used by handlers. + XBLReservedKey mReserved; // is reserved for chrome. Not used by handlers. int32_t mKeyMask; // Which modifier keys this event handler expects to have down // in order to be matched. diff --git a/dom/xbl/nsXBLWindowKeyHandler.cpp b/dom/xbl/nsXBLWindowKeyHandler.cpp index 0385617d865c..fe87322d5e99 100644 --- a/dom/xbl/nsXBLWindowKeyHandler.cpp +++ b/dom/xbl/nsXBLWindowKeyHandler.cpp @@ -211,8 +211,16 @@ BuildHandlerChain(nsIContent* aContent, nsXBLPrototypeHandler** aResult) valKey.IsEmpty() && valCharCode.IsEmpty() && valKeyCode.IsEmpty()) continue; - bool reserved = key->AttrValueIs(kNameSpaceID_None, nsGkAtoms::reserved, - nsGkAtoms::_true, eCaseMatters); + // reserved="pref" is the default for elements. + XBLReservedKey reserved = XBLReservedKey_Unset; + if (key->AttrValueIs(kNameSpaceID_None, nsGkAtoms::reserved, + nsGkAtoms::_true, eCaseMatters)) { + reserved = XBLReservedKey_True; + } else if (key->AttrValueIs(kNameSpaceID_None, nsGkAtoms::reserved, + nsGkAtoms::_false, eCaseMatters)) { + reserved = XBLReservedKey_False; + } + nsXBLPrototypeHandler* handler = new nsXBLPrototypeHandler(key, reserved); handler->SetNextHandler(*aResult); @@ -725,11 +733,6 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute( continue; } - bool isReserved = handler->GetIsReserved(); - if (aOutReservedForChrome) { - *aOutReservedForChrome = isReserved; - } - if (commandElement) { if (aExecute && !IsExecutableElement(commandElement)) { continue; @@ -738,23 +741,37 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute( if (!aExecute) { if (handler->EventTypeEquals(aEventType)) { + if (aOutReservedForChrome) { + *aOutReservedForChrome = IsReservedKey(widgetKeyboardEvent, handler); + } + return true; } + // If the command is reserved and the event is keydown, check also if // the handler is for keypress because if following keypress event is // reserved, we shouldn't dispatch the event into web contents. - if (isReserved && - aEventType == nsGkAtoms::keydown && + if (aEventType == nsGkAtoms::keydown && handler->EventTypeEquals(nsGkAtoms::keypress)) { - return true; + if (IsReservedKey(widgetKeyboardEvent, handler)) { + if (aOutReservedForChrome) { + *aOutReservedForChrome = true; + } + + return true; + } } // Otherwise, we've not found a handler for the event yet. continue; } + // This should only be assigned when aExecute is false. + MOZ_ASSERT(!aOutReservedForChrome); + // If it's not reserved and the event is a key event on a plugin, // the handler shouldn't be executed. - if (!isReserved && widgetKeyboardEvent->IsKeyEventOnPlugin()) { + if (widgetKeyboardEvent->IsKeyEventOnPlugin() && + !IsReservedKey(widgetKeyboardEvent, handler)) { return false; } @@ -791,6 +808,25 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute( return false; } +bool +nsXBLWindowKeyHandler::IsReservedKey(WidgetKeyboardEvent* aKeyEvent, + nsXBLPrototypeHandler* aHandler) +{ + XBLReservedKey reserved = aHandler->GetIsReserved(); + // reserved="true" means that the key is always reserved. reserved="false" + // means that the key is never reserved. Otherwise, we check site-specific + // permissions. + if (reserved == XBLReservedKey_False) { + return false; + } + + if (reserved == XBLReservedKey_True) { + return true; + } + + return nsContentUtils::ShouldBlockReservedKeys(aKeyEvent); +} + bool nsXBLWindowKeyHandler::HasHandlerForEvent(nsIDOMKeyEvent* aEvent, bool* aOutReservedForChrome) diff --git a/dom/xbl/nsXBLWindowKeyHandler.h b/dom/xbl/nsXBLWindowKeyHandler.h index a8b993dc63d8..38eba97118db 100644 --- a/dom/xbl/nsXBLWindowKeyHandler.h +++ b/dom/xbl/nsXBLWindowKeyHandler.h @@ -19,6 +19,7 @@ class nsXBLPrototypeHandler; namespace mozilla { class EventListenerManager; +class WidgetKeyboardEvent; struct IgnoreModifierState; namespace dom { class Element; @@ -77,6 +78,11 @@ protected: bool HasHandlerForEvent(nsIDOMKeyEvent* aEvent, bool* aOutReservedForChrome = nullptr); + // Returns true if the key would be reserved for the given handler. A reserved + // key is not sent to a content process or single-process equivalent. + bool IsReservedKey(mozilla::WidgetKeyboardEvent* aKeyEvent, + nsXBLPrototypeHandler* aHandler); + // Returns event type for matching between aWidgetKeyboardEvent and // shortcut key handlers. This is used for calling WalkHandlers(), // WalkHandlersInternal() and WalkHandlersAndExecute(). diff --git a/dom/xslt/crashtests/1336828.html b/dom/xslt/crashtests/1336828.html new file mode 100644 index 000000000000..3f25e23e034e --- /dev/null +++ b/dom/xslt/crashtests/1336828.html @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/dom/xslt/crashtests/1336830.html b/dom/xslt/crashtests/1336830.html new file mode 100644 index 000000000000..907f58956394 --- /dev/null +++ b/dom/xslt/crashtests/1336830.html @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/dom/xslt/crashtests/1336832.html b/dom/xslt/crashtests/1336832.html new file mode 100644 index 000000000000..0fb9033d1a34 --- /dev/null +++ b/dom/xslt/crashtests/1336832.html @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/dom/xslt/crashtests/949990.html b/dom/xslt/crashtests/949990.html new file mode 100644 index 000000000000..23868e4db3ba --- /dev/null +++ b/dom/xslt/crashtests/949990.html @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/dom/xslt/crashtests/crashtests.list b/dom/xslt/crashtests/crashtests.list index fbbf12c5ae73..13de6c1dd5ff 100644 --- a/dom/xslt/crashtests/crashtests.list +++ b/dom/xslt/crashtests/crashtests.list @@ -15,9 +15,13 @@ load 601543.html load 602115.html load 603844.html load 667315.xml +load 949990.html load 1089049.html load 1205163.xml load 1243337.xml load 1330492.html +load 1336828.html +load 1336830.html +load 1336832.html load 1338277.html load 1361892.html diff --git a/dom/xslt/xpath/XPathExpression.cpp b/dom/xslt/xpath/XPathExpression.cpp index f8c2c779f574..8fd9f0d3287f 100644 --- a/dom/xslt/xpath/XPathExpression.cpp +++ b/dom/xslt/xpath/XPathExpression.cpp @@ -101,6 +101,11 @@ XPathExpression::EvaluateWithContext(nsINode& aContextNode, return nullptr; } + if (aType > XPathResultBinding::FIRST_ORDERED_NODE_TYPE) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return nullptr; + } + if (!nsContentUtils::LegacyIsCallerNativeCode() && !nsContentUtils::CanCallerAccess(&aContextNode)) { diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp index 81af32dd8c80..e412975bc9f1 100644 --- a/extensions/cookie/nsPermissionManager.cpp +++ b/extensions/cookie/nsPermissionManager.cpp @@ -135,7 +135,8 @@ static const char* kPermissionsWithDefaults[] = { "camera", "microphone", "geo", - "desktop-notification" + "desktop-notification", + "shortcuts" }; // NOTE: nullptr can be passed as aType - if it is this function will return diff --git a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic index 869b119bf519..b516477b0e68 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic +++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic @@ -1,4 +1,4 @@ -52371 +52373 0/nm 0th/pt 1/n1 @@ -33803,6 +33803,7 @@ maleness/M malevolence/M malevolent/Y malfeasance/M +malform/S malformation/SM malformed malfunction/MDSG @@ -42047,6 +42048,7 @@ remarkableness/M remarkably remarked/U remediable +remediate/DGS remedy/GDSM remember/DG remembered/U diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 261fb4fd0b71..f17e88b8fb61 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -1573,12 +1573,14 @@ DrawTarget::Draw3DTransformedSurface(SourceSurface* aSurface, const Matrix4x4& a if (!dstSurf) { return false; } + + DataSourceSurface::ScopedMap map(dstSurf, DataSourceSurface::READ_WRITE); std::unique_ptr dstCanvas( SkCanvas::MakeRasterDirect( SkImageInfo::Make(xformBounds.Width(), xformBounds.Height(), GfxFormatToSkiaColorType(dstSurf->GetFormat()), kPremul_SkAlphaType), - dstSurf->GetData(), dstSurf->Stride())); + map.GetData(), map.GetStride())); if (!dstCanvas) { return false; } @@ -1746,13 +1748,14 @@ DrawTargetSkia::OptimizeSourceSurfaceForUnknownAlpha(SourceSurface *aSurface) co } RefPtr dataSurface = aSurface->GetDataSurface(); + DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ_WRITE); // For plugins, GDI can sometimes just write 0 to the alpha channel // even for RGBX formats. In this case, we have to manually write // the alpha channel to make Skia happy with RGBX and in case GDI // writes some bad data. Luckily, this only happens on plugins. - WriteRGBXFormat(dataSurface->GetData(), dataSurface->GetSize(), - dataSurface->Stride(), dataSurface->GetFormat()); + WriteRGBXFormat(map.GetData(), dataSurface->GetSize(), + map.GetStride(), dataSurface->GetFormat()); return dataSurface.forget(); } @@ -1775,8 +1778,11 @@ DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const // to trigger any required readback so that it only happens // once. RefPtr dataSurface = aSurface->GetDataSurface(); - MOZ_ASSERT(VerifyRGBXFormat(dataSurface->GetData(), dataSurface->GetSize(), - dataSurface->Stride(), dataSurface->GetFormat())); +#ifdef DEBUG + DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ); + MOZ_ASSERT(VerifyRGBXFormat(map.GetData(), dataSurface->GetSize(), + map.GetStride(), dataSurface->GetFormat())); +#endif return dataSurface.forget(); } diff --git a/gfx/2d/FilterProcessingSIMD-inl.h b/gfx/2d/FilterProcessingSIMD-inl.h index e0024148d4bb..986d8695af62 100644 --- a/gfx/2d/FilterProcessingSIMD-inl.h +++ b/gfx/2d/FilterProcessingSIMD-inl.h @@ -20,10 +20,12 @@ ConvertToB8G8R8A8_SIMD(SourceSurface* aSurface) RefPtr input = aSurface->GetDataSurface(); RefPtr output = Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8); - uint8_t *inputData = input->GetData(); - uint8_t *outputData = output->GetData(); - int32_t inputStride = input->Stride(); - int32_t outputStride = output->Stride(); + DataSourceSurface::ScopedMap inputMap(input, DataSourceSurface::READ); + DataSourceSurface::ScopedMap outputMap(output, DataSourceSurface::READ_WRITE); + uint8_t *inputData = inputMap.GetData(); + uint8_t *outputData = outputMap.GetData(); + int32_t inputStride = inputMap.GetStride(); + int32_t outputStride = outputMap.GetStride(); switch (input->GetFormat()) { case SurfaceFormat::B8G8R8A8: output = input; @@ -295,12 +297,16 @@ ApplyBlending_SIMD(DataSourceSurface* aInput1, DataSourceSurface* aInput2) return nullptr; } - uint8_t* source1Data = aInput1->GetData(); - uint8_t* source2Data = aInput2->GetData(); - uint8_t* targetData = target->GetData(); - int32_t targetStride = target->Stride(); - int32_t source1Stride = aInput1->Stride(); - int32_t source2Stride = aInput2->Stride(); + DataSourceSurface::ScopedMap inputMap1(aInput1, DataSourceSurface::READ); + DataSourceSurface::ScopedMap inputMap2(aInput2, DataSourceSurface::READ); + DataSourceSurface::ScopedMap outputMap(target, DataSourceSurface::READ_WRITE); + + uint8_t* source1Data = inputMap1.GetData(); + uint8_t* source2Data = inputMap2.GetData(); + uint8_t* targetData = outputMap.GetData(); + int32_t targetStride = outputMap.GetStride(); + int32_t source1Stride = inputMap1.GetStride(); + int32_t source2Stride = inputMap2.GetStride(); for (int32_t y = 0; y < size.height; y++) { for (int32_t x = 0; x < size.width; x += 4) { @@ -520,10 +526,13 @@ ApplyColorMatrix_SIMD(DataSourceSurface* aInput, const Matrix5x4 &aMatrix) return nullptr; } - uint8_t* sourceData = aInput->GetData(); - uint8_t* targetData = target->GetData(); - int32_t sourceStride = aInput->Stride(); - int32_t targetStride = target->Stride(); + DataSourceSurface::ScopedMap inputMap(aInput, DataSourceSurface::READ); + DataSourceSurface::ScopedMap outputMap(target, DataSourceSurface::READ_WRITE); + + uint8_t* sourceData = inputMap.GetData(); + uint8_t* targetData = outputMap.GetData(); + int32_t sourceStride = inputMap.GetStride(); + int32_t targetStride = outputMap.GetStride(); const int16_t factor = 128; const Float floatElementMax = INT16_MAX / factor; // 255 @@ -702,10 +711,13 @@ ApplyComposition(DataSourceSurface* aSource, DataSourceSurface* aDest) { IntSize size = aDest->GetSize(); - uint8_t* sourceData = aSource->GetData(); - uint8_t* destData = aDest->GetData(); - uint32_t sourceStride = aSource->Stride(); - uint32_t destStride = aDest->Stride(); + DataSourceSurface::ScopedMap input(aSource, DataSourceSurface::READ); + DataSourceSurface::ScopedMap output(aDest, DataSourceSurface::READ_WRITE); + + uint8_t* sourceData = input.GetData(); + uint8_t* destData = output.GetData(); + uint32_t sourceStride = input.GetStride(); + uint32_t destStride = output.GetStride(); for (int32_t y = 0; y < size.height; y++) { for (int32_t x = 0; x < size.width; x += 4) { @@ -1025,12 +1037,16 @@ ApplyArithmeticCombine_SIMD(DataSourceSurface* aInput1, DataSourceSurface* aInpu return nullptr; } - uint8_t* source1Data = aInput1->GetData(); - uint8_t* source2Data = aInput2->GetData(); - uint8_t* targetData = target->GetData(); - uint32_t source1Stride = aInput1->Stride(); - uint32_t source2Stride = aInput2->Stride(); - uint32_t targetStride = target->Stride(); + DataSourceSurface::ScopedMap inputMap1(aInput1, DataSourceSurface::READ); + DataSourceSurface::ScopedMap inputMap2(aInput2, DataSourceSurface::READ); + DataSourceSurface::ScopedMap outputMap(target, DataSourceSurface::READ_WRITE); + + uint8_t* source1Data = inputMap1.GetData(); + uint8_t* source2Data = inputMap2.GetData(); + uint8_t* targetData = outputMap.GetData(); + uint32_t source1Stride = inputMap1.GetStride(); + uint32_t source2Stride = inputMap2.GetStride(); + uint32_t targetStride = outputMap.GetStride(); // The arithmetic combine filter does the following calculation: // result = k1 * in1 * in2 + k2 * in1 + k3 * in2 + k4 diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index 0b67369e2e8b..97f76757c88f 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -1533,8 +1533,10 @@ RecordedDrawTargetCreation::Record(S &aStream) const MOZ_ASSERT(mExistingData); MOZ_ASSERT(mExistingData->GetSize() == mSize); RefPtr dataSurf = mExistingData->GetDataSurface(); + + DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ); for (int y = 0; y < mSize.height; y++) { - aStream.write((const char*)dataSurf->GetData() + y * dataSurf->Stride(), + aStream.write((const char*)map.GetData() + y * map.GetStride(), BytesPerPixel(mFormat) * mSize.width); } } @@ -1559,8 +1561,9 @@ RecordedDrawTargetCreation::RecordedDrawTargetCreation(S &aStream) return; } + DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ); for (int y = 0; y < mSize.height; y++) { - aStream.read((char*)dataSurf->GetData() + y * dataSurf->Stride(), + aStream.read((char*)map.GetData() + y * map.GetStride(), BytesPerPixel(mFormat) * mSize.width); } mExistingData = dataSurf; diff --git a/gfx/2d/SVGTurbulenceRenderer-inl.h b/gfx/2d/SVGTurbulenceRenderer-inl.h index b46d741e7b02..e9cda10e32ce 100644 --- a/gfx/2d/SVGTurbulenceRenderer-inl.h +++ b/gfx/2d/SVGTurbulenceRenderer-inl.h @@ -329,8 +329,9 @@ SVGTurbulenceRenderer::Render(const IntSize return nullptr; } - uint8_t* targetData = target->GetData(); - uint32_t stride = target->Stride(); + DataSourceSurface::ScopedMap map(target, DataSourceSurface::READ_WRITE); + uint8_t* targetData = map.GetData(); + uint32_t stride = map.GetStride(); Point startOffset = EquivalentNonNegativeOffset(aOffset); diff --git a/gfx/2d/unittest/TestBugs.cpp b/gfx/2d/unittest/TestBugs.cpp index d0efff51599a..a04ca2517129 100644 --- a/gfx/2d/unittest/TestBugs.cpp +++ b/gfx/2d/unittest/TestBugs.cpp @@ -61,9 +61,11 @@ TestBugs::CairoClip918671() RefPtr dataSurf1 = surf1->GetDataSurface(); RefPtr dataSurf2 = surf2->GetDataSurface(); + DataSourceSurface::ScopedMap map1(dataSurf1, DataSourceSurface::READ); + DataSourceSurface::ScopedMap map2(dataSurf2, DataSourceSurface::READ); for (int y = 0; y < dt->GetSize().height; y++) { - VERIFY(memcmp(dataSurf1->GetData() + y * dataSurf1->Stride(), - dataSurf2->GetData() + y * dataSurf2->Stride(), + VERIFY(memcmp(map1.GetData() + y * map1.GetStride(), + map2.GetData() + y * map2.GetStride(), dataSurf1->GetSize().width * 4) == 0); } diff --git a/gfx/gl/GLReadTexImageHelper.cpp b/gfx/gl/GLReadTexImageHelper.cpp index 65937822824d..bc0d3b4f5ae1 100644 --- a/gfx/gl/GLReadTexImageHelper.cpp +++ b/gfx/gl/GLReadTexImageHelper.cpp @@ -315,7 +315,11 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) MOZ_CRASH("GFX: Bad format, read pixels."); } destPixelSize = BytesPerPixel(dest->GetFormat()); - MOZ_ASSERT(dest->GetSize().width * destPixelSize <= dest->Stride()); + + Maybe map; + map.emplace(dest, DataSourceSurface::READ_WRITE); + + MOZ_ASSERT(dest->GetSize().width * destPixelSize <= map->GetStride()); GLenum readFormat = destFormat; GLenum readType = destType; @@ -327,7 +331,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) DataSourceSurface* readSurf = dest; int readAlignment = GuessAlignment(dest->GetSize().width, destPixelSize, - dest->Stride()); + map->GetStride()); if (!readAlignment) { needsTempSurf = true; } @@ -389,9 +393,12 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) } readSurf = tempSurf; + map = Nothing(); + map.emplace(readSurf, DataSourceSurface::READ_WRITE); } + MOZ_ASSERT(readAlignment); - MOZ_ASSERT(reinterpret_cast(readSurf->GetData()) % readAlignment == 0); + MOZ_ASSERT(reinterpret_cast(map->GetData()) % readAlignment == 0); GLsizei width = dest->GetSize().width; GLsizei height = dest->GetSize().height; @@ -403,9 +410,11 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) gl->fReadPixels(0, 0, width, height, readFormat, readType, - readSurf->GetData()); + map->GetData()); } + map = Nothing(); + if (readSurf != dest) { MOZ_ASSERT(readFormat == LOCAL_GL_RGBA); MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE); @@ -414,12 +423,12 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) } already_AddRefed -YInvertImageSurface(gfx::DataSourceSurface* aSurf) +YInvertImageSurface(gfx::DataSourceSurface* aSurf, uint32_t aStride) { RefPtr temp = Factory::CreateDataSourceSurfaceWithStride(aSurf->GetSize(), aSurf->GetFormat(), - aSurf->Stride()); + aStride); if (NS_WARN_IF(!temp)) { return nullptr; } @@ -475,7 +484,8 @@ ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, SurfaceFormat aFo gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4); } - gl->fGetTexImage(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, surf->GetData()); + DataSourceSurface::ScopedMap map(surf, DataSourceSurface::READ); + gl->fGetTexImage(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, map.GetData()); if (currentPackAlignment != 4) { gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment); @@ -486,7 +496,7 @@ ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, SurfaceFormat aFo } if (aYInvert) { - surf = YInvertImageSurface(surf); + surf = YInvertImageSurface(surf, map.GetStride()); } return surf.forget(); diff --git a/gfx/gl/GLReadTexImageHelper.h b/gfx/gl/GLReadTexImageHelper.h index 20d229e5327a..8e9fb0eaf471 100644 --- a/gfx/gl/GLReadTexImageHelper.h +++ b/gfx/gl/GLReadTexImageHelper.h @@ -34,7 +34,7 @@ already_AddRefed ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, gfx::SurfaceFormat aFormat); already_AddRefed -YInvertImageSurface(gfx::DataSourceSurface* aSurf); +YInvertImageSurface(gfx::DataSourceSurface* aSurf, uint32_t aStride); void SwapRAndBComponents(gfx::DataSourceSurface* surf); diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp index 48d025013850..ef5296e9a2b3 100644 --- a/gfx/gl/GLUploadHelpers.cpp +++ b/gfx/gl/GLUploadHelpers.cpp @@ -539,10 +539,10 @@ UploadSurfaceToTexture(GLContext* gl, GLenum aTextureUnit, GLenum aTextureTarget) { - - int32_t stride = aSurface->Stride(); + DataSourceSurface::ScopedMap map(aSurface, DataSourceSurface::READ); + int32_t stride = map.GetStride(); SurfaceFormat format = aSurface->GetFormat(); - unsigned char* data = aSurface->GetData() + + unsigned char* data = map.GetData() + DataOffset(aSrcPoint, stride, format); return UploadImageDataToTexture(gl, data, stride, format, diff --git a/gfx/layers/AsyncCanvasRenderer.cpp b/gfx/layers/AsyncCanvasRenderer.cpp index 908ed9c81df4..e2023c26c556 100644 --- a/gfx/layers/AsyncCanvasRenderer.cpp +++ b/gfx/layers/AsyncCanvasRenderer.cpp @@ -238,12 +238,13 @@ AsyncCanvasRenderer::GetSurface() MutexAutoLock lock(mMutex); if (mSurfaceForBasic) { // Since SourceSurface isn't thread-safe, we need copy to a new SourceSurface. + gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ); + RefPtr result = gfx::Factory::CreateDataSourceSurfaceWithStride(mSurfaceForBasic->GetSize(), mSurfaceForBasic->GetFormat(), - mSurfaceForBasic->Stride()); + srcMap.GetStride()); - gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ); gfx::DataSourceSurface::ScopedMap dstMap(result, gfx::DataSourceSurface::WRITE); if (NS_WARN_IF(!srcMap.IsMapped()) || @@ -271,8 +272,10 @@ AsyncCanvasRenderer::GetInputStream(const char *aMimeType, return NS_ERROR_FAILURE; } + gfx::DataSourceSurface::ScopedMap map(surface, gfx::DataSourceSurface::READ); + // Handle y flip. - RefPtr dataSurf = gl::YInvertImageSurface(surface); + RefPtr dataSurf = gl::YInvertImageSurface(surface, map.GetStride()); return gfxUtils::GetInputStream(dataSurf, false, aMimeType, aEncoderOptions, aStream); } diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index 18f03ad562d4..4a6edd0bf44f 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -503,15 +503,16 @@ private: tp->set_ismask(mIsMask); if (aImage) { + DataSourceSurface::ScopedMap map(aImage, DataSourceSurface::READ); tp->set_width(aImage->GetSize().width); tp->set_height(aImage->GetSize().height); - tp->set_stride(aImage->Stride()); + tp->set_stride(map.GetStride()); - mDatasize = aImage->GetSize().height * aImage->Stride(); + mDatasize = aImage->GetSize().height * map.GetStride(); auto compresseddata = MakeUnique(LZ4::maxCompressedSize(mDatasize)); if (compresseddata) { - int ndatasize = LZ4::compress((char*)aImage->GetData(), + int ndatasize = LZ4::compress((char*)map.GetData(), mDatasize, compresseddata.get()); if (ndatasize > 0) { @@ -520,11 +521,11 @@ private: tp->set_data(compresseddata.get(), mDatasize); } else { NS_WARNING("Compress data failed"); - tp->set_data(aImage->GetData(), mDatasize); + tp->set_data(map.GetData(), mDatasize); } } else { NS_WARNING("Couldn't new compressed data."); - tp->set_data(aImage->GetData(), mDatasize); + tp->set_data(map.GetData(), mDatasize); } } else { tp->set_width(0); diff --git a/gfx/layers/composite/PaintCounter.cpp b/gfx/layers/composite/PaintCounter.cpp index d3a7103fd8ca..90fec23a3b41 100644 --- a/gfx/layers/composite/PaintCounter.cpp +++ b/gfx/layers/composite/PaintCounter.cpp @@ -28,11 +28,12 @@ PaintCounter::PaintCounter() { mFormat = SurfaceFormat::B8G8R8A8; mSurface = Factory::CreateDataSourceSurface(mRect.Size(), mFormat); - mStride = mSurface->Stride(); + mMap.emplace(mSurface, DataSourceSurface::READ_WRITE); + mStride = mMap->GetStride(); mCanvas = SkCanvas::MakeRasterDirect(MakeSkiaImageInfo(mRect.Size(), mFormat), - mSurface->GetData(), mStride); + mMap->GetData(), mStride); mCanvas->clear(SK_ColorWHITE); } diff --git a/gfx/layers/composite/PaintCounter.h b/gfx/layers/composite/PaintCounter.h index da0fa0a05d4e..b02ee2962c8c 100644 --- a/gfx/layers/composite/PaintCounter.h +++ b/gfx/layers/composite/PaintCounter.h @@ -8,6 +8,7 @@ #define mozilla_layers_PaintCounter_h_ #include // for std::map +#include "mozilla/Maybe.h" #include "mozilla/RefPtr.h" // for already_AddRefed, RefCounted #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration #include "skia/include/core/SkCanvas.h" @@ -41,6 +42,7 @@ private: RefPtr mSurface; RefPtr mTextureSource; RefPtr mTexturedEffect; + Maybe mMap; static IntRect mRect; }; diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 407f589723e5..9b37e61312f8 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -1448,8 +1448,8 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface, context->UpdateSubresource(mTexture, 0, &box, data, map.mStride, map.mStride * rect.Height()); } } else { - context->UpdateSubresource(mTexture, 0, nullptr, aSurface->GetData(), - aSurface->Stride(), aSurface->Stride() * mSize.height); + context->UpdateSubresource(mTexture, 0, nullptr, map.mData, + map.mStride, map.mStride * mSize.height); } aSurface->Unmap(); @@ -1462,6 +1462,13 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface, mTileSRVs.resize(tileCount); mTexture = nullptr; + DataSourceSurface::ScopedMap map(aSurface, DataSourceSurface::READ); + if (!map.IsMapped()) { + gfxCriticalError() << "Failed to map surface."; + Reset(); + return false; + } + for (uint32_t i = 0; i < tileCount; i++) { IntRect tileRect = GetTileRect(i); @@ -1470,10 +1477,10 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface, desc.Usage = D3D11_USAGE_IMMUTABLE; D3D11_SUBRESOURCE_DATA initData; - initData.pSysMem = aSurface->GetData() + - tileRect.y * aSurface->Stride() + + initData.pSysMem = map.GetData() + + tileRect.y * map.GetStride() + tileRect.x * bpp; - initData.SysMemPitch = aSurface->Stride(); + initData.SysMemPitch = map.GetStride(); hr = mDevice->CreateTexture2D(&desc, &initData, getter_AddRefs(mTileTextures[i])); if (FAILED(hr) || !mTileTextures[i]) { diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp index e85803714a76..a21200ed9124 100644 --- a/gfx/tests/gtest/TestCompositor.cpp +++ b/gfx/tests/gtest/TestCompositor.cpp @@ -130,17 +130,19 @@ static bool CompositeAndCompare(RefPtr layerManager, Draw RefPtr ss = drawTarget->Snapshot(); RefPtr dss = ss->GetDataSurface(); - uint8_t* bitmap = dss->GetData(); + DataSourceSurface::ScopedMap dssMap(dss, DataSourceSurface::READ); + uint8_t* bitmap = dssMap.GetData(); RefPtr ssRef = refDT->Snapshot(); RefPtr dssRef = ssRef->GetDataSurface(); - uint8_t* bitmapRef = dssRef->GetData(); + DataSourceSurface::ScopedMap dssRefMap(dssRef, DataSourceSurface::READ); + uint8_t* bitmapRef = dssRefMap.GetData(); for (int y = 0; y < gCompHeight; y++) { for (int x = 0; x < gCompWidth; x++) { for (size_t channel = 0; channel < 4; channel++) { - uint8_t bit = bitmap[y * dss->Stride() + x * 4 + channel]; - uint8_t bitRef = bitmapRef[y * dss->Stride() + x * 4 + channel]; + uint8_t bit = bitmap[y * dssMap.GetStride() + x * 4 + channel]; + uint8_t bitRef = bitmapRef[y * dssRefMap.GetStride() + x * 4 + channel]; if (bit != bitRef) { printf("Layer Tree:\n"); layerManager->Dump(); diff --git a/gfx/tests/gtest/TestTextures.cpp b/gfx/tests/gtest/TestTextures.cpp index df4fb2e5f882..19b94b867117 100644 --- a/gfx/tests/gtest/TestTextures.cpp +++ b/gfx/tests/gtest/TestTextures.cpp @@ -163,10 +163,11 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) if (host->Lock()) { RefPtr hostDataSurface = host->GetAsSurface(); + DataSourceSurface::ScopedMap map(hostDataSurface, DataSourceSurface::READ); RefPtr hostSurface = - new gfxImageSurface(hostDataSurface->GetData(), + new gfxImageSurface(map.GetData(), hostDataSurface->GetSize(), - hostDataSurface->Stride(), + map.GetStride(), SurfaceFormatToImageFormat(hostDataSurface->GetFormat())); AssertSurfacesEqual(surface, hostSurface.get()); host->Unlock(); diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 5f844aac9ae9..de4486cff86d 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -12,6 +12,8 @@ #include "gfxFT2Utils.h" #include "gfxPlatform.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/ContentParent.h" #include "mozilla/Preferences.h" #include "mozilla/Sprintf.h" #include "mozilla/TimeStamp.h" @@ -22,10 +24,12 @@ #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" #include "nsCharSeparatedTokenizer.h" +#include "nsXULAppAPI.h" #include "mozilla/gfx/HelpersCairo.h" #include +#include #ifdef MOZ_WIDGET_GTK #include @@ -36,10 +40,18 @@ #include "mozilla/X11Util.h" #endif +#ifdef MOZ_CONTENT_SANDBOX +#include "mozilla/SandboxBrokerPolicyFactory.h" +#include "mozilla/SandboxSettings.h" +#endif + using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::unicode; +using mozilla::dom::SystemFontListEntry; +using mozilla::dom::FontPatternListEntry; + #ifndef FC_POSTSCRIPT_NAME #define FC_POSTSCRIPT_NAME "postscriptname" /* String */ #endif @@ -1205,6 +1217,25 @@ gfxFontconfigFontFamily::~gfxFontconfigFontFamily() MOZ_ASSERT(NS_IsMainThread()); } +template +void +gfxFontconfigFontFamily::AddFacesToFontList(Func aAddPatternFunc) +{ + if (HasStyles()) { + for (auto& fe : mAvailableFonts) { + if (!fe) { + continue; + } + auto fce = static_cast(fe.get()); + aAddPatternFunc(fce->GetPattern(), mContainsAppFonts); + } + } else { + for (auto& pat : mFontPatterns) { + aAddPatternFunc(pat, mContainsAppFonts); + } + } +} + gfxFontconfigFont::gfxFontconfigFont(const RefPtr& aUnscaledFont, cairo_scaled_font_t *aScaledFont, FcPattern *aPattern, @@ -1244,18 +1275,20 @@ gfxFcPlatformFontList::gfxFcPlatformFontList() , mLastConfig(nullptr) , mAlwaysUseFontconfigGenerics(true) { - // if the rescan interval is set, start the timer - int rescanInterval = FcConfigGetRescanInterval(nullptr); - if (rescanInterval) { - mLastConfig = FcConfigGetCurrent(); - NS_NewTimerWithFuncCallback(getter_AddRefs(mCheckFontUpdatesTimer), - CheckFontUpdates, - this, - (rescanInterval + 1) * 1000, - nsITimer::TYPE_REPEATING_SLACK, - "gfxFcPlatformFontList::gfxFcPlatformFontList"); - if (!mCheckFontUpdatesTimer) { - NS_WARNING("Failure to create font updates timer"); + if (XRE_IsParentProcess()) { + // if the rescan interval is set, start the timer + int rescanInterval = FcConfigGetRescanInterval(nullptr); + if (rescanInterval) { + mLastConfig = FcConfigGetCurrent(); + NS_NewTimerWithFuncCallback(getter_AddRefs(mCheckFontUpdatesTimer), + CheckFontUpdates, + this, + (rescanInterval + 1) * 1000, + nsITimer::TYPE_REPEATING_SLACK, + "gfxFcPlatformFontList::gfxFcPlatformFontList"); + if (!mCheckFontUpdatesTimer) { + NS_WARNING("Failure to create font updates timer"); + } } } @@ -1273,14 +1306,15 @@ gfxFcPlatformFontList::~gfxFcPlatformFontList() } void -gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet, bool aAppFonts) +gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet, + const SandboxPolicy* aPolicy, + bool aAppFonts) { // This iterates over the fonts in a font set and adds in gfxFontFamily - // objects for each family. The patterns for individual fonts are not - // copied here. When a family is actually used, the fonts in the family - // are enumerated and the patterns copied. Note that we're explicitly - // excluding non-scalable fonts such as X11 bitmap fonts, which - // Chrome Skia/Webkit code does also. + // objects for each family. Individual gfxFontEntry objects for each face + // are not created here; the patterns are just stored in the family. When + // a family is actually used, it will be populated with gfxFontEntry + // records and the patterns moved to those. if (!aFontSet) { NS_WARNING("AddFontSetFamilies called with a null font set."); @@ -1291,95 +1325,213 @@ gfxFcPlatformFontList::AddFontSetFamilies(FcFontSet* aFontSet, bool aAppFonts) RefPtr fontFamily; nsAutoString familyName; for (int f = 0; f < aFontSet->nfont; f++) { - FcPattern* font = aFontSet->fonts[f]; + FcPattern* pattern = aFontSet->fonts[f]; - // get canonical name - uint32_t cIndex = FindCanonicalNameIndex(font, FC_FAMILYLANG); - FcChar8* canonical = nullptr; - FcPatternGetString(font, FC_FAMILY, cIndex, &canonical); - if (!canonical) { + // Skip any fonts that aren't readable for us (e.g. due to restrictive + // file ownership/permissions). + FcChar8* path; + if (FcPatternGetString(pattern, FC_FILE, 0, &path) != FcResultMatch) { + continue; + } + if (access(reinterpret_cast(path), F_OK | R_OK) != 0) { continue; } - // same as the last one? no need to add a new family, skip - if (FcStrCmp(canonical, lastFamilyName) != 0) { - lastFamilyName = canonical; +#ifdef MOZ_CONTENT_SANDBOX + // Skip any fonts that will be blocked by the content-process sandbox + // policy. + if (aPolicy && !(aPolicy->Lookup(reinterpret_cast(path)) & + SandboxBroker::Perms::MAY_READ)) { + continue; + } +#endif - // add new family if one doesn't already exist - familyName.Truncate(); - AppendUTF8toUTF16(ToCharPtr(canonical), familyName); - nsAutoString keyName(familyName); - ToLowerCase(keyName); + AddPatternToFontList(pattern, lastFamilyName, + familyName, fontFamily, aAppFonts); + } +} - fontFamily = static_cast - (mFontFamilies.GetWeak(keyName)); - if (!fontFamily) { - fontFamily = new gfxFontconfigFontFamily(familyName); - mFontFamilies.Put(keyName, fontFamily); - } - // Record if the family contains fonts from the app font set - // (in which case we won't rely on fontconfig's charmap, due to - // bug 1276594). - if (aAppFonts) { - fontFamily->SetFamilyContainsAppFonts(true); - } +void +gfxFcPlatformFontList::AddPatternToFontList(FcPattern* aFont, + FcChar8*& aLastFamilyName, + nsAString& aFamilyName, + RefPtr& aFontFamily, + bool aAppFonts) +{ + // get canonical name + uint32_t cIndex = FindCanonicalNameIndex(aFont, FC_FAMILYLANG); + FcChar8* canonical = nullptr; + FcPatternGetString(aFont, FC_FAMILY, cIndex, &canonical); + if (!canonical) { + return; + } - // Add pointers to other localized family names. Most fonts - // only have a single name, so the first call to GetString - // will usually not match - FcChar8* otherName; - int n = (cIndex == 0 ? 1 : 0); - while (FcPatternGetString(font, FC_FAMILY, n, &otherName) == FcResultMatch) { - NS_ConvertUTF8toUTF16 otherFamilyName(ToCharPtr(otherName)); - AddOtherFamilyName(fontFamily, otherFamilyName); - n++; - if (n == int(cIndex)) { - n++; // skip over canonical name - } - } + // same as the last one? no need to add a new family, skip + if (FcStrCmp(canonical, aLastFamilyName) != 0) { + aLastFamilyName = canonical; + + // add new family if one doesn't already exist + aFamilyName.Truncate(); + AppendUTF8toUTF16(ToCharPtr(canonical), aFamilyName); + nsAutoString keyName(aFamilyName); + ToLowerCase(keyName); + + aFontFamily = static_cast + (mFontFamilies.GetWeak(keyName)); + if (!aFontFamily) { + aFontFamily = new gfxFontconfigFontFamily(aFamilyName); + mFontFamilies.Put(keyName, aFontFamily); + } + // Record if the family contains fonts from the app font set + // (in which case we won't rely on fontconfig's charmap, due to + // bug 1276594). + if (aAppFonts) { + aFontFamily->SetFamilyContainsAppFonts(true); } - NS_ASSERTION(fontFamily, "font must belong to a font family"); - fontFamily->AddFontPattern(font); + // Add pointers to other localized family names. Most fonts + // only have a single name, so the first call to GetString + // will usually not match + FcChar8* otherName; + int n = (cIndex == 0 ? 1 : 0); + while (FcPatternGetString(aFont, FC_FAMILY, n, &otherName) == + FcResultMatch) { + NS_ConvertUTF8toUTF16 otherFamilyName(ToCharPtr(otherName)); + AddOtherFamilyName(aFontFamily, otherFamilyName); + n++; + if (n == int(cIndex)) { + n++; // skip over canonical name + } + } + } - // map the psname, fullname ==> font family for local font lookups - nsAutoString psname, fullname; - GetFaceNames(font, familyName, psname, fullname); - if (!psname.IsEmpty()) { - ToLowerCase(psname); - mLocalNames.Put(psname, font); - } - if (!fullname.IsEmpty()) { - ToLowerCase(fullname); - mLocalNames.Put(fullname, font); - } + MOZ_ASSERT(aFontFamily, "font must belong to a font family"); + aFontFamily->AddFontPattern(aFont); + + // map the psname, fullname ==> font family for local font lookups + nsAutoString psname, fullname; + GetFaceNames(aFont, aFamilyName, psname, fullname); + if (!psname.IsEmpty()) { + ToLowerCase(psname); + mLocalNames.Put(psname, aFont); + } + if (!fullname.IsEmpty()) { + ToLowerCase(fullname); + mLocalNames.Put(fullname, aFont); } } nsresult gfxFcPlatformFontList::InitFontListForPlatform() { - mLastConfig = FcConfigGetCurrent(); +#ifdef MOZ_BUNDLED_FONTS + ActivateBundledFonts(); +#endif mLocalNames.Clear(); mFcSubstituteCache.Clear(); - // iterate over available fonts - FcFontSet* systemFonts = FcConfigGetFonts(nullptr, FcSetSystem); - AddFontSetFamilies(systemFonts, /* aAppFonts = */ false); mAlwaysUseFontconfigGenerics = PrefFontListsUseOnlyGenerics(); - -#ifdef MOZ_BUNDLED_FONTS - ActivateBundledFonts(); - FcFontSet* appFonts = FcConfigGetFonts(nullptr, FcSetApplication); - AddFontSetFamilies(appFonts, /* aAppFonts = */ true); -#endif - mOtherFamilyNamesInitialized = true; + if (XRE_IsContentProcess()) { + // Content process: use the font list passed from the chrome process, + // because we can't rely on fontconfig in the presence of sandboxing; + // it may report fonts that we can't actually access. + + FcChar8* lastFamilyName = (FcChar8*)""; + RefPtr fontFamily; + nsAutoString familyName; + + // Get font list that was passed during XPCOM startup + // or in an UpdateFontList message. + auto& fontList = dom::ContentChild::GetSingleton()->SystemFontList(); + + for (SystemFontListEntry& fle : fontList) { + MOZ_ASSERT(fle.type() == + SystemFontListEntry::Type::TFontPatternListEntry); + FontPatternListEntry& fpe(fle); + FcPattern* pattern = + FcNameParse((const FcChar8*)fpe.pattern().get()); + AddPatternToFontList(pattern, lastFamilyName, familyName, + fontFamily, fpe.appFontFamily()); + FcPatternDestroy(pattern); + } + + LOG_FONTLIST(("got font list from chrome process: " + "%u faces in %u families", + (unsigned)fontList.Length(), mFontFamilies.Count())); + + fontList.Clear(); + + return NS_OK; + } + + mLastConfig = FcConfigGetCurrent(); + + UniquePtr policy; + +#ifdef MOZ_CONTENT_SANDBOX + // Create a temporary SandboxPolicy to check font paths; use a fake PID + // to avoid picking up any PID-specific rules by accident. + SandboxBrokerPolicyFactory policyFactory; + if (GetEffectiveContentSandboxLevel() > 0 && + !PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) { + policy = policyFactory.GetContentPolicy(-1, false); + } +#endif + + // iterate over available fonts + FcFontSet* systemFonts = FcConfigGetFonts(nullptr, FcSetSystem); + AddFontSetFamilies(systemFonts, policy.get(), /* aAppFonts = */ false); + +#ifdef MOZ_BUNDLED_FONTS + FcFontSet* appFonts = FcConfigGetFonts(nullptr, FcSetApplication); + AddFontSetFamilies(appFonts, policy.get(), /* aAppFonts = */ true); +#endif + return NS_OK; } +void +gfxFcPlatformFontList::ReadSystemFontList( + InfallibleTArray* retValue) +{ + // Fontconfig versions below 2.9 drop the FC_FILE element in FcNameUnparse + // (see https://bugs.freedesktop.org/show_bug.cgi?id=26718), so when using + // an older version, we manually append it to the unparsed pattern. + if (FcGetVersion() < 20900) { + for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) { + auto family = + static_cast(iter.Data().get()); + family->AddFacesToFontList([&](FcPattern* aPat, bool aAppFonts) { + char* s = (char*)FcNameUnparse(aPat); + nsAutoCString patternStr(s); + free(s); + if (FcResultMatch == + FcPatternGetString(aPat, FC_FILE, 0, (FcChar8**)&s)) { + patternStr.Append(":file="); + patternStr.Append(s); + } + retValue->AppendElement(FontPatternListEntry(patternStr, + aAppFonts)); + }); + } + } else { + for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) { + auto family = + static_cast(iter.Data().get()); + family->AddFacesToFontList([&](FcPattern* aPat, bool aAppFonts) { + char* s = (char*)FcNameUnparse(aPat); + nsDependentCString patternStr(s); + retValue->AppendElement(FontPatternListEntry(patternStr, + aAppFonts)); + free(s); + }); + } + } +} + // For displaying the fontlist in UI, use explicit call to FcFontList. Using // FcFontList results in the list containing the localized names as dictated // by system defaults. @@ -1978,6 +2130,10 @@ gfxFcPlatformFontList::PrefFontListsUseOnlyGenerics() /* static */ void gfxFcPlatformFontList::CheckFontUpdates(nsITimer *aTimer, void *aThis) { + // A content process is not supposed to check this directly; + // it will be notified by the parent when the font list changes. + MOZ_ASSERT(XRE_IsParentProcess()); + // check for font updates FcInitBringUptoDate(); @@ -1987,6 +2143,8 @@ gfxFcPlatformFontList::CheckFontUpdates(nsITimer *aTimer, void *aThis) if (current != pfl->GetLastConfig()) { pfl->UpdateFontList(); pfl->ForceGlobalReflow(); + + mozilla::dom::ContentParent::NotifyUpdatedFonts(); } } diff --git a/gfx/thebes/gfxFcPlatformFontList.h b/gfx/thebes/gfxFcPlatformFontList.h index a54db670d8bd..94e074fc56fd 100644 --- a/gfx/thebes/gfxFcPlatformFontList.h +++ b/gfx/thebes/gfxFcPlatformFontList.h @@ -21,6 +21,16 @@ #include #include +#ifdef MOZ_CONTENT_SANDBOX +#include "mozilla/SandboxBroker.h" +#endif + +namespace mozilla { + namespace dom { + class SystemFontListEntry; + }; +}; + template <> class nsAutoRefTraits : public nsPointerRefTraits { @@ -182,6 +192,9 @@ public: mForceScalable(false) { } + template + void AddFacesToFontList(Func aAddPatternFunc); + void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override; // Families are constructed initially with just references to patterns. @@ -254,6 +267,8 @@ public: const nsACString& aGenericFamily, nsTArray& aListOfFonts) override; + void ReadSystemFontList( + InfallibleTArray* retValue); gfxFontEntry* LookupLocalFont(const nsAString& aFontName, uint16_t aWeight, @@ -294,9 +309,23 @@ public: protected: virtual ~gfxFcPlatformFontList(); +#ifdef MOZ_CONTENT_SANDBOX + typedef mozilla::SandboxBroker::Policy SandboxPolicy; +#else + // Dummy type just so we can still have a SandboxPolicy* parameter. + struct SandboxPolicy {}; +#endif + // Add all the font families found in a font set. // aAppFonts indicates whether this is the system or application fontset. - void AddFontSetFamilies(FcFontSet* aFontSet, bool aAppFonts); + void AddFontSetFamilies(FcFontSet* aFontSet, const SandboxPolicy* aPolicy, + bool aAppFonts); + + // Helper for above, to add a single font pattern. + void AddPatternToFontList(FcPattern* aFont, FcChar8*& aLastFamilyName, + nsAString& aFamilyName, + RefPtr& aFontFamily, + bool aAppFonts); // figure out which families fontconfig maps a generic to // (aGeneric assumed already lowercase) diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index 7df8995b027e..89e4d9a72919 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -59,7 +59,6 @@ gfxCharacterMap::NotifyReleased() gfxFontEntry::gfxFontEntry() : mStyle(NS_FONT_STYLE_NORMAL), mFixedPitch(false), - mIsValid(true), mIsBadUnderlineFont(false), mIsUserFontContainer(false), mIsDataUserFont(false), @@ -98,7 +97,6 @@ gfxFontEntry::gfxFontEntry() : gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) : mName(aName), mStyle(NS_FONT_STYLE_NORMAL), mFixedPitch(false), - mIsValid(true), mIsBadUnderlineFont(false), mIsUserFontContainer(false), mIsDataUserFont(false), diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 11e12596e288..35a4220ae7ed 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -349,7 +349,6 @@ public: uint8_t mStyle : 2; // italic/oblique bool mFixedPitch : 1; - bool mIsValid : 1; bool mIsBadUnderlineFont : 1; bool mIsUserFontContainer : 1; // userfont entry bool mIsDataUserFont : 1; // platform font entry (data) diff --git a/gfx/thebes/gfxImageSurface.cpp b/gfx/thebes/gfxImageSurface.cpp index fe236892b8c0..96148312c32c 100644 --- a/gfx/thebes/gfxImageSurface.cpp +++ b/gfx/thebes/gfxImageSurface.cpp @@ -279,7 +279,8 @@ gfxImageSurface::CopyFrom (SourceSurface *aSurface) return false; } - CopyForStride(mData, data->GetData(), size, mStride, data->Stride()); + DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ); + CopyForStride(mData, map.GetData(), size, mStride, map.GetStride()); return true; } @@ -319,7 +320,8 @@ gfxImageSurface::CopyTo(SourceSurface *aSurface) { return false; } - CopyForStride(data->GetData(), mData, size, data->Stride(), mStride); + DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ_WRITE); + CopyForStride(map.GetData(), mData, size, map.GetStride(), mStride); return true; } diff --git a/gfx/thebes/gfxMacPlatformFontList.h b/gfx/thebes/gfxMacPlatformFontList.h index df2ba3638e86..b26ef7589fa9 100644 --- a/gfx/thebes/gfxMacPlatformFontList.h +++ b/gfx/thebes/gfxMacPlatformFontList.h @@ -159,8 +159,8 @@ public: kTextSizeSystemFontFamily = 2, // name of 'system' font at text sizes kDisplaySizeSystemFontFamily = 3 // 'system' font at display sizes }; - void GetSystemFontFamilyList( - InfallibleTArray* aList); + void ReadSystemFontList( + InfallibleTArray* aList); protected: gfxFontFamily* diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm index cf20c2a9f321..0f6dc1f6b5ea 100644 --- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -64,6 +64,7 @@ #include "gfxFontConstants.h" #include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/ContentParent.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Preferences.h" #include "mozilla/Sprintf.h" @@ -76,6 +77,7 @@ using namespace mozilla; using namespace mozilla::gfx; +using mozilla::dom::SystemFontListEntry; using mozilla::dom::FontFamilyListEntry; // indexes into the NSArray objects that the Cocoa font manager returns @@ -987,12 +989,17 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() : } } - ::CFNotificationCenterAddObserver(::CFNotificationCenterGetLocalCenter(), - this, - RegisteredFontsChangedNotificationCallback, - kCTFontManagerRegisteredFontsChangedNotification, - 0, - CFNotificationSuspensionBehaviorDeliverImmediately); + // Only the parent process listens for OS font-changed notifications; + // after rebuilding its list, it will update the content processes. + if (XRE_IsParentProcess()) { + ::CFNotificationCenterAddObserver( + ::CFNotificationCenterGetLocalCenter(), + this, + RegisteredFontsChangedNotificationCallback, + kCTFontManagerRegisteredFontsChangedNotification, + 0, + CFNotificationSuspensionBehaviorDeliverImmediately); + } // cache this in a static variable so that MacOSFontFamily objects // don't have to repeatedly look it up @@ -1001,10 +1008,13 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() : gfxMacPlatformFontList::~gfxMacPlatformFontList() { - ::CFNotificationCenterRemoveObserver(::CFNotificationCenterGetLocalCenter(), - this, - kCTFontManagerRegisteredFontsChangedNotification, - 0); + if (XRE_IsParentProcess()) { + ::CFNotificationCenterRemoveObserver( + ::CFNotificationCenterGetLocalCenter(), + this, + kCTFontManagerRegisteredFontsChangedNotification, + 0); + } if (mDefaultFont) { ::CFRelease(mDefaultFont); @@ -1056,8 +1066,8 @@ gfxMacPlatformFontList::AddFamily(CFStringRef aFamily) } void -gfxMacPlatformFontList::GetSystemFontFamilyList( - InfallibleTArray* aList) +gfxMacPlatformFontList::ReadSystemFontList( + InfallibleTArray* aList) { // Note: We rely on the records for mSystemTextFontFamilyName and // mSystemDisplayFontFamilyName (if present) being *before* the main @@ -1099,32 +1109,31 @@ gfxMacPlatformFontList::InitFontListForPlatform() // Content process: use font list passed from the chrome process via // the GetXPCOMProcessAttributes message, because it's much faster than // querying Core Text again in the child. - mozilla::dom::ContentChild* cc = - mozilla::dom::ContentChild::GetSingleton(); - for (auto f : cc->SystemFontFamilyList()) { - switch (f.entryType()) { + auto& fontList = dom::ContentChild::GetSingleton()->SystemFontList(); + for (SystemFontListEntry& fle : fontList) { + MOZ_ASSERT(fle.type() == + SystemFontListEntry::Type::TFontFamilyListEntry); + FontFamilyListEntry& ffe(fle); + switch (ffe.entryType()) { case kStandardFontFamily: - AddFamily(f.familyName(), false); + AddFamily(ffe.familyName(), false); break; case kHiddenSystemFontFamily: - AddFamily(f.familyName(), true); + AddFamily(ffe.familyName(), true); break; case kTextSizeSystemFontFamily: - mSystemTextFontFamilyName = f.familyName(); + mSystemTextFontFamilyName = ffe.familyName(); break; case kDisplaySizeSystemFontFamily: - mSystemDisplayFontFamilyName = f.familyName(); + mSystemDisplayFontFamilyName = ffe.familyName(); mUseSizeSensitiveSystemFont = true; break; } } - // The ContentChild doesn't need the font list any longer. - cc->SystemFontFamilyList().Clear(); - } - - // If this is the chrome process, or if for some reason we failed to get - // a usable list above, get the available fonts from Core Text. - if (!mFontFamilies.Count()) { + fontList.Clear(); + } else { + // We're not a content process, so get the available fonts directly + // from Core Text. InitSystemFontNames(); CFArrayRef familyNames = CTFontManagerCopyAvailableFontFamilyNames(); for (NSString* familyName in (NSArray*)familyNames) { @@ -1343,6 +1352,8 @@ gfxMacPlatformFontList::RegisteredFontsChangedNotificationCallback(CFNotificatio // modify a preference that will trigger reflow everywhere fl->ForceGlobalReflow(); + + mozilla::dom::ContentParent::NotifyUpdatedFonts(); } gfxFontEntry* @@ -1521,7 +1532,7 @@ gfxMacPlatformFontList::MakePlatformFont(const nsAString& aFontName, ::CFRelease(fontRef); // if succeeded and font cmap is good, return the new font - if (newFontEntry->mIsValid && NS_SUCCEEDED(newFontEntry->ReadCMAP())) { + if (NS_SUCCEEDED(newFontEntry->ReadCMAP())) { return newFontEntry.release(); } diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 9d7191851cdb..c000eac0ca1a 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -64,7 +64,7 @@ BackendTypeBit(BackendType b) } // namespace gfx namespace dom { -class FontFamilyListEntry; +class SystemFontListEntry; } } // namespace mozilla @@ -337,12 +337,12 @@ public: nsTArray& aListOfFonts); /** - * Fill aFontFamilies with a list of FontFamilyListEntry records for the + * Fill aFontList with a list of SystemFontListEntry records for the * available fonts on the platform; used to pass the list from chrome to - * content process. Currently implemented only on MacOSX. + * content process. Currently implemented only on MacOSX and Linux. */ - virtual void GetSystemFontFamilyList( - InfallibleTArray* aFontFamilies) + virtual void ReadSystemFontList( + InfallibleTArray* aFontList) { } /** diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index aef3e484b23c..6a8a61f74e7c 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -17,6 +17,7 @@ #include "nsUnicharUtils.h" #include "nsUnicodeRange.h" #include "nsUnicodeProperties.h" +#include "nsXULAppAPI.h" #include "mozilla/Attributes.h" #include "mozilla/Likely.h" @@ -25,6 +26,7 @@ #include "mozilla/Preferences.h" #include "mozilla/Telemetry.h" #include "mozilla/TimeStamp.h" +#include "mozilla/dom/ContentParent.h" #include "mozilla/gfx/2D.h" #include @@ -200,8 +202,12 @@ gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames) NS_ADDREF(gFontListPrefObserver); Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs); - Preferences::RegisterCallback(FontWhitelistPrefChanged, - kFontSystemWhitelistPref); + // Only the parent process listens for whitelist changes; it will then + // notify its children to rebuild their font lists. + if (XRE_IsParentProcess()) { + Preferences::RegisterCallback(FontWhitelistPrefChanged, + kFontSystemWhitelistPref); + } RegisterStrongMemoryReporter(new MemoryReporter()); } @@ -212,11 +218,23 @@ gfxPlatformFontList::~gfxPlatformFontList() ClearLangGroupPrefFonts(); NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer"); Preferences::RemoveObservers(gFontListPrefObserver, kObservedPrefs); - Preferences::UnregisterCallback(FontWhitelistPrefChanged, - kFontSystemWhitelistPref); + if (XRE_IsParentProcess()) { + Preferences::UnregisterCallback(FontWhitelistPrefChanged, + kFontSystemWhitelistPref); + } NS_RELEASE(gFontListPrefObserver); } +/* static */ +void +gfxPlatformFontList::FontWhitelistPrefChanged(const char *aPref, + void *aClosure) +{ + MOZ_ASSERT(XRE_IsParentProcess()); + gfxPlatformFontList::PlatformFontList()->UpdateFontList(); + mozilla::dom::ContentParent::NotifyUpdatedFonts(); +} + // number of CSS generic font families const uint32_t kNumGenerics = 5; @@ -730,7 +748,8 @@ gfxPlatformFontList::FindAndAddFamilies(const nsAString& aFamily, if (!familyEntry && !mOtherFamilyNamesInitialized && !IsASCII(aFamily)) { InitOtherFamilyNames(!(aFlags & FindFamiliesFlags::eForceOtherFamilyNamesLoading)); familyEntry = mOtherFamilyNames.GetWeak(key); - if (!familyEntry && !mOtherFamilyNamesInitialized) { + if (!familyEntry && !mOtherFamilyNamesInitialized && + !(aFlags & FindFamiliesFlags::eNoAddToNamesMissedWhenSearching)) { // localized family names load timed out, add name to list of // names to check after localized names are loaded if (!mOtherNamesMissed) { @@ -1559,7 +1578,8 @@ gfxPlatformFontList::CleanupLoader() if (mOtherNamesMissed) { for (auto it = mOtherNamesMissed->Iter(); !it.Done(); it.Next()) { if (FindFamily(it.Get()->GetKey(), - FindFamiliesFlags::eForceOtherFamilyNamesLoading)) { + (FindFamiliesFlags::eForceOtherFamilyNamesLoading | + FindFamiliesFlags::eNoAddToNamesMissedWhenSearching))) { forceReflow = true; ForceGlobalReflow(); break; diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 4e4a7f249bd3..9358ebd74440 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -150,7 +150,10 @@ public: // family" names to add to the font list. This is used to avoid // a recursive search when using FindFamily to find a potential base // family name for a styled variant. - eNoSearchForLegacyFamilyNames = 1 << 1 + eNoSearchForLegacyFamilyNames = 1 << 1, + + // If set, FindAndAddFamilies will not add a missing entry to mOtherNamesMissed + eNoAddToNamesMissedWhenSearching = 1 << 2 }; // Find family(ies) matching aFamily and append to the aOutput array @@ -280,9 +283,7 @@ public: // Returns true if the font family whitelist is not empty. bool IsFontFamilyWhitelistActive(); - static void FontWhitelistPrefChanged(const char *aPref, void *aClosure) { - gfxPlatformFontList::PlatformFontList()->UpdateFontList(); - } + static void FontWhitelistPrefChanged(const char *aPref, void *aClosure); bool AddWithLegacyFamilyName(const nsAString& aLegacyName, gfxFontEntry* aFontEntry); diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 64773ebbfb94..cd46dc26d73a 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -65,6 +65,7 @@ using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::unicode; +using mozilla::dom::SystemFontListEntry; #if (MOZ_WIDGET_GTK == 2) static cairo_user_data_key_t cairo_gdk_drawable_key; @@ -249,6 +250,13 @@ gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, } } +void +gfxPlatformGtk::ReadSystemFontList( + InfallibleTArray* retValue) +{ + gfxFcPlatformFontList::PlatformFontList()->ReadSystemFontList(retValue); +} + gfxPlatformFontList* gfxPlatformGtk::CreatePlatformFontList() { diff --git a/gfx/thebes/gfxPlatformGtk.h b/gfx/thebes/gfxPlatformGtk.h index bd1a59593934..bc111782055a 100644 --- a/gfx/thebes/gfxPlatformGtk.h +++ b/gfx/thebes/gfxPlatformGtk.h @@ -22,6 +22,12 @@ struct _XDisplay; typedef struct _XDisplay Display; #endif // MOZ_X11 +namespace mozilla { + namespace dom { + class SystemFontListEntry; + }; +}; + class gfxPlatformGtk : public gfxPlatform { public: gfxPlatformGtk(); @@ -31,6 +37,9 @@ public: return (gfxPlatformGtk*) gfxPlatform::GetPlatform(); } + void ReadSystemFontList( + InfallibleTArray* retValue) override; + virtual already_AddRefed CreateOffscreenSurface(const IntSize& aSize, gfxImageFormat aFormat) override; diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp index 95d0ee8ba33d..b3af8c3329d4 100644 --- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -30,7 +30,7 @@ using namespace mozilla; using namespace mozilla::gfx; -using mozilla::dom::FontFamilyListEntry; +using mozilla::dom::SystemFontListEntry; // cribbed from CTFontManager.h enum { @@ -113,11 +113,10 @@ gfxPlatformMac::CreatePlatformFontList() } void -gfxPlatformMac::GetSystemFontFamilyList( - InfallibleTArray* aFontFamilies) +gfxPlatformMac::ReadSystemFontList( + InfallibleTArray* aFontList) { - gfxMacPlatformFontList::PlatformFontList()-> - GetSystemFontFamilyList(aFontFamilies); + gfxMacPlatformFontList::PlatformFontList()->ReadSystemFontList(aFontList); } already_AddRefed diff --git a/gfx/thebes/gfxPlatformMac.h b/gfx/thebes/gfxPlatformMac.h index 285f5a8fb7c5..0ad04b83d078 100644 --- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -40,8 +40,8 @@ public: virtual gfxPlatformFontList* CreatePlatformFontList() override; void - GetSystemFontFamilyList(InfallibleTArray* - aFontFamilies) override; + ReadSystemFontList(InfallibleTArray* + aFontList) override; bool IsFontFormatSupported(uint32_t aFormatFlags) override; diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index d346ac7ef916..bcbc5fef1d71 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1298,10 +1298,11 @@ gfxUtils::DumpAsDataURI(DrawTarget* aDT, FILE* aFile) /* static */ nsCString gfxUtils::GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface) { - int32_t dataSize = aSourceSurface->GetSize().height * aSourceSurface->Stride(); + DataSourceSurface::ScopedMap map(aSourceSurface, DataSourceSurface::READ); + int32_t dataSize = aSourceSurface->GetSize().height * map.GetStride(); auto compressedData = MakeUnique(LZ4::maxCompressedSize(dataSize)); if (compressedData) { - int nDataSize = LZ4::compress((char*)aSourceSurface->GetData(), + int nDataSize = LZ4::compress((char*)map.GetData(), dataSize, compressedData.get()); if (nDataSize > 0) { @@ -1311,7 +1312,7 @@ gfxUtils::GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface) nsCString string(""); string.AppendPrintf("data:image/lz4bgra;base64,%i,%i,%i,", aSourceSurface->GetSize().width, - aSourceSurface->Stride(), + map.GetStride(), aSourceSurface->GetSize().height); string.Append(encodedImg); return string; diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index 2263ad7f2ab2..78dc67e478ea 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -244,7 +244,8 @@ VRManagerChild::RecvUpdateDisplayInfo(nsTArray&& aDisplayUpdates) * can resolve. This must happen even if no changes * to VRDisplays have been detected here. */ - nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(windowId); + nsGlobalWindowInner* window = + nsGlobalWindowInner::GetInnerWindowWithId(windowId); if (!window) { continue; } diff --git a/image/test/gtest/Common.cpp b/image/test/gtest/Common.cpp index 0ffbbafb53db..99d9363b9657 100644 --- a/image/test/gtest/Common.cpp +++ b/image/test/gtest/Common.cpp @@ -187,16 +187,15 @@ RectIsSolidColor(SourceSurface* aSurface, RefPtr dataSurface = aSurface->GetDataSurface(); ASSERT_TRUE_OR_RETURN(dataSurface != nullptr, false); - ASSERT_EQ_OR_RETURN(dataSurface->Stride(), surfaceSize.width * 4, false); - DataSourceSurface::ScopedMap mapping(dataSurface, DataSourceSurface::MapType::READ); ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false); + ASSERT_EQ_OR_RETURN(mapping.GetStride(), surfaceSize.width * 4, false); - uint8_t* data = dataSurface->GetData(); + uint8_t* data = mapping.GetData(); ASSERT_TRUE_OR_RETURN(data != nullptr, false); - int32_t rowLength = dataSurface->Stride(); + int32_t rowLength = mapping.GetStride(); for (int32_t row = rect.y; row < rect.YMost(); ++row) { for (int32_t col = rect.x; col < rect.XMost(); ++col) { int32_t i = row * rowLength + col * 4; @@ -268,16 +267,15 @@ RowHasPixels(SourceSurface* aSurface, RefPtr dataSurface = aSurface->GetDataSurface(); ASSERT_TRUE_OR_RETURN(dataSurface, false); - ASSERT_EQ_OR_RETURN(dataSurface->Stride(), surfaceSize.width * 4, false); - DataSourceSurface::ScopedMap mapping(dataSurface, DataSourceSurface::MapType::READ); ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false); + ASSERT_EQ_OR_RETURN(mapping.GetStride(), surfaceSize.width * 4, false); - uint8_t* data = dataSurface->GetData(); + uint8_t* data = mapping.GetData(); ASSERT_TRUE_OR_RETURN(data != nullptr, false); - int32_t rowLength = dataSurface->Stride(); + int32_t rowLength = mapping.GetStride(); for (int32_t col = 0; col < surfaceSize.width; ++col) { int32_t i = aRow * rowLength + col * 4; ASSERT_EQ_OR_RETURN(aPixels[col].mBlue, data[i + 0], false); diff --git a/js/public/Initialization.h b/js/public/Initialization.h index 4d45d010334c..e7a56771077e 100644 --- a/js/public/Initialization.h +++ b/js/public/Initialization.h @@ -13,7 +13,12 @@ namespace JS { namespace detail { -enum class InitState { Uninitialized = 0, Running, ShutDown }; +enum class InitState { + Uninitialized = 0, + Initializing, + Running, + ShutDown +}; /** * SpiderMonkey's initialization status is tracked here, and it controls things @@ -99,7 +104,7 @@ JS_InitWithFailureDiagnostic(void) inline bool JS_IsInitialized(void) { - return JS::detail::libraryInitState != JS::detail::InitState::Uninitialized; + return JS::detail::libraryInitState >= JS::detail::InitState::Running; } /** diff --git a/js/src/ds/MemoryProtectionExceptionHandler.cpp b/js/src/ds/MemoryProtectionExceptionHandler.cpp index 066b43929146..2f9112cc8c5d 100644 --- a/js/src/ds/MemoryProtectionExceptionHandler.cpp +++ b/js/src/ds/MemoryProtectionExceptionHandler.cpp @@ -521,15 +521,12 @@ struct ExceptionHandlerState /* Each Mach exception handler runs in its own thread. */ Thread handlerThread; - - /* Ensure that the exception handler thread is terminated before we quit. */ - ~ExceptionHandlerState() { MemoryProtectionExceptionHandler::uninstall(); } }; /* This choice of ID is arbitrary, but must not match our exception ID. */ static const mach_msg_id_t sIDQuit = 42; -static ExceptionHandlerState sMachExceptionState; +static ExceptionHandlerState* sMachExceptionState = nullptr; /* * The meat of our exception handler. This thread waits for an exception @@ -540,8 +537,8 @@ static void MachExceptionHandler() { kern_return_t ret; - MachExceptionParameters& current = sMachExceptionState.current; - MachExceptionParameters& previous = sMachExceptionState.previous; + MachExceptionParameters& current = sMachExceptionState->current; + MachExceptionParameters& previous = sMachExceptionState->previous; // We use the simplest kind of 64-bit exception message here. ExceptionRequest64 request = {}; @@ -668,7 +665,7 @@ TerminateMachExceptionHandlerThread() mach_msg_header_t msg; msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); msg.msgh_size = static_cast(sizeof(msg)); - msg.msgh_remote_port = sMachExceptionState.current.port; + msg.msgh_remote_port = sMachExceptionState->current.port; msg.msgh_local_port = MACH_PORT_NULL; msg.msgh_reserved = 0; msg.msgh_id = sIDQuit; @@ -676,7 +673,7 @@ TerminateMachExceptionHandlerThread() MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (ret == MACH_MSG_SUCCESS) - sMachExceptionState.handlerThread.join(); + sMachExceptionState->handlerThread.join(); else MOZ_CRASH("MachExceptionHandler: Handler thread failed to terminate!"); } @@ -685,17 +682,22 @@ bool MemoryProtectionExceptionHandler::install() { MOZ_ASSERT(!sExceptionHandlerInstalled); + MOZ_ASSERT(!sMachExceptionState); // If the exception handler is disabled, report success anyway. if (MemoryProtectionExceptionHandler::isDisabled()) return true; + sMachExceptionState = js_new(); + if (!sMachExceptionState) + return false; + kern_return_t ret; mach_port_t task = mach_task_self(); // Allocate a new exception port with receive rights. - sMachExceptionState.current = {}; - MachExceptionParameters& current = sMachExceptionState.current; + sMachExceptionState->current = {}; + MachExceptionParameters& current = sMachExceptionState->current; ret = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, ¤t.port); if (ret != KERN_SUCCESS) return false; @@ -709,7 +711,7 @@ MemoryProtectionExceptionHandler::install() } // Start the thread that will receive the messages from our exception port. - if (!sMachExceptionState.handlerThread.init(MachExceptionHandler)) { + if (!sMachExceptionState->handlerThread.init(MachExceptionHandler)) { mach_port_deallocate(task, current.port); current = {}; return false; @@ -721,8 +723,8 @@ MemoryProtectionExceptionHandler::install() current.flavor = THREAD_STATE_NONE; // Tell the task to use our exception handler, and save the previous one. - sMachExceptionState.previous = {}; - MachExceptionParameters& previous = sMachExceptionState.previous; + sMachExceptionState->previous = {}; + MachExceptionParameters& previous = sMachExceptionState->previous; mach_msg_type_number_t previousCount = 1; ret = task_swap_exception_ports(task, current.mask, current.port, current.behavior, current.flavor, &previous.mask, &previousCount, @@ -746,20 +748,25 @@ void MemoryProtectionExceptionHandler::uninstall() { if (sExceptionHandlerInstalled) { + MOZ_ASSERT(sMachExceptionState); + mach_port_t task = mach_task_self(); // Restore the previous exception handler. - MachExceptionParameters& previous = sMachExceptionState.previous; + MachExceptionParameters& previous = sMachExceptionState->previous; task_set_exception_ports(task, previous.mask, previous.port, previous.behavior, previous.flavor); TerminateMachExceptionHandlerThread(); // Release the Mach IPC port we used. - mach_port_deallocate(task, sMachExceptionState.current.port); + mach_port_deallocate(task, sMachExceptionState->current.port); - sMachExceptionState.current = {}; - sMachExceptionState.previous = {}; + sMachExceptionState->current = {}; + sMachExceptionState->previous = {}; + + js_delete(sMachExceptionState); + sMachExceptionState = nullptr; sExceptionHandlerInstalled = false; } diff --git a/js/src/jsutil.h b/js/src/jsutil.h index f4d44a840a0d..1ece05df3d7f 100644 --- a/js/src/jsutil.h +++ b/js/src/jsutil.h @@ -20,6 +20,7 @@ #include +#include "js/Initialization.h" #include "js/Utility.h" #include "js/Value.h" @@ -47,6 +48,16 @@ js_memcpy(void* dst_, const void* src_, size_t len) namespace js { +// An internal version of JS_IsInitialized() that returns whether SpiderMonkey +// is currently initialized or is in the process of being initialized. +inline bool +IsInitialized() +{ + using namespace JS::detail; + return libraryInitState == InitState::Initializing || + libraryInitState == InitState::Running; +} + template static inline void Reverse(T* beg, T* end) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 0f1d0be8efda..79842e404f04 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -236,7 +236,7 @@ class OffThreadState { char16_t* source; JS::TranscodeBuffer xdr; }; -static OffThreadState gOffThreadState; +static OffThreadState* gOffThreadState; bool OffThreadState::startIfIdle(JSContext* cx, ScriptKind kind, ScopedJSFreePtr& newSource) @@ -4501,7 +4501,7 @@ SyntaxParse(JSContext* cx, unsigned argc, Value* vp) static void OffThreadCompileScriptCallback(void* token, void* callbackData) { - gOffThreadState.markDone(token); + gOffThreadState->markDone(token); } static bool @@ -4578,7 +4578,7 @@ OffThreadCompileScript(JSContext* cx, unsigned argc, Value* vp) return false; } - if (!gOffThreadState.startIfIdle(cx, ScriptKind::Script, ownedChars)) { + if (!gOffThreadState->startIfIdle(cx, ScriptKind::Script, ownedChars)) { JS_ReportErrorASCII(cx, "called offThreadCompileScript without calling runOffThreadScript" " to receive prior off-thread compilation"); return false; @@ -4587,7 +4587,7 @@ OffThreadCompileScript(JSContext* cx, unsigned argc, Value* vp) if (!JS::CompileOffThread(cx, options, chars, length, OffThreadCompileScriptCallback, nullptr)) { - gOffThreadState.abandon(cx); + gOffThreadState->abandon(cx); return false; } @@ -4603,7 +4603,7 @@ runOffThreadScript(JSContext* cx, unsigned argc, Value* vp) if (OffThreadParsingMustWaitForGC(cx->runtime())) gc::FinishGC(cx); - void* token = gOffThreadState.waitUntilDone(cx, ScriptKind::Script); + void* token = gOffThreadState->waitUntilDone(cx, ScriptKind::Script); if (!token) { JS_ReportErrorASCII(cx, "called runOffThreadScript when no compilation is pending"); return false; @@ -4663,7 +4663,7 @@ OffThreadCompileModule(JSContext* cx, unsigned argc, Value* vp) return false; } - if (!gOffThreadState.startIfIdle(cx, ScriptKind::Module, ownedChars)) { + if (!gOffThreadState->startIfIdle(cx, ScriptKind::Module, ownedChars)) { JS_ReportErrorASCII(cx, "called offThreadCompileModule without receiving prior off-thread " "compilation"); return false; @@ -4672,7 +4672,7 @@ OffThreadCompileModule(JSContext* cx, unsigned argc, Value* vp) if (!JS::CompileOffThreadModule(cx, options, chars, length, OffThreadCompileScriptCallback, nullptr)) { - gOffThreadState.abandon(cx); + gOffThreadState->abandon(cx); return false; } @@ -4688,7 +4688,7 @@ FinishOffThreadModule(JSContext* cx, unsigned argc, Value* vp) if (OffThreadParsingMustWaitForGC(cx->runtime())) gc::FinishGC(cx); - void* token = gOffThreadState.waitUntilDone(cx, ScriptKind::Module); + void* token = gOffThreadState->waitUntilDone(cx, ScriptKind::Module); if (!token) { JS_ReportErrorASCII(cx, "called finishOffThreadModule when no compilation is pending"); return false; @@ -4765,16 +4765,16 @@ OffThreadDecodeScript(JSContext* cx, unsigned argc, Value* vp) return false; } - if (!gOffThreadState.startIfIdle(cx, ScriptKind::DecodeScript, mozilla::Move(loadBuffer))) { + if (!gOffThreadState->startIfIdle(cx, ScriptKind::DecodeScript, mozilla::Move(loadBuffer))) { JS_ReportErrorASCII(cx, "called offThreadDecodeScript without calling " "runOffThreadDecodedScript to receive prior off-thread compilation"); return false; } - if (!JS::DecodeOffThreadScript(cx, options, gOffThreadState.xdrBuffer(), 0, + if (!JS::DecodeOffThreadScript(cx, options, gOffThreadState->xdrBuffer(), 0, OffThreadCompileScriptCallback, nullptr)) { - gOffThreadState.abandon(cx); + gOffThreadState->abandon(cx); return false; } @@ -4790,7 +4790,7 @@ runOffThreadDecodedScript(JSContext* cx, unsigned argc, Value* vp) if (OffThreadParsingMustWaitForGC(cx->runtime())) gc::FinishGC(cx); - void* token = gOffThreadState.waitUntilDone(cx, ScriptKind::DecodeScript); + void* token = gOffThreadState->waitUntilDone(cx, ScriptKind::DecodeScript); if (!token) { JS_ReportErrorASCII(cx, "called runOffThreadDecodedScript when no compilation is pending"); return false; @@ -5673,7 +5673,7 @@ struct BufferStreamState } }; -static ExclusiveWaitableData bufferStreamState(mutexid::BufferStreamState); +static ExclusiveWaitableData* bufferStreamState; static void BufferStreamMain(BufferStreamJob* job) @@ -5691,7 +5691,7 @@ BufferStreamMain(BufferStreamJob* job) size_t delayMillis; size_t chunkSize; { - auto state = bufferStreamState.lock(); + auto state = bufferStreamState->lock(); shutdown = state->shutdown; delayMillis = state->delayMillis; chunkSize = state->chunkSize; @@ -5712,7 +5712,7 @@ BufferStreamMain(BufferStreamJob* job) byteOffset += chunkSize; } - auto state = bufferStreamState.lock(); + auto state = bufferStreamState->lock(); size_t jobIndex = 0; while (state->jobs[jobIndex].get() != job) jobIndex++; @@ -5741,7 +5741,7 @@ ConsumeBufferSource(JSContext* cx, JS::HandleObject obj, JS::MimeType, JS::Strea BufferStreamJob* jobPtr = job.get(); { - auto state = bufferStreamState.lock(); + auto state = bufferStreamState->lock(); MOZ_ASSERT(!state->shutdown); if (!state->jobs.append(Move(job))) return false; @@ -5766,7 +5766,7 @@ SetBufferStreamParams(JSContext* cx, unsigned argc, Value* vp) return false; { - auto state = bufferStreamState.lock(); + auto state = bufferStreamState->lock(); state->delayMillis = delayMillis; state->chunkSize = chunkSize; } @@ -5775,6 +5775,16 @@ SetBufferStreamParams(JSContext* cx, unsigned argc, Value* vp) return true; } +static void +ShutdownBufferStreams() +{ + auto state = bufferStreamState->lock(); + state->shutdown = true; + while (!state->jobs.empty()) + state.wait(/* jobs empty */); + state->jobs.clearAndFree(); +} + class SprintOptimizationTypeInfoOp : public JS::ForEachTrackedOptimizationTypeInfoOp { Sprinter* sp; @@ -8628,14 +8638,6 @@ main(int argc, char** argv, char** envp) { PreInit(); - auto shutdownBufferStreams = MakeScopeExit([] { - auto state = bufferStreamState.lock(); - state->shutdown = true; - while (!state->jobs.empty()) - state.wait(/* jobs empty */); - state->jobs.clearAndFree(); - }); - sArgc = argc; sArgv = argv; @@ -8928,8 +8930,24 @@ main(int argc, char** argv, char** envp) JS_AddInterruptCallback(cx, ShellInterruptCallback); JS::SetBuildIdOp(cx, ShellBuildId); JS::SetAsmJSCacheOps(cx, &asmJSCacheOps); + + bufferStreamState = + js_new>(mutexid::BufferStreamState); + if (!bufferStreamState) + return 1; + auto shutdownBufferStreams = MakeScopeExit([] { + ShutdownBufferStreams(); + js_delete(bufferStreamState); + }); JS::InitConsumeStreamCallback(cx, ConsumeBufferSource); + gOffThreadState = js_new(); + if (!gOffThreadState) + return 1; + auto deleteOffThreadState = MakeScopeExit([] { + js_delete(gOffThreadState); + }); + JS_SetNativeStackQuota(cx, gMaxStackSize); JS::dbg::SetDebuggerMallocSizeOf(cx, moz_malloc_size_of); diff --git a/js/src/threading/Mutex.cpp b/js/src/threading/Mutex.cpp index d419beab22d4..d38f60895d42 100644 --- a/js/src/threading/Mutex.cpp +++ b/js/src/threading/Mutex.cpp @@ -6,8 +6,7 @@ #include "threading/Mutex.h" -#include "js/Initialization.h" -#include "js/Utility.h" +#include "jsutil.h" using namespace js; @@ -31,6 +30,7 @@ js::Mutex::ShutDown() /* static */ js::Mutex::MutexVector& js::Mutex::heldMutexStack() { + MOZ_ASSERT(js::IsInitialized()); auto stack = HeldMutexStack.get(); if (!stack) { AutoEnterOOMUnsafeRegion oomUnsafe; @@ -45,11 +45,6 @@ js::Mutex::heldMutexStack() void js::Mutex::lock() { - if (!JS_IsInitialized()) { - MutexImpl::lock(); - return; - } - auto& stack = heldMutexStack(); if (!stack.empty()) { const Mutex& prev = *stack.back(); @@ -71,11 +66,6 @@ js::Mutex::lock() void js::Mutex::unlock() { - if (!JS_IsInitialized()) { - MutexImpl::unlock(); - return; - } - auto& stack = heldMutexStack(); MOZ_ASSERT(stack.back() == this); MutexImpl::unlock(); diff --git a/js/src/threading/Thread.h b/js/src/threading/Thread.h index 1c8a0e6b2ed8..d00842fc4a62 100644 --- a/js/src/threading/Thread.h +++ b/js/src/threading/Thread.h @@ -16,7 +16,8 @@ #include -#include "js/Utility.h" +#include "jsutil.h" + #include "threading/LockGuard.h" #include "threading/Mutex.h" #include "vm/MutexIDs.h" @@ -101,7 +102,9 @@ public: : idMutex_(mutexid::ThreadId) , id_(Id()) , options_(mozilla::Forward(options)) - { } + { + MOZ_ASSERT(js::IsInitialized()); + } // Start a thread of execution at functor |f| with parameters |args|. This // method will return false if thread creation fails. This Thread must not diff --git a/js/src/vm/Initialization.cpp b/js/src/vm/Initialization.cpp index 1b035a67e004..5d11b62428c0 100644 --- a/js/src/vm/Initialization.cpp +++ b/js/src/vm/Initialization.cpp @@ -82,6 +82,8 @@ JS::detail::InitWithFailureDiagnostic(bool isDebugBuild) MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(), "how do we have live runtimes before JS_Init?"); + libraryInitState = InitState::Initializing; + PRMJ_NowInit(); // The first invocation of `ProcessCreation` creates a temporary thread @@ -110,7 +112,7 @@ JS::detail::InitWithFailureDiagnostic(bool isDebugBuild) RETURN_IF_FAIL(js::jit::InitProcessExecutableMemory()); - MOZ_ALWAYS_TRUE(js::MemoryProtectionExceptionHandler::install()); + RETURN_IF_FAIL(js::MemoryProtectionExceptionHandler::install()); RETURN_IF_FAIL(js::jit::InitializeIon()); diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index e3272bca3012..0255f7ae0148 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -2118,7 +2118,7 @@ nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx) if (!console) return NS_OK; - nsGlobalWindow* globalWin = CurrentWindowOrNull(cx); + nsGlobalWindowInner* globalWin = CurrentWindowOrNull(cx); nsPIDOMWindowInner* win = globalWin ? globalWin->AsInner() : nullptr; const uint64_t innerWindowID = win ? win->WindowID() : 0; @@ -2338,7 +2338,7 @@ nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList, MOZ_ASSERT(global); // Don't allow doing this if the global is a Window - nsGlobalWindow* win; + nsGlobalWindowInner* win; if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, &global, win))) { return NS_ERROR_NOT_AVAILABLE; } diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index 30b841bffbcd..070152bdefc9 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -668,7 +668,7 @@ XPCJSContext::InterruptCallback(JSContext* cx) // Get the DOM window associated with the running script. If the script is // running in a non-DOM scope, we have to just let it keep running. RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); - RefPtr win = WindowOrNull(global); + RefPtr win = WindowOrNull(global); if (!win && IsSandbox(global)) { // If this is a sandbox associated with a DOMWindow via a // sandboxPrototype, use that DOMWindow. This supports GreaseMonkey diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index d76e38a133c8..2ac79f63dcf5 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -531,18 +531,18 @@ CompilationScope() return XPCJSRuntime::Get()->CompilationScope(); } -nsGlobalWindow* +nsGlobalWindowInner* WindowOrNull(JSObject* aObj) { MOZ_ASSERT(aObj); MOZ_ASSERT(!js::IsWrapper(aObj)); - nsGlobalWindow* win = nullptr; + nsGlobalWindowInner* win = nullptr; UNWRAP_NON_WRAPPER_OBJECT(Window, aObj, win); return win; } -nsGlobalWindow* +nsGlobalWindowInner* WindowGlobalOrNull(JSObject* aObj) { MOZ_ASSERT(aObj); @@ -551,7 +551,7 @@ WindowGlobalOrNull(JSObject* aObj) return WindowOrNull(glob); } -nsGlobalWindow* +nsGlobalWindowInner* AddonWindowOrNull(JSObject* aObj) { if (!IsInAddonScope(aObj)) @@ -571,7 +571,7 @@ AddonWindowOrNull(JSObject* aObj) return WindowOrNull(mainGlobal); } -nsGlobalWindow* +nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx) { JSObject* glob = JS::CurrentGlobalOrNull(cx); @@ -2238,7 +2238,7 @@ class XPCJSRuntimeStats : public JS::RuntimeStats extras->pathPrefix.AssignLiteral("explicit/js-non-window/zones/"); RootedObject global(cx, JS::GetRealmGlobalOrNull(realm)); if (global) { - RefPtr window; + RefPtr window; if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, global, window))) { // The global is a |window| object. Use the path prefix that // we should have already created for it. @@ -2278,7 +2278,7 @@ class XPCJSRuntimeStats : public JS::RuntimeStats Rooted realm(cx, JS::GetRealmForCompartment(c)); RootedObject global(cx, JS::GetRealmGlobalOrNull(realm)); if (global) { - RefPtr window; + RefPtr window; if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, global, window))) { // The global is a |window| object. Use the path prefix that // we should have already created for it. diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index ca9ce623224d..45ed2a7348de 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -27,7 +27,7 @@ #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/Preferences.h" -class nsGlobalWindow; +class nsGlobalWindowInner; class nsIPrincipal; class nsScriptNameSpaceManager; class nsIHandleReportCallback; @@ -483,14 +483,14 @@ NativeGlobal(JSObject* aObj); * If |aObj| is a window, returns the associated nsGlobalWindow. * Otherwise, returns null. */ -nsGlobalWindow* +nsGlobalWindowInner* WindowOrNull(JSObject* aObj); /** * If |aObj| has a window for a global, returns the associated nsGlobalWindow. * Otherwise, returns null. */ -nsGlobalWindow* +nsGlobalWindowInner* WindowGlobalOrNull(JSObject* aObj); /** @@ -498,14 +498,14 @@ WindowGlobalOrNull(JSObject* aObj); * live DOM Window, returns the associated nsGlobalWindow. Otherwise, returns * null. */ -nsGlobalWindow* +nsGlobalWindowInner* AddonWindowOrNull(JSObject* aObj); /** * If |cx| is in a compartment whose global is a window, returns the associated * nsGlobalWindow. Otherwise, returns null. */ -nsGlobalWindow* +nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx); void diff --git a/js/xpconnect/tests/unit/test_isModuleLoaded.js b/js/xpconnect/tests/unit/test_isModuleLoaded.js index a5430bb04c15..cf8598a0eafb 100644 --- a/js/xpconnect/tests/unit/test_isModuleLoaded.js +++ b/js/xpconnect/tests/unit/test_isModuleLoaded.js @@ -2,7 +2,7 @@ const Cu = Components.utils; function run_test() { // Existing module. - do_check_true(!Cu.isModuleLoaded("resource://gre/modules/NetUtil.jsm"), + do_check_true(Cu.isModuleLoaded("resource://gre/modules/NetUtil.jsm"), "isModuleLoaded returned correct value for non-loaded module"); Cu.import("resource://gre/modules/NetUtil.jsm"); do_check_true(Cu.isModuleLoaded("resource://gre/modules/NetUtil.jsm"), diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp index 620f1f678f51..65049691fda4 100644 --- a/js/xpconnect/wrappers/AccessCheck.cpp +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -129,7 +129,7 @@ IsFrameId(JSContext* cx, JSObject* obj, jsid idArg) MOZ_ASSERT(!js::IsWrapper(obj)); RootedId id(cx, idArg); - nsGlobalWindow* win = WindowOrNull(obj); + nsGlobalWindowInner* win = WindowOrNull(obj); if (!win) { return false; } diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index dc80d74c6fb1..197dd70970df 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -280,7 +280,7 @@ ReportWrapperDenial(JSContext* cx, HandleId id, WrapperDenialType type, const ch // Compute the current window id if any. uint64_t windowId = 0; - nsGlobalWindow* win = WindowGlobalOrNull(CurrentGlobalOrNull(cx)); + nsGlobalWindowInner* win = WindowGlobalOrNull(CurrentGlobalOrNull(cx)); if (win) windowId = win->WindowID(); @@ -1434,7 +1434,7 @@ IsXPCWNHolderClass(const JSClass* clasp) } // namespace XrayUtils -static nsGlobalWindow* +static nsGlobalWindowInner* AsWindow(JSContext* cx, JSObject* wrapper) { // We want to use our target object here, since we don't want to be @@ -1763,13 +1763,13 @@ DOMXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper, HandleObj // Check for indexed access on a window. uint32_t index = GetArrayIndexFromId(cx, id); if (IsArrayIndex(index)) { - nsGlobalWindow* win = AsWindow(cx, wrapper); + nsGlobalWindowInner* win = AsWindow(cx, wrapper); // Note: As() unwraps outer windows to get to the inner window. if (win) { nsCOMPtr subframe = win->IndexedGetter(index); if (subframe) { subframe->EnsureInnerWindow(); - nsGlobalWindow* global = nsGlobalWindow::Cast(subframe); + nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(subframe); JSObject* obj = global->FastGetGlobalJSObject(); if (MOZ_UNLIKELY(!obj)) { // It's gone? @@ -1835,7 +1835,7 @@ DOMXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flag AutoIdVector& props) { // Put the indexed properties for a window first. - nsGlobalWindow* win = AsWindow(cx, wrapper); + nsGlobalWindowInner* win = AsWindow(cx, wrapper); if (win) { uint32_t length = win->Length(); if (!props.reserve(props.length() + length)) { @@ -2131,7 +2131,7 @@ XrayWrapper::getPropertyDescriptor(JSContext* cx, HandleObject wra // named access. So we just handle it separately here. Note that this is // only relevant for CrossOriginXrayWrapper, which calls // getPropertyDescriptor from getOwnPropertyDescriptor. - nsGlobalWindow* win = nullptr; + nsGlobalWindowInner* win = nullptr; if (!desc.object() && JSID_IS_STRING(id) && (win = AsWindow(cx, wrapper))) @@ -2140,7 +2140,7 @@ XrayWrapper::getPropertyDescriptor(JSContext* cx, HandleObject wra if (!name.init(cx, JSID_TO_STRING(id))) return false; if (nsCOMPtr childDOMWin = win->GetChildWindow(name)) { - auto* cwin = nsGlobalWindow::Cast(childDOMWin); + auto* cwin = nsGlobalWindowOuter::Cast(childDOMWin); JSObject* childObj = cwin->FastGetGlobalJSObject(); if (MOZ_UNLIKELY(!childObj)) return xpc::Throw(cx, NS_ERROR_FAILURE); diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 4394516df7b3..be33cf990d91 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1222,7 +1222,7 @@ nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt, nsAutoPopupStatePusher popupStatePusher(openAbused, true); // Never permit dialogs from the beforeunload handler - nsGlobalWindow* globalWindow = nsGlobalWindow::Cast(window); + nsGlobalWindowOuter* globalWindow = nsGlobalWindowOuter::Cast(window); dialogsAreEnabled = globalWindow->AreDialogsEnabled(); nsGlobalWindow::TemporarilyDisableDialogs disableDialogs(globalWindow); diff --git a/layout/build/moz.build b/layout/build/moz.build index 188a3537aba7..64665b7ea808 100644 --- a/layout/build/moz.build +++ b/layout/build/moz.build @@ -37,7 +37,6 @@ LOCAL_INCLUDES += [ '/dom/filesystem', '/dom/geolocation', '/dom/html', - '/dom/json', '/dom/jsurl', '/dom/media', '/dom/offline', diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index b2e95c2e790b..5627c49873ea 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -75,7 +75,6 @@ #include "nsJSProtocolHandler.h" #include "nsScriptNameSpaceManager.h" #include "nsIControllerContext.h" -#include "nsJSON.h" #include "nsZipArchive.h" #include "mozilla/Attributes.h" #include "mozilla/dom/DOMException.h" @@ -627,7 +626,6 @@ NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID); NS_DEFINE_NAMED_CID(NS_DOMPARSER_CID); NS_DEFINE_NAMED_CID(NS_DOMSESSIONSTORAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_DOMLOCALSTORAGEMANAGER_CID); -NS_DEFINE_NAMED_CID(NS_DOMJSON_CID); NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID); NS_DEFINE_NAMED_CID(DOMREQUEST_SERVICE_CID); NS_DEFINE_NAMED_CID(QUOTAMANAGER_SERVICE_CID); @@ -886,7 +884,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = { { &kNS_XPCEXCEPTION_CID, false, nullptr, ExceptionConstructor }, { &kNS_DOMSESSIONSTORAGEMANAGER_CID, false, nullptr, SessionStorageManagerConstructor }, { &kNS_DOMLOCALSTORAGEMANAGER_CID, false, nullptr, LocalStorageManagerConstructor }, - { &kNS_DOMJSON_CID, false, nullptr, NS_NewJSON }, { &kNS_TEXTEDITOR_CID, false, nullptr, TextEditorConstructor }, { &kDOMREQUEST_SERVICE_CID, false, nullptr, DOMRequestServiceConstructor }, { &kQUOTAMANAGER_SERVICE_CID, false, nullptr, QuotaManagerServiceConstructor }, @@ -1013,7 +1010,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = { // Keeping the old ContractID for backward compatibility { "@mozilla.org/dom/storagemanager;1", &kNS_DOMLOCALSTORAGEMANAGER_CID }, { "@mozilla.org/dom/sessionStorage-manager;1", &kNS_DOMSESSIONSTORAGEMANAGER_CID }, - { "@mozilla.org/dom/json;1", &kNS_DOMJSON_CID }, { "@mozilla.org/editor/texteditor;1", &kNS_TEXTEDITOR_CID }, { DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID }, { QUOTAMANAGER_SERVICE_CONTRACTID, &kQUOTAMANAGER_SERVICE_CID }, diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index f134481bbda0..1e460d2e6bc6 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -416,7 +416,7 @@ load 571618-1.svg asserts(1) asserts-if(stylo,0-1) load 571975-1.html # bug 574889 load 571995.xhtml load 574958.xhtml -asserts(0-4) load 578977.html # bug 757305 +asserts(0-6) load 578977.html # bug 757305 load 580504-1.xhtml load 585598-1.xhtml load 586806-1.html diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index aa5f673a5fe4..df9c695a2e32 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -582,7 +582,6 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (layers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) { DisplayListClipState::AutoSaveRestore blendClip(aBuilder); - blendClip.ClearUpToASR(thisItemASR); thisItemList.AppendNewToTop( new (aBuilder) nsDisplayBlendMode(aBuilder, this, &thisItemList, layers.mLayers[i].mBlendMode, @@ -594,7 +593,6 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (needBlendContainer) { const ActiveScrolledRoot* containerASR = contASRTracker.GetContainerASR(); DisplayListClipState::AutoSaveRestore blendContainerClip(aBuilder); - blendContainerClip.ClearUpToASR(containerASR); aLists.BorderBackground()->AppendNewToTop( nsDisplayBlendContainer::CreateForBackgroundBlendMode(aBuilder, this, aLists.BorderBackground(), diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index edd7f8b11d7b..bdc9650bccc7 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -3098,7 +3098,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, */ if (aBuilder->ContainsBlendMode()) { DisplayListClipState::AutoSaveRestore blendContainerClipState(aBuilder); - blendContainerClipState.ClearUpToASR(containerItemASR); resultList.AppendNewToTop( nsDisplayBlendContainer::CreateForMixBlendMode(aBuilder, this, &resultList, containerItemASR)); @@ -3137,7 +3136,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, if (usingMask) { DisplayListClipState::AutoSaveRestore maskClipState(aBuilder); - maskClipState.ClearUpToASR(containerItemASR); // The mask should move with aBuilder->CurrentActiveScrolledRoot(), so // that's the ASR we prefer to use for the mask item. However, we can // only do this if the mask if clipped with respect to that ASR, because @@ -3173,7 +3171,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, // The clip we would set on an element with opacity would clip // all descendant content, but some should not be clipped. DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder); - opacityClipState.ClearUpToASR(containerItemASR); resultList.AppendNewToTop( new (aBuilder) nsDisplayOpacity(aBuilder, this, &resultList, containerItemASR, @@ -3316,7 +3313,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, if (useBlendMode) { DisplayListClipState::AutoSaveRestore blendModeClipState(aBuilder); - blendModeClipState.ClearUpToASR(containerItemASR); resultList.AppendNewToTop( new (aBuilder) nsDisplayBlendMode(aBuilder, this, &resultList, effects->mMixBlendMode, @@ -3348,7 +3344,9 @@ WrapInWrapList(nsDisplayListBuilder* aBuilder, return item; } - return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList, aContainerASR); + // Clear clip rect for the construction of the items below. Since we're + // clipping all their contents, they themselves don't need to be clipped. + return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList, aContainerASR, true); } /** @@ -3734,10 +3732,6 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, buildingForChild.RestoreBuildingInvisibleItemsValue(); - // Clear clip rect for the construction of the items below. Since we're - // clipping all their contents, they themselves don't need to be clipped. - clipState.ClearUpToASR(wrapListASR); - if (isPositioned || isVisuallyAtomic || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) { // Genuine stacking contexts, and positioned pseudo-stacking-contexts, diff --git a/layout/painting/DisplayListClipState.cpp b/layout/painting/DisplayListClipState.cpp index d6a5c13d0f2e..2086c0b7c5ff 100644 --- a/layout/painting/DisplayListClipState.cpp +++ b/layout/painting/DisplayListClipState.cpp @@ -10,20 +10,6 @@ namespace mozilla { -void -DisplayListClipState::ClearUpToASR(const ActiveScrolledRoot* aASR) -{ - while (mClipChainContentDescendants && - ActiveScrolledRoot::IsAncestor(aASR, mClipChainContentDescendants->mASR)) { - mClipChainContentDescendants = mClipChainContentDescendants->mParent; - } - while (mClipChainContainingBlockDescendants && - ActiveScrolledRoot::IsAncestor(aASR, mClipChainContainingBlockDescendants->mASR)) { - mClipChainContainingBlockDescendants = mClipChainContainingBlockDescendants->mParent; - } - InvalidateCurrentCombinedClipChain(aASR); -} - const DisplayItemClipChain* DisplayListClipState::GetCurrentCombinedClipChain(nsDisplayListBuilder* aBuilder) { diff --git a/layout/painting/DisplayListClipState.h b/layout/painting/DisplayListClipState.h index 9c733179e536..d59024d98e53 100644 --- a/layout/painting/DisplayListClipState.h +++ b/layout/painting/DisplayListClipState.h @@ -74,8 +74,6 @@ private: mCurrentCombinedClipChainIsValid = false; } - void ClearUpToASR(const ActiveScrolledRoot* aASR); - void SetClipChainForContainingBlockDescendants(const DisplayItemClipChain* aClipChain) { mClipChainContainingBlockDescendants = aClipChain; @@ -172,15 +170,6 @@ public: #endif } - void ClearUpToASR(const ActiveScrolledRoot* aASR) - { - NS_ASSERTION(!mRestored, "Already restored!"); - mState.ClearUpToASR(aASR); -#ifdef DEBUG - mClipUsed = false; -#endif - } - void SetClipChainForContainingBlockDescendants(const DisplayItemClipChain* aClipChain) { mState.SetClipChainForContainingBlockDescendants(aClipChain); diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp index 8afce2369d60..89876a59a4ef 100644 --- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -282,6 +282,20 @@ RetainedDisplayListBuilder::IncrementSubDocPresShellPaintCount(nsDisplayItem* aI mBuilder.IncrementPresShellPaintCount(presShell); } +void UpdateASR(nsDisplayItem* aItem, + const ActiveScrolledRoot* aContainerASR) +{ + nsDisplayWrapList* wrapList = aItem->AsDisplayWrapList(); + if (!wrapList) { + aItem->SetActiveScrolledRoot(aContainerASR); + return; + } + + wrapList->SetActiveScrolledRoot( + ActiveScrolledRoot::PickAncestor(wrapList->GetFrameActiveScrolledRoot(), + aContainerASR)); +} + /** * Takes two display lists and merges them into an output list. * @@ -332,11 +346,25 @@ RetainedDisplayListBuilder::IncrementSubDocPresShellPaintCount(nsDisplayItem* aI void RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList, nsDisplayList* aOldList, - nsDisplayList* aOutList) + nsDisplayList* aOutList, + const ActiveScrolledRoot** aOutContainerASR) { nsDisplayList merged(&mBuilder); + const ActiveScrolledRoot* containerASR = nullptr; const auto ReuseItem = [&](nsDisplayItem* aItem) { + const ActiveScrolledRoot* itemClipASR = + aItem->GetClipChain() ? aItem->GetClipChain()->mASR : nullptr; + + const ActiveScrolledRoot* finiteBoundsASR = ActiveScrolledRoot::PickDescendant( + itemClipASR, aItem->GetActiveScrolledRoot()); + if (merged.IsEmpty()) { + containerASR = finiteBoundsASR; + } else { + containerASR = + ActiveScrolledRoot::PickAncestor(containerASR, finiteBoundsASR); + } + merged.AppendToTop(aItem); aItem->SetReused(true); @@ -380,7 +408,10 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList, if (oldItem->GetChildren()) { MOZ_ASSERT(newItem->GetChildren()); - MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(), oldItem->GetChildren()); + const ActiveScrolledRoot* containerASRForChildren; + MergeDisplayLists(newItem->GetChildren(), oldItem->GetChildren(), + oldItem->GetChildren(), &containerASRForChildren); + UpdateASR(oldItem, containerASRForChildren); oldItem->UpdateBounds(&mBuilder); } if (oldItem->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) { @@ -397,8 +428,10 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList, // ensure that we find and remove any invalidated items. if (old->GetChildren()) { nsDisplayList empty(&mBuilder); + const ActiveScrolledRoot* containerASRForChildren; MergeDisplayLists(&empty, old->GetChildren(), - old->GetChildren()); + old->GetChildren(), &containerASRForChildren); + UpdateASR(old, containerASRForChildren); old->UpdateBounds(&mBuilder); } ReuseItem(old); @@ -425,7 +458,10 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList, if (!IsAnyAncestorModified(old->FrameForInvalidation()) && old->GetChildren()) { MOZ_ASSERT(newItem->GetChildren()); - MergeDisplayLists(newItem->GetChildren(), old->GetChildren(), newItem->GetChildren()); + const ActiveScrolledRoot* containerASRForChildren; + MergeDisplayLists(newItem->GetChildren(), old->GetChildren(), + newItem->GetChildren(), &containerASRForChildren); + UpdateASR(newItem, containerASRForChildren); newItem->UpdateBounds(&mBuilder); } @@ -443,27 +479,32 @@ RetainedDisplayListBuilder::MergeDisplayLists(nsDisplayList* aNewList, // Reuse the remaining valid items from the old display list. while (nsDisplayItem* old = aOldList->RemoveBottom()) { if (!IsAnyAncestorModified(old->FrameForInvalidation())) { - ReuseItem(old); - if (old->GetChildren()) { // We are calling MergeDisplayLists() to ensure that the display items // with modified or deleted children will be correctly handled. // Passing an empty new display list as an argument skips the merging // loop above and jumps back here. nsDisplayList empty(&mBuilder); + const ActiveScrolledRoot* containerASRForChildren; - MergeDisplayLists(&empty, old->GetChildren(), old->GetChildren()); + MergeDisplayLists(&empty, old->GetChildren(), + old->GetChildren(), &containerASRForChildren); + UpdateASR(old, containerASRForChildren); old->UpdateBounds(&mBuilder); } if (old->GetType() == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) { MergeLayerEventRegions(old, nullptr); } + ReuseItem(old); } else { old->Destroy(&mBuilder); } } aOutList->AppendToTop(&merged); + if (aOutContainerASR) { + *aOutContainerASR = containerASR; + } } static void @@ -787,7 +828,7 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop) // are not visible anymore) from the old list. // TODO: Optimization opportunity. In this case, MergeDisplayLists() // unnecessarily creates a hashtable of the old items. - MergeDisplayLists(&modifiedDL, &mList, &mList); + MergeDisplayLists(&modifiedDL, &mList, &mList, nullptr); //printf_stderr("Painting --- Merged list:\n"); //nsFrame::PrintDisplayList(&mBuilder, mList); diff --git a/layout/painting/RetainedDisplayListBuilder.h b/layout/painting/RetainedDisplayListBuilder.h index 492c6c70ecaf..0c3e57d3009f 100644 --- a/layout/painting/RetainedDisplayListBuilder.h +++ b/layout/painting/RetainedDisplayListBuilder.h @@ -34,7 +34,8 @@ private: void MergeDisplayLists(nsDisplayList* aNewList, nsDisplayList* aOldList, - nsDisplayList* aOutList); + nsDisplayList* aOutList, + const mozilla::ActiveScrolledRoot** aOutContainerASR = nullptr); bool ComputeRebuildRegion(nsTArray& aModifiedFrames, nsRect* aOutDirty, diff --git a/layout/painting/crashtests/1413073-1.html b/layout/painting/crashtests/1413073-1.html new file mode 100644 index 000000000000..ddecfb242441 --- /dev/null +++ b/layout/painting/crashtests/1413073-1.html @@ -0,0 +1,15 @@ + + +
+
+
+ + + diff --git a/layout/painting/crashtests/1413073-2.html b/layout/painting/crashtests/1413073-2.html new file mode 100644 index 000000000000..01d1718745da --- /dev/null +++ b/layout/painting/crashtests/1413073-2.html @@ -0,0 +1,18 @@ + + +
+
+
+
+
+
+ + + diff --git a/layout/painting/crashtests/crashtests.list b/layout/painting/crashtests/crashtests.list index 699dd13d57ef..f440384bdc2e 100644 --- a/layout/painting/crashtests/crashtests.list +++ b/layout/painting/crashtests/crashtests.list @@ -1,3 +1,5 @@ load 1402183-1.html skip-if(!(stylo||styloVsGecko)||Android) load 1407470-1.html +load 1413073-1.html +load 1413073-2.html load 1405881-1.html diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 76d0a139f3bf..1b8f6bd7fcfc 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1002,9 +1002,11 @@ nsDisplayListBuilder::EndFrame() } void -nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) +nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame, bool aAlreadyAddedFrame) { - mFramesMarkedForDisplay.AppendElement(aFrame); + if (!aAlreadyAddedFrame) { + mFramesMarkedForDisplay.AppendElement(aFrame); + } for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) { if (f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) @@ -1162,6 +1164,10 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, return; } + // Always store OutOfFlowDisplayData for visible frames (even when they aren't dirty) + // since a nested out-of-flow frame might force building and we'll need to have this + // data available. + // mClipState.GetClipChainForContainingBlockDescendants can return pointers // to objects on the stack, so we need to clone the chain. const DisplayItemClipChain* clipChain = @@ -1170,8 +1176,14 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot; OutOfFlowDisplayData* data = new OutOfFlowDisplayData(clipChain, combinedClipChain, asr, visible, dirty); aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data); + mFramesMarkedForDisplay.AppendElement(aFrame); - MarkFrameForDisplay(aFrame, aDirtyFrame); + // Only MarkFrameForDisplay if we're dirty. If this is a nested out-of-flow frame, then it will + // also mark any outer frames to ensure that building reaches the dirty feame. + if (!dirty.IsEmpty() || + aFrame->ForceDescendIntoIfVisible()) { + MarkFrameForDisplay(aFrame, aDirtyFrame, true); + } } static void UnmarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) { @@ -3667,7 +3679,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil if (bg->mImage.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) { DisplayListClipState::AutoSaveRestore blendClip(aBuilder); - blendClip.ClearUpToASR(asr); // asr is scrolled. Even if we wrap a fixed background layer, that's // fine, because the item will have a scrolled clip that limits the // item with respect to asr. @@ -3681,7 +3692,6 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil if (needBlendContainer) { DisplayListClipState::AutoSaveRestore blendContainerClip(aBuilder); - blendContainerClip.ClearUpToASR(asr); bgItemList.AppendNewToTop( nsDisplayBlendContainer::CreateForBackgroundBlendMode(aBuilder, aFrame, &bgItemList, asr)); } @@ -5917,11 +5927,14 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, - const ActiveScrolledRoot* aActiveScrolledRoot) + const ActiveScrolledRoot* aActiveScrolledRoot, + bool aClearClipChain) : nsDisplayItem(aBuilder, aFrame, aActiveScrolledRoot) , mList(aBuilder) + , mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot()) , mOverrideZIndex(0) , mHasZIndexOverride(false) + , mClearingClipChain(aClearClipChain) { MOZ_COUNT_CTOR(nsDisplayWrapList); @@ -6239,7 +6252,7 @@ nsDisplayOpacity::nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const ActiveScrolledRoot* aActiveScrolledRoot, bool aForEventsAndPluginsOnly) - : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot) + : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true) , mOpacity(aFrame->StyleEffects()->mOpacity) , mForEventsAndPluginsOnly(aForEventsAndPluginsOnly) { @@ -6542,7 +6555,7 @@ nsDisplayBlendMode::nsDisplayBlendMode(nsDisplayListBuilder* aBuilder, uint8_t aBlendMode, const ActiveScrolledRoot* aActiveScrolledRoot, uint32_t aIndex) - : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot) + : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true) , mBlendMode(aBlendMode) , mIndex(aIndex) { @@ -6660,7 +6673,7 @@ nsDisplayBlendContainer::nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const ActiveScrolledRoot* aActiveScrolledRoot, bool aIsForBackground) - : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot) + : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true) , mIsForBackground(aIsForBackground) { MOZ_COUNT_CTOR(nsDisplayBlendContainer); @@ -6719,8 +6732,9 @@ nsDisplayOwnLayer::nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, const ActiveScrolledRoot* aActiveScrolledRoot, uint32_t aFlags, ViewID aScrollTarget, const ScrollThumbData& aThumbData, - bool aForceActive) - : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot) + bool aForceActive, + bool aClearClipChain) + : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, aClearClipChain) , mFlags(aFlags) , mScrollTarget(aScrollTarget) , mThumbData(aThumbData) @@ -9014,8 +9028,9 @@ nsCharClipDisplayItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, bool aHandleOpacity, - const ActiveScrolledRoot* aActiveScrolledRoot) - : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot) + const ActiveScrolledRoot* aActiveScrolledRoot, + bool aClearClipChain) + : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, aClearClipChain) , mHandleOpacity(aHandleOpacity) { MOZ_COUNT_CTOR(nsDisplaySVGEffects); @@ -9198,7 +9213,7 @@ nsDisplayMask::nsDisplayMask(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, bool aHandleOpacity, const ActiveScrolledRoot* aActiveScrolledRoot) - : nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity, aActiveScrolledRoot) + : nsDisplaySVGEffects(aBuilder, aFrame, aList, aHandleOpacity, aActiveScrolledRoot, true) { MOZ_COUNT_CTOR(nsDisplayMask); diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index f646cac63947..dd013d52bc69 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -834,7 +834,7 @@ public: */ void MarkFramesForDisplayList(nsIFrame* aDirtyFrame, const nsFrameList& aFrames); - void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame); + void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame, bool aAlreadyAddedFrame = false); void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame); void ClearFixedBackgroundDisplayData(); @@ -1607,7 +1607,6 @@ public: if (!aFrame->IsFrameModified()) { mModifiedFramesDuringBuilding.AppendElement(aFrame); aFrame->SetFrameIsModified(true); - mInInvalidSubtree = true; return true; } return false; @@ -1942,6 +1941,7 @@ public: * Downcasts this item to nsDisplayWrapList, if possible. */ virtual const nsDisplayWrapList* AsDisplayWrapList() const { return nullptr; } + virtual nsDisplayWrapList* AsDisplayWrapList() { return nullptr; } /** * Create a clone of this item. @@ -2584,7 +2584,7 @@ public: } void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClipChain* aOther, bool aStore); - void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; } + virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; } const ActiveScrolledRoot* GetActiveScrolledRoot() const { return mActiveScrolledRoot; } virtual void SetClipChain(const DisplayItemClipChain* aClipChain, @@ -4572,12 +4572,14 @@ public: nsDisplayList* aList); nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, - const ActiveScrolledRoot* aActiveScrolledRoot); + const ActiveScrolledRoot* aActiveScrolledRoot, + bool aClearClipChain = false); nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayItem* aItem); nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : nsDisplayItem(aBuilder, aFrame) , mList(aBuilder) + , mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot()) , mOverrideZIndex(0) , mHasZIndexOverride(false) { @@ -4595,11 +4597,13 @@ public: : nsDisplayItem(aBuilder, aOther) , mList(aOther.mList.mBuilder) , mListPtr(&mList) + , mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot) , mMergedFrames(aOther.mMergedFrames) , mBounds(aOther.mBounds) , mBaseVisibleRect(aOther.mBaseVisibleRect) , mOverrideZIndex(aOther.mOverrideZIndex) , mHasZIndexOverride(aOther.mHasZIndexOverride) + , mClearingClipChain(aOther.mClearingClipChain) { MOZ_COUNT_CTOR(nsDisplayWrapList); } @@ -4610,6 +4614,10 @@ public: { return this; } + virtual nsDisplayWrapList* AsDisplayWrapList() override + { + return this; + } virtual void Destroy(nsDisplayListBuilder* aBuilder) override { mList.DeleteAll(aBuilder); @@ -4629,6 +4637,16 @@ public: */ virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override { + // Clear the clip chain up to the asr, but don't store it, so that we'll recover + // it when we reuse the item. + if (mClearingClipChain) { + const DisplayItemClipChain* clip = mState.mClipChain; + while (clip && ActiveScrolledRoot::IsAncestor(GetActiveScrolledRoot(), clip->mASR)) { + clip = clip->mParent; + } + SetClipChain(clip, false); + } + nsRect visibleRect; mBounds = mListPtr->GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot, &visibleRect); @@ -4736,6 +4754,8 @@ public: mozilla::layers::WebRenderLayerManager* aManager, nsDisplayListBuilder* aDisplayListBuilder) override; + const ActiveScrolledRoot* GetFrameActiveScrolledRoot() { return mFrameActiveScrolledRoot; } + protected: nsDisplayWrapList() = delete; @@ -4749,6 +4769,9 @@ protected: nsDisplayList mList; nsDisplayList* mListPtr; + // The active scrolled root for the frame that created this + // wrap list. + RefPtr mFrameActiveScrolledRoot; // The frames from items that have been merged into this item, excluding // this item's own frame. nsTArray mMergedFrames; @@ -4758,6 +4781,7 @@ protected: nsRect mBaseVisibleRect; int32_t mOverrideZIndex; bool mHasZIndexOverride; + bool mClearingClipChain = false; }; /** @@ -5041,7 +5065,8 @@ public: uint32_t aFlags = 0, ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID, const ScrollThumbData& aThumbData = ScrollThumbData{}, - bool aForceActive = true); + bool aForceActive = true, + bool aClearClipChain = false); #ifdef NS_BUILD_REFCNT_LOGGING virtual ~nsDisplayOwnLayer(); #endif @@ -5434,7 +5459,8 @@ class nsDisplaySVGEffects: public nsDisplayWrapList { public: nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, bool aHandleOpacity, - const ActiveScrolledRoot* aActiveScrolledRoot); + const ActiveScrolledRoot* aActiveScrolledRoot, + bool aClearClipChain = false); nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, bool aHandleOpacity); #ifdef NS_BUILD_REFCNT_LOGGING @@ -5761,6 +5787,12 @@ public: return mStoredList.GetChildren(); } + virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) override + { + nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot); + mStoredList.SetActiveScrolledRoot(aActiveScrolledRoot); + } + virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect, HitTestState *aState, nsTArray *aOutFrames) override; virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, @@ -6149,6 +6181,12 @@ public: return mList.GetChildren(); } + virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) override + { + nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot); + mList.SetActiveScrolledRoot(aActiveScrolledRoot); + } + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override { return mList.GetComponentAlphaBounds(aBuilder); diff --git a/layout/reftests/display-list/1413073-ref.html b/layout/reftests/display-list/1413073-ref.html new file mode 100644 index 000000000000..eac0fd7bf45d --- /dev/null +++ b/layout/reftests/display-list/1413073-ref.html @@ -0,0 +1,54 @@ + + + + + +The ASR for the opacity item is the root scroll frame instead of the subframe. + + + + + +
+
+
+
+
+
+
+
+
+ diff --git a/layout/reftests/display-list/1413073.html b/layout/reftests/display-list/1413073.html new file mode 100644 index 000000000000..f266852ae2fb --- /dev/null +++ b/layout/reftests/display-list/1413073.html @@ -0,0 +1,69 @@ + + + + + +The ASR for the opacity item is the root scroll frame instead of the subframe. + + + + + +
+
+
+
+
+
+
+
+
+ + + diff --git a/layout/reftests/display-list/reftest.list b/layout/reftests/display-list/reftest.list index 5140de9ff305..a58534309f5b 100644 --- a/layout/reftests/display-list/reftest.list +++ b/layout/reftests/display-list/reftest.list @@ -8,3 +8,4 @@ skip-if(!retainedDisplayList) == retained-dl-scroll-out-of-view-1.html retained- skip-if(!retainedDisplayList) == retained-dl-displayport-1.html retained-dl-displayport-1-ref.html skip-if(!retainedDisplayList) == retained-dl-prerender-transform-1.html retained-dl-prerender-transform-1-ref.html == retained-dl-wrap-list.html retained-dl-wrap-list-ref.html +fuzzy(1,235200) == 1413073.html 1413073-ref.html diff --git a/layout/style/CSS.cpp b/layout/style/CSS.cpp index 920009b0e9b1..5d6dbdd0100c 100644 --- a/layout/style/CSS.cpp +++ b/layout/style/CSS.cpp @@ -32,7 +32,7 @@ static nsresult GetParsingInfo(const GlobalObject& aGlobal, SupportsParsingInfo& aInfo) { - nsGlobalWindow* win = xpc::WindowOrNull(aGlobal.Get()); + nsGlobalWindowInner* win = xpc::WindowOrNull(aGlobal.Get()); if (!win) { return NS_ERROR_FAILURE; } diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index d2fbcdda1363..1de5b8c67207 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -1367,11 +1367,12 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const ActiveScrolledRoot* ownLayerASR = contASRTracker->GetContainerASR(); DisplayListClipState::AutoSaveRestore ownLayerClipState(aBuilder); - ownLayerClipState.ClearUpToASR(ownLayerASR); // Wrap the list to make it its own layer aLists.Content()->AppendNewToTop(new (aBuilder) - nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR)); + nsDisplayOwnLayer(aBuilder, this, &masterList, ownLayerASR, 0, + mozilla::layers::FrameMetrics::NULL_SCROLL_ID, + mozilla::layers::ScrollThumbData{}, true, true)); } } diff --git a/layout/xul/nsMenuBarListener.cpp b/layout/xul/nsMenuBarListener.cpp index 976c6ef9999b..9c6056166443 100644 --- a/layout/xul/nsMenuBarListener.cpp +++ b/layout/xul/nsMenuBarListener.cpp @@ -61,6 +61,9 @@ nsMenuBarListener::nsMenuBarListener(nsMenuBarFrame* aMenuBarFrame, mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("keyup"), this, false); mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("mozaccesskeynotfound"), this, false); + // Need a capturing event listener if the user has blocked pages from overriding + // system keys so that we can prevent menu accesskeys from being cancelled. + mEventTarget->AddEventListener(NS_LITERAL_STRING("keydown"), this, true); // mousedown event should be handled in all phase mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true); @@ -97,6 +100,8 @@ nsMenuBarListener::OnDestroyMenuBarFrame() this, false); mEventTarget->RemoveSystemEventListener( NS_LITERAL_STRING("mozaccesskeynotfound"), this, false); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keydown"), + this, true); mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, true); mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), @@ -277,56 +282,17 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent) } nsCOMPtr keyEvent = do_QueryInterface(aKeyEvent); - uint32_t keyCode, charCode; + uint32_t keyCode; keyEvent->GetKeyCode(&keyCode); - keyEvent->GetCharCode(&charCode); - - bool hasAccessKeyCandidates = charCode != 0; - if (!hasAccessKeyCandidates) { - if (nativeKeyEvent) { - AutoTArray keys; - nativeKeyEvent->GetAccessKeyCandidates(keys); - hasAccessKeyCandidates = !keys.IsEmpty(); - } - } // Cancel the access key flag unless we are pressing the access key. if (keyCode != (uint32_t)mAccessKey) { mAccessKeyDownCanceled = true; } - if (IsAccessKeyPressed(keyEvent) && hasAccessKeyCandidates) { - // Do shortcut navigation. - // A letter was pressed. We want to see if a shortcut gets matched. If - // so, we'll know the menu got activated. - nsMenuFrame* result = mMenuBarFrame->FindMenuWithShortcut(keyEvent); - if (result) { - // If the keyboard event matches with a menu item's accesskey and - // will be sent to a remote process, it should be executed with - // reply event from the focused remote process. Note that if the - // menubar is active, the event is already marked as "stop cross - // process dispatching". So, in that case, this won't wait - // reply from the remote content. - if (nativeKeyEvent->WillBeSentToRemoteProcess()) { - nativeKeyEvent->StopImmediatePropagation(); - nativeKeyEvent->MarkAsWaitingReplyFromRemoteProcess(); - return NS_OK; - } - mMenuBarFrame->SetActiveByKeyboard(); - mMenuBarFrame->SetActive(true); - result->OpenMenu(true); - - // The opened menu will listen next keyup event. - // Therefore, we should clear the keydown flags here. - mAccessKeyDown = mAccessKeyDownCanceled = false; - - aKeyEvent->StopPropagation(); - aKeyEvent->PreventDefault(); - } - } #ifndef XP_MACOSX - // Also need to handle F10 specially on Non-Mac platform. - else if (nativeKeyEvent->mMessage == eKeyPress && keyCode == NS_VK_F10) { + // Need to handle F10 specially on Non-Mac platform. + if (nativeKeyEvent->mMessage == eKeyPress && keyCode == NS_VK_F10) { if ((GetModifiersForAccessKey(keyEvent) & ~MODIFIER_CONTROL) == 0) { // If the keyboard event should activate the menubar and will be // sent to a remote process, it should be executed with reply @@ -353,8 +319,38 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent) aKeyEvent->PreventDefault(); } } + + return NS_OK; } #endif // !XP_MACOSX + + nsMenuFrame* menuFrameForKey = GetMenuForKeyEvent(keyEvent); + if (!menuFrameForKey) { + return NS_OK; + } + + // If the keyboard event matches with a menu item's accesskey and + // will be sent to a remote process, it should be executed with + // reply event from the focused remote process. Note that if the + // menubar is active, the event is already marked as "stop cross + // process dispatching". So, in that case, this won't wait + // reply from the remote content. + if (nativeKeyEvent->WillBeSentToRemoteProcess()) { + nativeKeyEvent->StopImmediatePropagation(); + nativeKeyEvent->MarkAsWaitingReplyFromRemoteProcess(); + return NS_OK; + } + + mMenuBarFrame->SetActiveByKeyboard(); + mMenuBarFrame->SetActive(true); + menuFrameForKey->OpenMenu(true); + + // The opened menu will listen next keyup event. + // Therefore, we should clear the keydown flags here. + mAccessKeyDown = mAccessKeyDownCanceled = false; + + aKeyEvent->StopPropagation(); + aKeyEvent->PreventDefault(); } return NS_OK; @@ -385,6 +381,45 @@ nsMenuBarListener::GetModifiersForAccessKey(nsIDOMKeyEvent* aKeyEvent) return (inputEvent->mModifiers & kPossibleModifiersForAccessKey); } +nsMenuFrame* +nsMenuBarListener::GetMenuForKeyEvent(nsIDOMKeyEvent* aKeyEvent) +{ + if (!IsAccessKeyPressed(aKeyEvent)) { + return nullptr; + } + + uint32_t charCode; + aKeyEvent->GetCharCode(&charCode); + bool hasAccessKeyCandidates = charCode != 0; + if (!hasAccessKeyCandidates) { + WidgetKeyboardEvent* nativeKeyEvent = + aKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent(); + + AutoTArray keys; + nativeKeyEvent->GetAccessKeyCandidates(keys); + hasAccessKeyCandidates = !keys.IsEmpty(); + } + + if (hasAccessKeyCandidates) { + // Do shortcut navigation. + // A letter was pressed. We want to see if a shortcut gets matched. If + // so, we'll know the menu got activated. + return mMenuBarFrame->FindMenuWithShortcut(aKeyEvent); + } + + return nullptr; +} + +void +nsMenuBarListener::ReserveKeyIfNeeded(nsIDOMEvent* aKeyEvent) +{ + WidgetKeyboardEvent* nativeKeyEvent = + aKeyEvent->WidgetEventPtr()->AsKeyboardEvent(); + if (nsContentUtils::ShouldBlockReservedKeys(nativeKeyEvent)) { + nativeKeyEvent->MarkAsReservedByChrome(); + } +} + //////////////////////////////////////////////////////////////////////// nsresult nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent) @@ -397,18 +432,34 @@ nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent) aKeyEvent->GetIsTrusted(&trustedEvent); } - if (!trustedEvent) + if (!trustedEvent) { return NS_OK; + } + + nsCOMPtr keyEvent = do_QueryInterface(aKeyEvent); + if (!keyEvent) { + return NS_OK; + } + + uint32_t theChar; + keyEvent->GetKeyCode(&theChar); + + uint16_t eventPhase; + aKeyEvent->GetEventPhase(&eventPhase); + bool capturing = (eventPhase == nsIDOMEvent::CAPTURING_PHASE); + +#ifndef XP_MACOSX + if (capturing && !mAccessKeyDown && theChar == NS_VK_F10 && + (GetModifiersForAccessKey(keyEvent) & ~MODIFIER_CONTROL) == 0) { + ReserveKeyIfNeeded(aKeyEvent); + } +#endif if (mAccessKey && mAccessKeyFocuses) { bool defaultPrevented = false; aKeyEvent->GetDefaultPrevented(&defaultPrevented); - nsCOMPtr keyEvent = do_QueryInterface(aKeyEvent); - uint32_t theChar; - keyEvent->GetKeyCode(&theChar); - // No other modifiers can be down. // Especially CTRL. CTRL+ALT == AltGR, and we'll fuck up on non-US // enhanced 102-key keyboards if we don't check this. @@ -416,7 +467,7 @@ nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent) ((theChar == (uint32_t)mAccessKey) && (GetModifiersForAccessKey(keyEvent) & ~mAccessKeyMask) == 0); - if (!mAccessKeyDown) { + if (!capturing && !mAccessKeyDown) { // If accesskey isn't being pressed and the key isn't the accesskey, // ignore the event. if (!isAccessKeyDownEvent) { @@ -441,6 +492,13 @@ nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent) mAccessKeyDownCanceled = !isAccessKeyDownEvent; } + if (capturing && mAccessKey) { + nsMenuFrame* menuFrameForKey = GetMenuForKeyEvent(keyEvent); + if (menuFrameForKey) { + ReserveKeyIfNeeded(aKeyEvent); + } + } + return NS_OK; // means I am NOT consuming event } diff --git a/layout/xul/nsMenuBarListener.h b/layout/xul/nsMenuBarListener.h index 425b49107a83..a154ec1be6e6 100644 --- a/layout/xul/nsMenuBarListener.h +++ b/layout/xul/nsMenuBarListener.h @@ -15,6 +15,7 @@ #undef KeyPress #endif +class nsMenuFrame; class nsMenuBarFrame; class nsIDOMKeyEvent; @@ -74,6 +75,18 @@ protected: static mozilla::Modifiers GetModifiersForAccessKey(nsIDOMKeyEvent* event); + /** + * Given a key event for an Alt+shortcut combination, + * return the menu, if any, that would be opened. + */ + nsMenuFrame* GetMenuForKeyEvent(nsIDOMKeyEvent* aKeyEvent); + + /** + * Call MarkAsReservedByChrome if the user's preferences indicate that + * the key should be chrome-only. + */ + void ReserveKeyIfNeeded(nsIDOMEvent* aKeyEvent); + // This should only be called by the nsMenuBarListener during event dispatch, // thus ensuring that this doesn't get destroyed during the process. void ToggleMenuActiveState(); diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index 84c7f40b69a8..0c5a5306f1c6 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -1819,7 +1819,7 @@ nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup) #ifdef XP_MACOSX if (rootWin) { - auto globalWin = nsGlobalWindow::Cast(rootWin.get()); + auto globalWin = nsGlobalWindowOuter::Cast(rootWin.get()); if (globalWin->IsInModalState()) { return false; } diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index c9c3fdc9a9f4..68949feb7254 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -579,7 +579,7 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer) nsresult PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver, - nsGlobalWindow* aWindow, + nsGlobalWindowInner* aWindow, const PeerConnectionConfiguration& aConfiguration, nsISupports* aThread) { @@ -727,7 +727,7 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver, void PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver, - nsGlobalWindow& aWindow, + nsGlobalWindowInner& aWindow, const RTCConfiguration& aConfiguration, nsISupports* aThread, ErrorResult &rv) @@ -744,7 +744,7 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver, return; } - res = Initialize(aObserver, &aWindow, converted, aThread); + res = Initialize(aObserver, aWindow.AssertInner(), converted, aThread); if (NS_FAILED(res)) { rv.Throw(res); return; diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index e73fe356c77c..3090a25bf57e 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -55,7 +55,6 @@ class AFakePCObserver; #endif } -class nsGlobalWindow; class nsDOMDataChannel; namespace mozilla { @@ -325,13 +324,13 @@ public: // (used directly by unit-tests, and indirectly by the JS entry point) // This is necessary because RTCConfiguration can't be used by unit-tests nsresult Initialize(PeerConnectionObserver& aObserver, - nsGlobalWindow* aWindow, + nsGlobalWindowInner* aWindow, const PeerConnectionConfiguration& aConfiguration, nsISupports* aThread); // Initialize PeerConnection from an RTCConfiguration object (JS entrypoint) void Initialize(PeerConnectionObserver& aObserver, - nsGlobalWindow& aWindow, + nsGlobalWindowInner& aWindow, const RTCConfiguration& aConfiguration, nsISupports* aThread, ErrorResult &rv); diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index 6f1ae68e659d..6eecae82448b 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -690,7 +690,7 @@ class PCDispatchWrapper : public nsSupportsWeakReference } NS_IMETHODIMP Initialize(TestObserver* aObserver, - nsGlobalWindow* aWindow, + nsGlobalWindowInner* aWindow, const PeerConnectionConfiguration& aConfiguration, nsIThread* aThread) { nsresult rv; diff --git a/media/webrtc/trunk/webrtc/modules/audio_coding/neteq/merge.cc b/media/webrtc/trunk/webrtc/modules/audio_coding/neteq/merge.cc index 299682f60d44..54e50db95cd5 100644 --- a/media/webrtc/trunk/webrtc/modules/audio_coding/neteq/merge.cc +++ b/media/webrtc/trunk/webrtc/modules/audio_coding/neteq/merge.cc @@ -211,6 +211,12 @@ int16_t Merge::SignalScaling(const int16_t* input, size_t input_length, // Adjust muting factor if new vector is more or less of the BGN energy. const size_t mod_input_length = std::min(static_cast(64 * fs_mult_), input_length); + + // Missing input, do no muting + if (mod_input_length == 0) { + return 16384; + } + const int16_t expanded_max = WebRtcSpl_MaxAbsValueW16(expanded_signal, mod_input_length); int32_t factor = (expanded_max * expanded_max) / diff --git a/memory/build/Utils.h b/memory/build/Utils.h index c8a96f8b0c48..d4bbe4ec645c 100644 --- a/memory/build/Utils.h +++ b/memory/build/Utils.h @@ -32,14 +32,24 @@ CompareAddr(T* aAddr1, T* aAddr2) } // User-defined literals to make constants more legible -constexpr unsigned long long int operator"" _KiB(unsigned long long int aNum) +constexpr size_t operator"" _KiB(unsigned long long int aNum) { - return aNum * 1024; + return size_t(aNum) * 1024; } -constexpr unsigned long long int operator"" _MiB(unsigned long long int aNum) +constexpr size_t operator"" _KiB(long double aNum) { - return aNum * 1024_KiB; + return size_t(aNum * 1024); +} + +constexpr size_t operator"" _MiB(unsigned long long int aNum) +{ + return size_t(aNum) * 1024_KiB; +} + +constexpr size_t operator"" _MiB(long double aNum) +{ + return size_t(aNum * 1024_KiB); } constexpr long double operator""_percent(long double aPercent) diff --git a/memory/build/malloc_decls.h b/memory/build/malloc_decls.h index 540082d349dd..0796f9344d4d 100644 --- a/memory/build/malloc_decls.h +++ b/memory/build/malloc_decls.h @@ -105,7 +105,9 @@ MALLOC_DECL(jemalloc_ptr_info, void, const void*, jemalloc_ptr_info_t*) // functions. MALLOC_DECL(moz_create_arena, arena_id_t) -// Dispose of the given arena. Subsequent uses of the arena will fail. +// Dispose of the given arena. Subsequent uses of the arena will crash. +// Passing an invalid id (inexistent or already disposed) to this function +// will crash. MALLOC_DECL(moz_dispose_arena, void, arena_id_t) #endif @@ -113,8 +115,9 @@ MALLOC_DECL(moz_dispose_arena, void, arena_id_t) // Same as the functions without the moz_arena_ prefix, but using arenas // created with moz_create_arena. // The contract, even if not enforced at runtime in some configurations, -// is that moz_arena_realloc and moz_arena_free will crash if the wrong -// arena id is given. All functions will crash if the arena id is invalid. +// is that moz_arena_realloc and moz_arena_free will crash if the given +// arena doesn't own the given pointer. All functions will crash if the +// arena id is invalid. // Although discouraged, plain realloc and free can still be used on // pointers allocated with these functions. Realloc will properly keep // new pointers in the same arena as the original. diff --git a/memory/build/mozjemalloc.cpp b/memory/build/mozjemalloc.cpp index d7aba0101acf..55e3034f5f64 100644 --- a/memory/build/mozjemalloc.cpp +++ b/memory/build/mozjemalloc.cpp @@ -618,32 +618,37 @@ enum ChunkType struct extent_node_t { // Linkage for the size/address-ordered tree. - RedBlackTreeNode link_szad; + RedBlackTreeNode mLinkBySize; // Linkage for the address-ordered tree. - RedBlackTreeNode link_ad; + RedBlackTreeNode mLinkByAddr; // Pointer to the extent that this tree node is responsible for. - void* addr; + void* mAddr; // Total region size. - size_t size; + size_t mSize; - // What type of chunk is there; used by chunk recycling code. - ChunkType chunk_type; + union { + // What type of chunk is there; used for chunk recycling. + ChunkType mChunkType; + + // A pointer to the associated arena, for huge allocations. + arena_t* mArena; + }; }; struct ExtentTreeSzTrait { static RedBlackTreeNode& GetTreeNode(extent_node_t* aThis) { - return aThis->link_szad; + return aThis->mLinkBySize; } static inline int Compare(extent_node_t* aNode, extent_node_t* aOther) { - int ret = (aNode->size > aOther->size) - (aNode->size < aOther->size); - return ret ? ret : CompareAddr(aNode->addr, aOther->addr); + int ret = (aNode->mSize > aOther->mSize) - (aNode->mSize < aOther->mSize); + return ret ? ret : CompareAddr(aNode->mAddr, aOther->mAddr); } }; @@ -651,12 +656,12 @@ struct ExtentTreeTrait { static RedBlackTreeNode& GetTreeNode(extent_node_t* aThis) { - return aThis->link_ad; + return aThis->mLinkByAddr; } static inline int Compare(extent_node_t* aNode, extent_node_t* aOther) { - return CompareAddr(aNode->addr, aOther->addr); + return CompareAddr(aNode->mAddr, aOther->mAddr); } }; @@ -664,9 +669,9 @@ struct ExtentTreeBoundsTrait : public ExtentTreeTrait { static inline int Compare(extent_node_t* aKey, extent_node_t* aNode) { - uintptr_t key_addr = reinterpret_cast(aKey->addr); - uintptr_t node_addr = reinterpret_cast(aNode->addr); - size_t node_size = aNode->size; + uintptr_t key_addr = reinterpret_cast(aKey->mAddr); + uintptr_t node_addr = reinterpret_cast(aNode->mAddr); + size_t node_size = aNode->mSize; // Is aKey within aNode? if (node_addr <= key_addr && key_addr < node_addr + node_size) { @@ -1246,13 +1251,13 @@ chunk_dealloc(void* aChunk, size_t aSize, ChunkType aType); static void chunk_ensure_zero(void* aPtr, size_t aSize, bool aZeroed); static void* -huge_malloc(size_t size, bool zero); +huge_malloc(size_t size, bool zero, arena_t* aArena); static void* -huge_palloc(size_t aSize, size_t aAlignment, bool aZero); +huge_palloc(size_t aSize, size_t aAlignment, bool aZero, arena_t* aArena); static void* -huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize); +huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize, arena_t* aArena); static void -huge_dalloc(void* aPtr); +huge_dalloc(void* aPtr, arena_t* aArena); #ifdef XP_WIN extern "C" #else @@ -1967,20 +1972,20 @@ chunk_recycle(size_t aSize, size_t aAlignment, bool* aZeroed) if (alloc_size < aSize) { return nullptr; } - key.addr = nullptr; - key.size = alloc_size; + key.mAddr = nullptr; + key.mSize = alloc_size; chunks_mtx.Lock(); extent_node_t* node = gChunksBySize.SearchOrNext(&key); if (!node) { chunks_mtx.Unlock(); return nullptr; } - size_t leadsize = ALIGNMENT_CEILING((uintptr_t)node->addr, aAlignment) - - (uintptr_t)node->addr; - MOZ_ASSERT(node->size >= leadsize + aSize); - size_t trailsize = node->size - leadsize - aSize; - void* ret = (void*)((uintptr_t)node->addr + leadsize); - ChunkType chunk_type = node->chunk_type; + size_t leadsize = ALIGNMENT_CEILING((uintptr_t)node->mAddr, aAlignment) - + (uintptr_t)node->mAddr; + MOZ_ASSERT(node->mSize >= leadsize + aSize); + size_t trailsize = node->mSize - leadsize - aSize; + void* ret = (void*)((uintptr_t)node->mAddr + leadsize); + ChunkType chunk_type = node->mChunkType; if (aZeroed) { *aZeroed = (chunk_type == ZEROED_CHUNK); } @@ -1989,7 +1994,7 @@ chunk_recycle(size_t aSize, size_t aAlignment, bool* aZeroed) gChunksByAddress.Remove(node); if (leadsize != 0) { // Insert the leading space as a smaller chunk. - node->size = leadsize; + node->mSize = leadsize; gChunksBySize.Insert(node); gChunksByAddress.Insert(node); node = nullptr; @@ -2010,9 +2015,9 @@ chunk_recycle(size_t aSize, size_t aAlignment, bool* aZeroed) } chunks_mtx.Lock(); } - node->addr = (void*)((uintptr_t)(ret) + aSize); - node->size = trailsize; - node->chunk_type = chunk_type; + node->mAddr = (void*)((uintptr_t)(ret) + aSize); + node->mSize = trailsize; + node->mChunkType = chunk_type; gChunksBySize.Insert(node); gChunksByAddress.Insert(node); node = nullptr; @@ -2125,18 +2130,18 @@ chunk_record(void* aChunk, size_t aSize, ChunkType aType) // RAII deallocates xnode and xprev defined above after unlocking // in order to avoid potential dead-locks MutexAutoLock lock(chunks_mtx); - key.addr = (void*)((uintptr_t)aChunk + aSize); + key.mAddr = (void*)((uintptr_t)aChunk + aSize); extent_node_t* node = gChunksByAddress.SearchOrNext(&key); // Try to coalesce forward. - if (node && node->addr == key.addr) { + if (node && node->mAddr == key.mAddr) { // Coalesce chunk with the following address range. This does // not change the position within gChunksByAddress, so only // remove/insert from/into gChunksBySize. gChunksBySize.Remove(node); - node->addr = aChunk; - node->size += aSize; - if (node->chunk_type != aType) { - node->chunk_type = RECYCLED_CHUNK; + node->mAddr = aChunk; + node->mSize += aSize; + if (node->mChunkType != aType) { + node->mChunkType = RECYCLED_CHUNK; } gChunksBySize.Insert(node); } else { @@ -2149,16 +2154,16 @@ chunk_record(void* aChunk, size_t aSize, ChunkType aType) return; } node = xnode.release(); - node->addr = aChunk; - node->size = aSize; - node->chunk_type = aType; + node->mAddr = aChunk; + node->mSize = aSize; + node->mChunkType = aType; gChunksByAddress.Insert(node); gChunksBySize.Insert(node); } // Try to coalesce backward. extent_node_t* prev = gChunksByAddress.Prev(node); - if (prev && (void*)((uintptr_t)prev->addr + prev->size) == aChunk) { + if (prev && (void*)((uintptr_t)prev->mAddr + prev->mSize) == aChunk) { // Coalesce chunk with the previous address range. This does // not change the position within gChunksByAddress, so only // remove/insert node from/into gChunksBySize. @@ -2166,10 +2171,10 @@ chunk_record(void* aChunk, size_t aSize, ChunkType aType) gChunksByAddress.Remove(prev); gChunksBySize.Remove(node); - node->addr = prev->addr; - node->size += prev->size; - if (node->chunk_type != prev->chunk_type) { - node->chunk_type = RECYCLED_CHUNK; + node->mAddr = prev->mAddr; + node->mSize += prev->mSize; + if (node->mChunkType != prev->mChunkType) { + node->mChunkType = RECYCLED_CHUNK; } gChunksBySize.Insert(node); @@ -3088,11 +3093,11 @@ imalloc(size_t aSize, bool aZero, arena_t* aArena) { MOZ_ASSERT(aSize != 0); + aArena = aArena ? aArena : choose_arena(aSize); if (aSize <= gMaxLargeClass) { - aArena = aArena ? aArena : choose_arena(aSize); return aArena->Malloc(aSize, aZero); } - return huge_malloc(aSize, aZero); + return huge_malloc(aSize, aZero, aArena); } // Only handles large allocations that require more than page alignment. @@ -3180,9 +3185,9 @@ ipalloc(size_t aAlignment, size_t aSize, arena_t* aArena) return nullptr; } + aArena = aArena ? aArena : choose_arena(aSize); if (ceil_size <= gPageSize || (aAlignment <= gPageSize && ceil_size <= gMaxLargeClass)) { - aArena = aArena ? aArena : choose_arena(aSize); ret = aArena->Malloc(ceil_size, false); } else { size_t run_size; @@ -3223,12 +3228,11 @@ ipalloc(size_t aAlignment, size_t aSize, arena_t* aArena) } if (run_size <= gMaxLargeClass) { - aArena = aArena ? aArena : choose_arena(aSize); ret = aArena->Palloc(aAlignment, ceil_size, run_size); } else if (aAlignment <= kChunkSize) { - ret = huge_malloc(ceil_size, false); + ret = huge_malloc(ceil_size, false, aArena); } else { - ret = huge_palloc(ceil_size, aAlignment, false); + ret = huge_palloc(ceil_size, aAlignment, false, aArena); } } @@ -3263,71 +3267,90 @@ arena_salloc(const void* ptr) return ret; } -// Validate ptr before assuming that it points to an allocation. Currently, -// the following validation is performed: -// -// + Check that ptr is not nullptr. -// -// + Check that ptr lies within a mapped chunk. -static inline size_t -isalloc_validate(const void* aPtr) +class AllocInfo { - // If the allocator is not initialized, the pointer can't belong to it. - if (malloc_initialized == false) { - return 0; +public: + template + static inline AllocInfo Get(const void* aPtr) + { + // If the allocator is not initialized, the pointer can't belong to it. + if (Validate && malloc_initialized == false) { + return AllocInfo(); + } + + auto chunk = GetChunkForPtr(aPtr); + if (Validate) { + if (!chunk || !gChunkRTree.Get(chunk)) { + return AllocInfo(); + } + } + + if (chunk != aPtr) { + MOZ_DIAGNOSTIC_ASSERT(chunk->arena->mMagic == ARENA_MAGIC); + return AllocInfo(arena_salloc(aPtr), chunk); + } + + extent_node_t key; + + // Huge allocation + key.mAddr = chunk; + MutexAutoLock lock(huge_mtx); + extent_node_t* node = huge.Search(&key); + if (Validate && !node) { + return AllocInfo(); + } + return AllocInfo(node->mSize, node); } - auto chunk = GetChunkForPtr(aPtr); - if (!chunk) { - return 0; + // Validate ptr before assuming that it points to an allocation. Currently, + // the following validation is performed: + // + // + Check that ptr is not nullptr. + // + // + Check that ptr lies within a mapped chunk. + static inline AllocInfo GetValidated(const void* aPtr) + { + return Get(aPtr); } - if (!gChunkRTree.Get(chunk)) { - return 0; + AllocInfo() + : mSize(0) + , mChunk(nullptr) + { } - if (chunk != aPtr) { - MOZ_DIAGNOSTIC_ASSERT(chunk->arena->mMagic == ARENA_MAGIC); - return arena_salloc(aPtr); + explicit AllocInfo(size_t aSize, arena_chunk_t* aChunk) + : mSize(aSize) + , mChunk(aChunk) + { + MOZ_ASSERT(mSize <= gMaxLargeClass); } - extent_node_t key; - - // Chunk. - key.addr = (void*)chunk; - MutexAutoLock lock(huge_mtx); - extent_node_t* node = huge.Search(&key); - if (node) { - return node->size; - } - return 0; -} - -static inline size_t -isalloc(const void* aPtr) -{ - MOZ_ASSERT(aPtr); - - auto chunk = GetChunkForPtr(aPtr); - if (chunk != aPtr) { - // Region. - MOZ_DIAGNOSTIC_ASSERT(chunk->arena->mMagic == ARENA_MAGIC); - - return arena_salloc(aPtr); + explicit AllocInfo(size_t aSize, extent_node_t* aNode) + : mSize(aSize) + , mNode(aNode) + { + MOZ_ASSERT(mSize > gMaxLargeClass); } - extent_node_t key; + size_t Size() { return mSize; } - // Chunk (huge allocation). - MutexAutoLock lock(huge_mtx); + arena_t* Arena() + { + return (mSize <= gMaxLargeClass) ? mChunk->arena : mNode->mArena; + } - // Extract from tree of huge allocations. - key.addr = const_cast(aPtr); - extent_node_t* node = huge.Search(&key); - MOZ_DIAGNOSTIC_ASSERT(node); +private: + size_t mSize; + union { + // Pointer to the chunk associated with the allocation for small + // and large allocations. + arena_chunk_t* mChunk; - return node->size; -} + // Pointer to the extent node for huge allocations. + extent_node_t* mNode; + }; +}; template<> inline void @@ -3350,13 +3373,13 @@ MozJemalloc::jemalloc_ptr_info(const void* aPtr, jemalloc_ptr_info_t* aInfo) extent_node_t key; { MutexAutoLock lock(huge_mtx); - key.addr = const_cast(aPtr); + key.mAddr = const_cast(aPtr); node = reinterpret_cast*>( &huge) ->Search(&key); if (node) { - *aInfo = { TagLiveHuge, node->addr, node->size }; + *aInfo = { TagLiveHuge, node->mAddr, node->mSize }; return; } } @@ -3561,7 +3584,7 @@ arena_t::DallocLarge(arena_chunk_t* aChunk, void* aPtr) } static inline void -arena_dalloc(void* aPtr, size_t aOffset) +arena_dalloc(void* aPtr, size_t aOffset, arena_t* aArena) { MOZ_ASSERT(aPtr); MOZ_ASSERT(aOffset != 0); @@ -3571,6 +3594,7 @@ arena_dalloc(void* aPtr, size_t aOffset) auto arena = chunk->arena; MOZ_ASSERT(arena); MOZ_DIAGNOSTIC_ASSERT(arena->mMagic == ARENA_MAGIC); + MOZ_RELEASE_ASSERT(!aArena || arena == aArena); MutexAutoLock lock(arena->mLock); size_t pageind = aOffset >> gPageSize2Pow; @@ -3586,7 +3610,7 @@ arena_dalloc(void* aPtr, size_t aOffset) } static inline void -idalloc(void* ptr) +idalloc(void* ptr, arena_t* aArena) { size_t offset; @@ -3594,9 +3618,9 @@ idalloc(void* ptr) offset = GetChunkOffsetForPtr(ptr); if (offset != 0) { - arena_dalloc(ptr, offset); + arena_dalloc(ptr, offset, aArena); } else { - huge_dalloc(ptr); + huge_dalloc(ptr, aArena); } } @@ -3660,7 +3684,7 @@ arena_t::RallocGrowLarge(arena_chunk_t* aChunk, // always fail if growing an object, and the following run is already in use. // Returns whether reallocation was successful. static bool -arena_ralloc_large(void* aPtr, size_t aSize, size_t aOldSize) +arena_ralloc_large(void* aPtr, size_t aSize, size_t aOldSize, arena_t* aArena) { size_t psize; @@ -3674,17 +3698,15 @@ arena_ralloc_large(void* aPtr, size_t aSize, size_t aOldSize) } arena_chunk_t* chunk = GetChunkForPtr(aPtr); - arena_t* arena = chunk->arena; - MOZ_DIAGNOSTIC_ASSERT(arena->mMagic == ARENA_MAGIC); if (psize < aOldSize) { // Fill before shrinking in order avoid a race. memset((void*)((uintptr_t)aPtr + aSize), kAllocPoison, aOldSize - aSize); - arena->RallocShrinkLarge(chunk, aPtr, psize, aOldSize); + aArena->RallocShrinkLarge(chunk, aPtr, psize, aOldSize); return true; } - bool ret = arena->RallocGrowLarge(chunk, aPtr, psize, aOldSize); + bool ret = aArena->RallocGrowLarge(chunk, aPtr, psize, aOldSize); if (ret && opt_zero) { memset((void*)((uintptr_t)aPtr + aOldSize), 0, aSize - aOldSize); } @@ -3710,7 +3732,7 @@ arena_ralloc(void* aPtr, size_t aSize, size_t aOldSize, arena_t* aArena) } } else if (aOldSize > gMaxBinClass && aOldSize <= gMaxLargeClass) { MOZ_ASSERT(aSize > gMaxBinClass); - if (arena_ralloc_large(aPtr, aSize, aOldSize)) { + if (arena_ralloc_large(aPtr, aSize, aOldSize, aArena)) { return aPtr; } } @@ -3718,7 +3740,6 @@ arena_ralloc(void* aPtr, size_t aSize, size_t aOldSize, arena_t* aArena) // If we get here, then aSize and aOldSize are different enough that we // need to move the object. In that case, fall back to allocating new // space and copying. - aArena = aArena ? aArena : choose_arena(aSize); ret = aArena->Malloc(aSize, false); if (!ret) { return nullptr; @@ -3734,22 +3755,25 @@ arena_ralloc(void* aPtr, size_t aSize, size_t aOldSize, arena_t* aArena) { memcpy(ret, aPtr, copysize); } - idalloc(aPtr); + idalloc(aPtr, aArena); return ret; } static inline void* iralloc(void* aPtr, size_t aSize, arena_t* aArena) { - size_t oldsize; - MOZ_ASSERT(aPtr); MOZ_ASSERT(aSize != 0); - oldsize = isalloc(aPtr); + auto info = AllocInfo::Get(aPtr); + auto arena = info.Arena(); + MOZ_RELEASE_ASSERT(!aArena || arena == aArena); + aArena = aArena ? aArena : arena; + size_t oldsize = info.Size(); + MOZ_DIAGNOSTIC_ASSERT(aArena->mMagic == ARENA_MAGIC); return (aSize <= gMaxLargeClass) ? arena_ralloc(aPtr, aSize, oldsize, aArena) - : huge_ralloc(aPtr, aSize, oldsize); + : huge_ralloc(aPtr, aSize, oldsize, aArena); } arena_t::arena_t() @@ -3826,13 +3850,13 @@ ArenaCollection::CreateArena(bool aIsPrivate) // Begin general internal functions. static void* -huge_malloc(size_t size, bool zero) +huge_malloc(size_t size, bool zero, arena_t* aArena) { - return huge_palloc(size, kChunkSize, zero); + return huge_palloc(size, kChunkSize, zero, aArena); } static void* -huge_palloc(size_t aSize, size_t aAlignment, bool aZero) +huge_palloc(size_t aSize, size_t aAlignment, bool aZero, arena_t* aArena) { void* ret; size_t csize; @@ -3863,9 +3887,10 @@ huge_palloc(size_t aSize, size_t aAlignment, bool aZero) } // Insert node into huge. - node->addr = ret; + node->mAddr = ret; psize = PAGE_CEILING(aSize); - node->size = psize; + node->mSize = psize; + node->mArena = aArena ? aArena : choose_arena(aSize); { MutexAutoLock lock(huge_mtx); @@ -3884,7 +3909,7 @@ huge_palloc(size_t aSize, size_t aAlignment, bool aZero) // // A correct program will only touch memory in excess of how much it // requested if it first calls malloc_usable_size and finds out how - // much space it has to play with. But because we set node->size = + // much space it has to play with. But because we set node->mSize = // psize above, malloc_usable_size will return psize, not csize, and // the program will (hopefully) never touch bytes in excess of psize. // Thus those bytes won't take up space in physical memory, and we can @@ -3919,7 +3944,7 @@ huge_palloc(size_t aSize, size_t aAlignment, bool aZero) } static void* -huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize) +huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize, arena_t* aArena) { void* ret; size_t copysize; @@ -3939,13 +3964,14 @@ huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize) // Update recorded size. MutexAutoLock lock(huge_mtx); - key.addr = const_cast(aPtr); + key.mAddr = const_cast(aPtr); extent_node_t* node = huge.Search(&key); MOZ_ASSERT(node); - MOZ_ASSERT(node->size == aOldSize); + MOZ_ASSERT(node->mSize == aOldSize); + MOZ_RELEASE_ASSERT(!aArena || node->mArena == aArena); huge_allocated -= aOldSize - psize; // No need to change huge_mapped, because we didn't (un)map anything. - node->size = psize; + node->mSize = psize; } else if (psize > aOldSize) { if (!pages_commit((void*)((uintptr_t)aPtr + aOldSize), psize - aOldSize)) { @@ -3963,14 +3989,15 @@ huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize) // Update recorded size. extent_node_t key; MutexAutoLock lock(huge_mtx); - key.addr = const_cast(aPtr); + key.mAddr = const_cast(aPtr); extent_node_t* node = huge.Search(&key); MOZ_ASSERT(node); - MOZ_ASSERT(node->size == aOldSize); + MOZ_ASSERT(node->mSize == aOldSize); + MOZ_RELEASE_ASSERT(!aArena || node->mArena == aArena); huge_allocated += psize - aOldSize; // No need to change huge_mapped, because we didn't // (un)map anything. - node->size = psize; + node->mSize = psize; } if (opt_zero && aSize > aOldSize) { @@ -3982,7 +4009,7 @@ huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize) // If we get here, then aSize and aOldSize are different enough that we // need to use a different size class. In that case, fall back to // allocating new space and copying. - ret = huge_malloc(aSize, false); + ret = huge_malloc(aSize, false, aArena); if (!ret) { return nullptr; } @@ -3996,12 +4023,12 @@ huge_ralloc(void* aPtr, size_t aSize, size_t aOldSize) { memcpy(ret, aPtr, copysize); } - idalloc(aPtr); + idalloc(aPtr, aArena); return ret; } static void -huge_dalloc(void* aPtr) +huge_dalloc(void* aPtr, arena_t* aArena) { extent_node_t* node; { @@ -4009,18 +4036,19 @@ huge_dalloc(void* aPtr) MutexAutoLock lock(huge_mtx); // Extract from tree of huge allocations. - key.addr = aPtr; + key.mAddr = aPtr; node = huge.Search(&key); MOZ_ASSERT(node); - MOZ_ASSERT(node->addr == aPtr); + MOZ_ASSERT(node->mAddr == aPtr); + MOZ_RELEASE_ASSERT(!aArena || node->mArena == aArena); huge.Remove(node); - huge_allocated -= node->size; - huge_mapped -= CHUNK_CEILING(node->size); + huge_allocated -= node->mSize; + huge_mapped -= CHUNK_CEILING(node->mSize); } // Unmap chunk. - chunk_dealloc(node->addr, CHUNK_CEILING(node->size), HUGE_CHUNK); + chunk_dealloc(node->mAddr, CHUNK_CEILING(node->mSize), HUGE_CHUNK); base_node_dealloc(node); } @@ -4350,10 +4378,10 @@ BaseAllocator::free(void* aPtr) offset = GetChunkOffsetForPtr(aPtr); if (offset != 0) { MOZ_RELEASE_ASSERT(malloc_initialized); - arena_dalloc(aPtr, offset); + arena_dalloc(aPtr, offset, mArena); } else if (aPtr) { MOZ_RELEASE_ASSERT(malloc_initialized); - huge_dalloc(aPtr); + huge_dalloc(aPtr, mArena); } } @@ -4446,7 +4474,7 @@ template<> inline size_t MozJemalloc::malloc_usable_size(usable_ptr_t aPtr) { - return isalloc_validate(aPtr); + return AllocInfo::GetValidated(aPtr).Size(); } template<> @@ -4684,9 +4712,8 @@ inline void MozJemalloc::moz_dispose_arena(arena_id_t aArenaId) { arena_t* arena = gArenas.GetById(aArenaId, /* IsPrivate = */ true); - if (arena) { - gArenas.DisposeArena(arena); - } + MOZ_RELEASE_ASSERT(arena); + gArenas.DisposeArena(arena); } #define MALLOC_DECL(name, return_type, ...) \ @@ -5012,7 +5039,7 @@ MOZ_EXPORT void* (*__memalign_hook)(size_t, size_t) = memalign_impl; void* _recalloc(void* aPtr, size_t aCount, size_t aSize) { - size_t oldsize = aPtr ? isalloc(aPtr) : 0; + size_t oldsize = aPtr ? AllocInfo::Get(aPtr).Size() : 0; CheckedInt checkedSize = CheckedInt(aCount) * aSize; if (!checkedSize.isValid()) { @@ -5039,7 +5066,7 @@ _recalloc(void* aPtr, size_t aCount, size_t aSize) void* _expand(void* aPtr, size_t newsize) { - if (isalloc(aPtr) >= newsize) { + if (AllocInfo::Get(aPtr).Size() >= newsize) { return aPtr; } diff --git a/memory/gtest/TestJemalloc.cpp b/memory/gtest/TestJemalloc.cpp index 6da2d06b1a51..e172493cdea9 100644 --- a/memory/gtest/TestJemalloc.cpp +++ b/memory/gtest/TestJemalloc.cpp @@ -12,6 +12,39 @@ #include "gtest/gtest.h" +#ifdef MOZ_CRASHREPORTER +#include "nsCOMPtr.h" +#include "nsICrashReporter.h" +#include "nsServiceManagerUtils.h" +#endif + +#if defined(DEBUG) && !defined(XP_WIN) && !defined(ANDROID) +#define HAS_GDB_SLEEP_DURATION 1 +extern unsigned int _gdb_sleep_duration; +#endif + +// Death tests are too slow on OSX because of the system crash reporter. +#ifndef XP_DARWIN +static void DisableCrashReporter() +{ +#ifdef MOZ_CRASHREPORTER + nsCOMPtr crashreporter = + do_GetService("@mozilla.org/toolkit/crash-reporter;1"); + if (crashreporter) { + crashreporter->SetEnabled(false); + } +#endif +} + +// Wrap ASSERT_DEATH_IF_SUPPORTED to disable the crash reporter +// when entering the subprocess, so that the expected crashes don't +// create a minidump that the gtest harness will interpret as an error. +#define ASSERT_DEATH_WRAP(a, b) \ + ASSERT_DEATH_IF_SUPPORTED({ DisableCrashReporter(); a; }, b) +#else +#define ASSERT_DEATH_WRAP(a, b) +#endif + using namespace mozilla; static inline void @@ -223,3 +256,58 @@ TEST(Jemalloc, PtrInfo) jemalloc_thread_local_arena(false); } + +#ifdef NIGHTLY_BUILD +TEST(Jemalloc, Arenas) +{ + arena_id_t arena = moz_create_arena(); + ASSERT_TRUE(arena != 0); + void* ptr = moz_arena_malloc(arena, 42); + ASSERT_TRUE(ptr != nullptr); + ptr = moz_arena_realloc(arena, ptr, 64); + ASSERT_TRUE(ptr != nullptr); + moz_arena_free(arena, ptr); + ptr = moz_arena_calloc(arena, 24, 2); + // For convenience, free can be used to free arena pointers. + free(ptr); + moz_dispose_arena(arena); + +#ifdef HAS_GDB_SLEEP_DURATION + // Avoid death tests adding some unnecessary (long) delays. + unsigned int old_gdb_sleep_duration = _gdb_sleep_duration; + _gdb_sleep_duration = 0; +#endif + + // Can't use an arena after it's disposed. + ASSERT_DEATH_WRAP(moz_arena_malloc(arena, 80), ""); + + // Arena id 0 can't be used to somehow get to the main arena. + ASSERT_DEATH_WRAP(moz_arena_malloc(0, 80), ""); + + arena = moz_create_arena(); + arena_id_t arena2 = moz_create_arena(); + + // For convenience, realloc can also be used to reallocate arena pointers. + // The result should be in the same arena. Test various size class transitions. + size_t sizes[] = { 1, 42, 80, 1_KiB, 1.5_KiB, 72_KiB, 129_KiB, 2.5_MiB, 5.1_MiB }; + for (size_t from_size : sizes) { + for (size_t to_size : sizes) { + ptr = moz_arena_malloc(arena, from_size); + ptr = realloc(ptr, to_size); + // Freeing with the wrong arena should crash. + ASSERT_DEATH_WRAP(moz_arena_free(arena2, ptr), ""); + // Likewise for moz_arena_realloc. + ASSERT_DEATH_WRAP(moz_arena_realloc(arena2, ptr, from_size), ""); + // The following will crash if it's not in the right arena. + moz_arena_free(arena, ptr); + } + } + + moz_dispose_arena(arena2); + moz_dispose_arena(arena); + +#ifdef HAS_GDB_SLEEP_DURATION + _gdb_sleep_duration = old_gdb_sleep_duration; +#endif +} +#endif diff --git a/mfbt/Maybe.h b/mfbt/Maybe.h index e701e1c7fc47..98f44fb33efe 100644 --- a/mfbt/Maybe.h +++ b/mfbt/Maybe.h @@ -225,11 +225,7 @@ public: bool isNothing() const { return !mIsSome; } /* Returns the contents of this Maybe by value. Unsafe unless |isSome()|. */ - T value() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } + T value() const; /* * Returns the contents of this Maybe by value. If |isNothing()|, returns @@ -258,17 +254,8 @@ public: } /* Returns the contents of this Maybe by pointer. Unsafe unless |isSome()|. */ - T* ptr() - { - MOZ_ASSERT(mIsSome); - return &ref(); - } - - const T* ptr() const - { - MOZ_ASSERT(mIsSome); - return &ref(); - } + T* ptr(); + const T* ptr() const; /* * Returns the contents of this Maybe by pointer. If |isNothing()|, @@ -312,30 +299,12 @@ public: return aFunc(); } - T* operator->() - { - MOZ_ASSERT(mIsSome); - return ptr(); - } - - const T* operator->() const - { - MOZ_ASSERT(mIsSome); - return ptr(); - } + T* operator->(); + const T* operator->() const; /* Returns the contents of this Maybe by ref. Unsafe unless |isSome()|. */ - T& ref() - { - MOZ_ASSERT(mIsSome); - return *static_cast(data()); - } - - const T& ref() const - { - MOZ_ASSERT(mIsSome); - return *static_cast(data()); - } + T& ref(); + const T& ref() const; /* * Returns the contents of this Maybe by ref. If |isNothing()|, returns @@ -379,17 +348,8 @@ public: return aFunc(); } - T& operator*() - { - MOZ_ASSERT(mIsSome); - return ref(); - } - - const T& operator*() const - { - MOZ_ASSERT(mIsSome); - return ref(); - } + T& operator*(); + const T& operator*() const; /* If |isSome()|, runs the provided function or functor on the contents of * this Maybe. */ @@ -453,12 +413,7 @@ public: * arguments to |emplace()| are the parameters to T's constructor. */ template - void emplace(Args&&... aArgs) - { - MOZ_ASSERT(!mIsSome); - ::new (KnownNotNull, data()) T(Forward(aArgs)...); - mIsSome = true; - } + void emplace(Args&&... aArgs); friend std::ostream& operator<<(std::ostream& aStream, const Maybe& aMaybe) @@ -472,6 +427,88 @@ public: } }; +template +T +Maybe::value() const +{ + MOZ_RELEASE_ASSERT(mIsSome); + return ref(); +} + +template +T* +Maybe::ptr() +{ + MOZ_RELEASE_ASSERT(mIsSome); + return &ref(); +} + +template +const T* +Maybe::ptr() const +{ + MOZ_RELEASE_ASSERT(mIsSome); + return &ref(); +} + +template +T* +Maybe::operator->() +{ + MOZ_RELEASE_ASSERT(mIsSome); + return ptr(); +} + +template +const T* +Maybe::operator->() const +{ + MOZ_RELEASE_ASSERT(mIsSome); + return ptr(); +} + +template +T& +Maybe::ref() +{ + MOZ_RELEASE_ASSERT(mIsSome); + return *static_cast(data()); +} + +template +const T& +Maybe::ref() const +{ + MOZ_RELEASE_ASSERT(mIsSome); + return *static_cast(data()); +} + +template +T& +Maybe::operator*() +{ + MOZ_RELEASE_ASSERT(mIsSome); + return ref(); +} + +template +const T& +Maybe::operator*() const +{ + MOZ_RELEASE_ASSERT(mIsSome); + return ref(); +} + +template +template +void +Maybe::emplace(Args&&... aArgs) +{ + MOZ_RELEASE_ASSERT(!mIsSome); + ::new (KnownNotNull, data()) T(Forward(aArgs)...); + mIsSome = true; +} + /* * Some() creates a Maybe value containing the provided T value. If T has a * move constructor, it's used to make this as efficient as possible. diff --git a/mobile/android/chrome/content/about.js b/mobile/android/chrome/content/about.js index 00af77b27f95..4e9e32a878b3 100644 --- a/mobile/android/chrome/content/about.js +++ b/mobile/android/chrome/content/about.js @@ -30,7 +30,7 @@ function init() { distroIdField.textContent = distroId + " - " + distroVersion; distroIdField.hidden = false; - let distroAbout = Services.prefs.getComplexValue("distribution.about", Ci.nsISupportsString); + let distroAbout = Services.prefs.getStringPref("distribution.about"); let distroField = document.getElementById("distributionAbout"); distroField.textContent = distroAbout; distroField.hidden = false; diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java index 63c229d4c363..56188b77a3ab 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java @@ -476,11 +476,6 @@ public class GeckoSession implements Parcelable { preload(appContext, /* geckoArgs */ null, multiprocess); } - if (mSettings.getString(GeckoSessionSettings.DATA_DIR) == null) { - mSettings.setString(GeckoSessionSettings.DATA_DIR, - appContext.getApplicationInfo().dataDir); - } - final String chromeUri = mSettings.getString(GeckoSessionSettings.CHROME_URI); final int screenId = mSettings.getInt(GeckoSessionSettings.SCREEN_ID); final boolean isPrivate = mSettings.getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSessionSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSessionSettings.java index 8e401e917c99..e7cfa3de672f 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSessionSettings.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSessionSettings.java @@ -84,12 +84,6 @@ public final class GeckoSessionSettings implements Parcelable { public static final Key USE_REMOTE_DEBUGGER = new Key("useRemoteDebugger"); - public static final Key DEBUGGER_SOCKET_DIR = - new Key("debuggerSocketDir"); - - /* package */ static final Key DATA_DIR = - new Key("dataDir", /* initOnly */ true, /* values */ null); - private final GeckoSession mSession; private final GeckoBundle mBundle; @@ -108,7 +102,6 @@ public final class GeckoSessionSettings implements Parcelable { mBundle.putBoolean(USE_MULTIPROCESS.name, true); mBundle.putInt(DISPLAY_MODE.name, DISPLAY_MODE_BROWSER); mBundle.putBoolean(USE_REMOTE_DEBUGGER.name, false); - mBundle.putString(DEBUGGER_SOCKET_DIR.name, null); } /* package */ GeckoSessionSettings(final GeckoSessionSettings settings, diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java index 5d8909766ca9..2b7dd781a5b0 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java @@ -125,6 +125,13 @@ public final class GeckoLoader { } } + try { + final File dataDir = new File(context.getApplicationInfo().dataDir); + putenv("MOZ_ANDROID_DATA_DIR=" + dataDir.getCanonicalPath()); + } catch (final java.io.IOException e) { + Log.e(LOGTAG, "Failed to resolve app data directory"); + } + putenv("MOZ_ANDROID_PACKAGE_NAME=" + context.getPackageName()); setupDownloadEnvironment(context); diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in index 3f7ec4fd3994..59b2ab2f2893 100644 --- a/mobile/android/installer/package-manifest.in +++ b/mobile/android/installer/package-manifest.in @@ -131,7 +131,6 @@ @BINPATH@/components/dom_notification.xpt @BINPATH@/components/dom_html.xpt @BINPATH@/components/dom_offline.xpt -@BINPATH@/components/dom_json.xpt @BINPATH@/components/dom_payments.xpt @BINPATH@/components/dom_power.xpt #ifdef MOZ_ANDROID_GCM diff --git a/mobile/android/modules/geckoview/GeckoViewRemoteDebugger.jsm b/mobile/android/modules/geckoview/GeckoViewRemoteDebugger.jsm index 25ead7c4afb4..4fe8948955f2 100644 --- a/mobile/android/modules/geckoview/GeckoViewRemoteDebugger.jsm +++ b/mobile/android/modules/geckoview/GeckoViewRemoteDebugger.jsm @@ -50,15 +50,23 @@ class GeckoViewRemoteDebugger extends GeckoViewModule { "resource://gre/modules/dbg-browser-actors.js"); DebuggerServer.allowChromeProcess = true; } - this._isEnabled = true; - this._usbDebugger.stop(); let windowId = this.window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils) .outerWindowID; - let portOrPath = (this.settings.debuggerSocketDir || this.settings.dataDir) + - "/firefox-debugger-socket-" + - windowId; + let env = Cc["@mozilla.org/process/environment;1"] + .getService(Ci.nsIEnvironment); + let dataDir = env.get("MOZ_ANDROID_DATA_DIR"); + + if (!dataDir) { + debug("Missing env MOZ_ANDROID_DATA_DIR - aborting debugger server start"); + return; + } + + this._isEnabled = true; + this._usbDebugger.stop(); + + let portOrPath = dataDir + "/firefox-debugger-socket-" + windowId; this._usbDebugger.start(portOrPath); } diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index aaff8015a5c3..4081e3ce4ebd 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -2563,20 +2563,6 @@ nsPrefBranch::GetComplexValue(const char* aPrefName, return NS_OK; } - if (aType.Equals(NS_GET_IID(nsISupportsString))) { - nsCOMPtr theString( - do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv)); - - if (NS_SUCCEEDED(rv)) { - // Debugging to see why we end up with very long strings here with - // some addons, see bug 836263. - NS_ConvertUTF8toUTF16 wdata(utf8String); - theString->SetData(wdata); - theString.forget(reinterpret_cast(aRetVal)); - } - return rv; - } - NS_WARNING("nsPrefBranch::GetComplexValue - Unsupported interface type"); return NS_NOINTERFACE; } @@ -2708,8 +2694,7 @@ nsPrefBranch::SetComplexValue(const char* aPrefName, return SetCharPrefInternal(aPrefName, descriptorString); } - if (aType.Equals(NS_GET_IID(nsISupportsString)) || - aType.Equals(NS_GET_IID(nsIPrefLocalizedString))) { + if (aType.Equals(NS_GET_IID(nsIPrefLocalizedString))) { nsCOMPtr theString = do_QueryInterface(aValue); if (theString) { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index d97e74b85d4e..7466759f3caa 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5147,7 +5147,7 @@ pref("dom.w3c_touch_events.enabled", 2); #endif // W3C draft pointer events -#if !defined(ANDROID) && defined(NIGHTLY_BUILD) +#if !defined(ANDROID) && defined(EARLY_BETA_OR_EARLIER) pref("dom.w3c_pointer_events.enabled", true); #else pref("dom.w3c_pointer_events.enabled", false); diff --git a/modules/libpref/nsIPrefBranch.idl b/modules/libpref/nsIPrefBranch.idl index 90ee00874874..39cc234a84b4 100644 --- a/modules/libpref/nsIPrefBranch.idl +++ b/modules/libpref/nsIPrefBranch.idl @@ -191,8 +191,6 @@ interface nsIPrefBranch : nsISupports * @param aType The XPCOM interface that this complex preference * represents. Interfaces currently supported are: * - nsIFile - * - nsISupportsString (UniChar) - * (deprecated; see getStringPref) * - nsIPrefLocalizedString (Localized UniChar) * @param aValue The XPCOM object into which to the complex preference * value should be retrieved. diff --git a/modules/libpref/test/unit/test_defaultValues.js b/modules/libpref/test/unit/test_defaultValues.js index 5b73c0ce69f0..8384f7accc60 100644 --- a/modules/libpref/test/unit/test_defaultValues.js +++ b/modules/libpref/test/unit/test_defaultValues.js @@ -36,13 +36,6 @@ function run_test() { ps.setStringPref(prefName, "éèçàê€"); strictEqual(ps.getStringPref(prefName), "éèçàê€"); strictEqual(ps.getStringPref(prefName, "string"), "éèçàê€"); - strictEqual(ps.getStringPref(prefName), - ps.getComplexValue(prefName, Ci.nsISupportsString).data); - let str = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - str.data = "ù€ÚîœïŒëøÇ“"; - ps.setComplexValue(prefName, Ci.nsISupportsString, str); - strictEqual(ps.getStringPref(prefName), "ù€ÚîœïŒëøÇ“"); prefName = "test.default.values.float"; do_check_throws(function() { ps.getFloatPref(prefName); }, diff --git a/modules/libpref/test/unit/test_libPrefs.js b/modules/libpref/test/unit/test_libPrefs.js index ad7ea610a51a..c269fe3f646a 100644 --- a/modules/libpref/test/unit/test_libPrefs.js +++ b/modules/libpref/test/unit/test_libPrefs.js @@ -48,9 +48,9 @@ function run_test() { do_check_throws(function() { pb.setCharPref(null, null); }, Cr.NS_ERROR_INVALID_ARG); do_check_throws(function() { - pb.getComplexValue(null, Components.interfaces.nsISupportsString); }, Cr.NS_ERROR_INVALID_ARG); + pb.getStringPref(null); }, Cr.NS_ERROR_INVALID_ARG); do_check_throws(function() { - pb.setComplexValue(null, Components.interfaces.nsISupportsString, pb); }, Cr.NS_ERROR_INVALID_ARG); + pb.setStringPref(null, null); }, Cr.NS_ERROR_INVALID_ARG); do_check_throws(function() { pb.clearUserPref(null); }, Cr.NS_ERROR_INVALID_ARG); do_check_throws(function() { diff --git a/netwerk/dns/nsIDNService.cpp b/netwerk/dns/nsIDNService.cpp index c13f10927a27..f9f71635792a 100644 --- a/netwerk/dns/nsIDNService.cpp +++ b/netwerk/dns/nsIDNService.cpp @@ -102,14 +102,14 @@ void nsIDNService::prefsChanged(nsIPrefBranch *prefBranch, const char16_t *pref) mLock.AssertCurrentThreadOwns(); if (!pref || NS_LITERAL_STRING(NS_NET_PREF_IDNBLACKLIST).Equals(pref)) { - nsCOMPtr blacklist; - nsresult rv = prefBranch->GetComplexValue(NS_NET_PREF_IDNBLACKLIST, - NS_GET_IID(nsISupportsString), - getter_AddRefs(blacklist)); - if (NS_SUCCEEDED(rv)) - blacklist->ToString(getter_Copies(mIDNBlacklist)); - else + nsAutoCString blacklist; + nsresult rv = prefBranch->GetStringPref(NS_NET_PREF_IDNBLACKLIST, + EmptyCString(), 0, blacklist); + if (NS_SUCCEEDED(rv)) { + CopyUTF8toUTF16(blacklist, mIDNBlacklist); + } else { mIDNBlacklist.Truncate(); + } } if (!pref || NS_LITERAL_STRING(NS_NET_PREF_SHOWPUNYCODE).Equals(pref)) { bool val; diff --git a/netwerk/ipc/NeckoChild.cpp b/netwerk/ipc/NeckoChild.cpp index ca068ca3c109..14d6e68bf145 100644 --- a/netwerk/ipc/NeckoChild.cpp +++ b/netwerk/ipc/NeckoChild.cpp @@ -206,7 +206,7 @@ PWebSocketEventListenerChild* NeckoChild::AllocPWebSocketEventListenerChild(const uint64_t& aInnerWindowID) { nsCOMPtr target; - if (nsGlobalWindow* win = nsGlobalWindow::GetInnerWindowWithId(aInnerWindowID)) { + if (nsGlobalWindowInner* win = nsGlobalWindowInner::GetInnerWindowWithId(aInnerWindowID)) { target = win->EventTargetFor(TaskCategory::Other); } diff --git a/security/manager/ssl/nsNSSIOLayer.cpp b/security/manager/ssl/nsNSSIOLayer.cpp index d6abfb75d23d..4c44838cff14 100644 --- a/security/manager/ssl/nsNSSIOLayer.cpp +++ b/security/manager/ssl/nsNSSIOLayer.cpp @@ -2605,7 +2605,7 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS, if (getTLSProviderFlagAltHandshake(infoObject->GetProviderTlsFlags())) { MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("[%p] nsSSLIOLayerSetOptions: Use AltHandshake\n", fd)); - if (SECSuccess != SSL_UseAltHandshakeType(fd, PR_TRUE)) { + if (SECSuccess != SSL_UseAltServerHelloType(fd, PR_TRUE)) { MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("[%p] nsSSLIOLayerSetOptions: Use AltHandshake failed\n", fd)); // continue on default path diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index bf1e767417b3..800b20871b8b 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_34_BETA3 +NSS_3_34_BETA5 diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 0dcc2ce65d56..87229085ab5e 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -1183,7 +1183,7 @@ run_client(void) /* Alternate ServerHello content type (TLS 1.3 only) */ if (enableAltServerHello) { - rv = SSL_UseAltHandshakeType(s, PR_TRUE); + rv = SSL_UseAltServerHelloType(s, PR_TRUE); if (rv != SECSuccess) { SECU_PrintError(progName, "error enabling alternate ServerHello type"); error = 1; diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 5182f75552c8..590d1bfaeee3 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,3 +10,4 @@ */ #error "Do not include this header file." + diff --git a/security/nss/gtests/ssl_gtest/tls_agent.cc b/security/nss/gtests/ssl_gtest/tls_agent.cc index 77b848b9ce4c..dd096e98018f 100644 --- a/security/nss/gtests/ssl_gtest/tls_agent.cc +++ b/security/nss/gtests/ssl_gtest/tls_agent.cc @@ -387,7 +387,7 @@ void TlsAgent::SetShortHeadersEnabled() { void TlsAgent::SetAltHandshakeTypeEnabled() { EXPECT_TRUE(EnsureTlsSetup()); - SECStatus rv = SSL_UseAltHandshakeType(ssl_fd(), PR_TRUE); + SECStatus rv = SSL_UseAltServerHelloType(ssl_fd(), PR_TRUE); EXPECT_EQ(SECSuccess, rv); } diff --git a/security/nss/lib/ssl/sslexp.h b/security/nss/lib/ssl/sslexp.h index fd87effc9042..688903e9ae06 100644 --- a/security/nss/lib/ssl/sslexp.h +++ b/security/nss/lib/ssl/sslexp.h @@ -26,8 +26,8 @@ SEC_BEGIN_PROTOS * This will either become part of the standard or be disabled * after we have tested it. */ -#define SSL_UseAltHandshakeType(fd, enable) \ - SSL_EXPERIMENTAL_API("SSL_UseAltHandshakeType", \ +#define SSL_UseAltServerHelloType(fd, enable) \ + SSL_EXPERIMENTAL_API("SSL_UseAltServerHelloType", \ (PRFileDesc * _fd, PRBool _enable), \ (fd, enable)) diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 28c7a3c65a52..b3a6f1d76d4d 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -3875,7 +3875,7 @@ struct { void *function; } ssl_experimental_functions[] = { #ifndef SSL_DISABLE_EXPERIMENTAL_API - EXP(UseAltHandshakeType), + EXP(UseAltServerHelloType), #endif { "", NULL } }; diff --git a/security/nss/lib/ssl/tls13con.c b/security/nss/lib/ssl/tls13con.c index eb3ed8f96c71..c80dccc2ec22 100644 --- a/security/nss/lib/ssl/tls13con.c +++ b/security/nss/lib/ssl/tls13con.c @@ -4612,13 +4612,13 @@ tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions) } SECStatus -SSLExp_UseAltHandshakeType(PRFileDesc *fd, PRBool enable) +SSLExp_UseAltServerHelloType(PRFileDesc *fd, PRBool enable) { sslSocket *ss; ss = ssl_FindSocket(fd); if (!ss || IS_DTLS(ss)) { - SSL_DBG(("%d: SSL[%d]: bad socket in SSLExp_UseAltHandshakeType", + SSL_DBG(("%d: SSL[%d]: bad socket in SSLExp_UseAltServerHelloType", SSL_GETPID(), fd)); PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; diff --git a/security/nss/lib/ssl/tls13con.h b/security/nss/lib/ssl/tls13con.h index 7ec6168a78b7..906a0ab4cad0 100644 --- a/security/nss/lib/ssl/tls13con.h +++ b/security/nss/lib/ssl/tls13con.h @@ -85,7 +85,7 @@ PRUint16 tls13_EncodeAltDraftVersion(SSL3ProtocolVersion version); SECStatus tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions); SECStatus tls13_SendNewSessionTicket(sslSocket *ss); -SECStatus SSLExp_UseAltHandshakeType(PRFileDesc *fd, PRBool enable); +SECStatus SSLExp_UseAltServerHelloType(PRFileDesc *fd, PRBool enable); void tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec); #endif /* __tls13con_h_ */ diff --git a/services/sync/tests/unit/head_helpers.js b/services/sync/tests/unit/head_helpers.js index 53a650da45a1..8fa9f71745fe 100644 --- a/services/sync/tests/unit/head_helpers.js +++ b/services/sync/tests/unit/head_helpers.js @@ -36,15 +36,16 @@ Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js", XPCOMUtils.defineLazyGetter(this, "SyncPingSchema", function() { let ns = {}; Cu.import("resource://gre/modules/FileUtils.jsm", ns); + Cu.import("resource://gre/modules/NetUtil.jsm", ns); let stream = Cc["@mozilla.org/network/file-input-stream;1"] .createInstance(Ci.nsIFileInputStream); - let jsonReader = Cc["@mozilla.org/dom/json;1"] - .createInstance(Components.interfaces.nsIJSON); let schema; try { let schemaFile = do_get_file("sync_ping_schema.json"); stream.init(schemaFile, ns.FileUtils.MODE_RDONLY, ns.FileUtils.PERMS_FILE, 0); - schema = jsonReader.decodeFromStream(stream, stream.available()); + + let bytes = ns.NetUtil.readInputStream(stream, stream.available()); + schema = JSON.parse((new TextDecoder()).decode(bytes)); } finally { stream.close(); } diff --git a/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js b/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js new file mode 100644 index 000000000000..3b355ce8a34f --- /dev/null +++ b/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js @@ -0,0 +1,453 @@ +/* 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/. */ + +var EXPORTED_SYMBOLS = ["applicationName", "assert", "Copy", "getBrowserObject", + "getChromeWindow", "getWindows", "getWindowByTitle", + "getWindowByType", "getWindowId", "getMethodInWindows", + "getPreference", "saveDataURL", "setPreference", + "sleep", "startTimer", "stopTimer", "takeScreenshot", + "unwrapNode", "waitFor" + ]; + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + + +Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +const applicationIdMap = { + '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': 'Firefox' +} +const applicationName = applicationIdMap[Services.appinfo.ID] || Services.appinfo.name; + +var assertions = {}; Cu.import('resource://mozmill/modules/assertions.js', assertions); +var broker = {}; Cu.import('resource://mozmill/driver/msgbroker.js', broker); +var errors = {}; Cu.import('resource://mozmill/modules/errors.js', errors); + +var assert = new assertions.Assert(); + +var hwindow = Services.appShell.hiddenDOMWindow; + +var uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator); + +function Copy (obj) { + for (var n in obj) { + this[n] = obj[n]; + } +} + +/** + * Returns the browser object of the specified window + * + * @param {Window} aWindow + * Window to get the browser element from. + * + * @returns {Object} The browser element + */ +function getBrowserObject(aWindow) { + return aWindow.gBrowser; +} + +function getChromeWindow(aWindow) { + var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow) + .QueryInterface(Ci.nsIDOMChromeWindow); + + return chromeWin; +} + +function getWindows(type) { + if (type == undefined) { + type = ""; + } + + var windows = []; + var enumerator = Services.wm.getEnumerator(type); + + while (enumerator.hasMoreElements()) { + windows.push(enumerator.getNext()); + } + + if (type == "") { + windows.push(hwindow); + } + + return windows; +} + +function getMethodInWindows(methodName) { + for (var w of getWindows()) { + if (w[methodName] != undefined) { + return w[methodName]; + } + } + + throw new Error("Method with name: '" + methodName + "' is not in any open window."); +} + +function getWindowByTitle(title) { + for (var w of getWindows()) { + if (w.document.title && w.document.title == title) { + return w; + } + } + + throw new Error("Window with title: '" + title + "' not found."); +} + +function getWindowByType(type) { + return Services.wm.getMostRecentWindow(type); +} + +/** + * Retrieve the outer window id for the given window. + * + * @param {Number} aWindow + * Window to retrieve the id from. + * @returns {Boolean} The outer window id + **/ +function getWindowId(aWindow) { + try { + // Normally we can retrieve the id via window utils + return aWindow.QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIDOMWindowUtils). + outerWindowID; + } catch (e) { + // ... but for observer notifications we need another interface + return aWindow.QueryInterface(Ci.nsISupportsPRUint64).data; + } +} + +var checkChrome = function () { + var loc = window.document.location.href; + try { + loc = window.top.document.location.href; + } catch (e) { + } + + return /^chrome:\/\//.test(loc); +} + +/** + * Called to get the state of an individual preference. + * + * @param aPrefName string The preference to get the state of. + * @param aDefaultValue any The default value if preference was not found. + * + * @returns any The value of the requested preference + * + * @see setPref + * Code by Henrik Skupin: + */ +function getPreference(aPrefName, aDefaultValue) { + try { + var branch = Services.prefs; + + switch (typeof aDefaultValue) { + case ('boolean'): + return branch.getBoolPref(aPrefName); + case ('string'): + return branch.getCharPref(aPrefName); + case ('number'): + return branch.getIntPref(aPrefName); + default: + // XXX: how does this work? It's missing the nsIIDRef argument... + return branch.getComplexValue(aPrefName); + } + } catch (e) { + return aDefaultValue; + } +} + +/** + * Called to set the state of an individual preference. + * + * @param aPrefName string The preference to set the state of. + * @param aValue any The value to set the preference to. + * + * @returns boolean Returns true if value was successfully set. + * + * @see getPref + * Code by Henrik Skupin: + */ +function setPreference(aName, aValue) { + try { + var branch = Services.prefs; + + switch (typeof aValue) { + case ('boolean'): + branch.setBoolPref(aName, aValue); + break; + case ('string'): + branch.setCharPref(aName, aValue); + break; + case ('number'): + branch.setIntPref(aName, aValue); + break; + default: + // XXX: how does this work? It's missing the nsIIDRef argument... + branch.setComplexValue(aName, aValue); + } + } catch (e) { + return false; + } + + return true; +} + +/** + * Sleep for the given amount of milliseconds + * + * @param {number} milliseconds + * Sleeps the given number of milliseconds + */ +function sleep(milliseconds) { + var timeup = false; + + hwindow.setTimeout(function () { timeup = true; }, milliseconds); + Services.tm.spinEventLoopUntil(() => timeup); + + broker.pass({'function':'utils.sleep()'}); +} + +/** + * Check if the callback function evaluates to true + */ +function assert(callback, message, thisObject) { + var result = callback.call(thisObject); + + if (!result) { + throw new Error(message || arguments.callee.name + ": Failed for '" + callback + "'"); + } + + return true; +} + +/** + * Unwraps a node which is wrapped into a XPCNativeWrapper or XrayWrapper + * + * @param {DOMnode} Wrapped DOM node + * @returns {DOMNode} Unwrapped DOM node + */ +function unwrapNode(aNode) { + var node = aNode; + if (node) { + // unwrap is not available on older branches (3.5 and 3.6) - Bug 533596 + if ("unwrap" in XPCNativeWrapper) { + node = XPCNativeWrapper.unwrap(node); + } + else if (node.wrappedJSObject != null) { + node = node.wrappedJSObject; + } + } + + return node; +} + +/** + * Waits for the callback evaluates to true + */ +function waitFor(callback, message, timeout, interval, thisObject) { + broker.log({'function': 'utils.waitFor() - DEPRECATED', + 'message': 'utils.waitFor() is deprecated. Use assert.waitFor() instead'}); + assert.waitFor(callback, message, timeout, interval, thisObject); +} + +/** + * Calculates the x and y chrome offset for an element + * See https://developer.mozilla.org/en/DOM/window.innerHeight + * + * Note this function will not work if the user has custom toolbars (via extension) at the bottom or left/right of the screen + */ +function getChromeOffset(elem) { + var win = elem.ownerGlobal; + // Calculate x offset + var chromeWidth = 0; + + if (win["name"] != "sidebar") { + chromeWidth = win.outerWidth - win.innerWidth; + } + + // Calculate y offset + var chromeHeight = win.outerHeight - win.innerHeight; + // chromeHeight == 0 means elem is already in the chrome and doesn't need the addonbar offset + if (chromeHeight > 0) { + // window.innerHeight doesn't include the addon or find bar, so account for these if present + var addonbar = win.document.getElementById("addon-bar"); + if (addonbar) { + chromeHeight -= addonbar.scrollHeight; + } + + var findbar = win.document.getElementById("FindToolbar"); + if (findbar) { + chromeHeight -= findbar.scrollHeight; + } + } + + return {'x':chromeWidth, 'y':chromeHeight}; +} + +/** + * Takes a screenshot of the specified DOM node + */ +function takeScreenshot(node, highlights) { + var rect, win, width, height, left, top, needsOffset; + // node can be either a window or an arbitrary DOM node + try { + // node is an arbitrary DOM node + win = node.ownerGlobal; + rect = node.getBoundingClientRect(); + width = rect.width; + height = rect.height; + top = rect.top; + left = rect.left; + // offset for highlights not needed as they will be relative to this node + needsOffset = false; + } catch (e) { + // node is a window + win = node; + width = win.innerWidth; + height = win.innerHeight; + top = 0; + left = 0; + // offset needed for highlights to take 'outerHeight' of window into account + needsOffset = true; + } + + var canvas = win.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); + canvas.width = width; + canvas.height = height; + + var ctx = canvas.getContext("2d"); + // Draws the DOM contents of the window to the canvas + ctx.drawWindow(win, left, top, width, height, "rgb(255,255,255)"); + + // This section is for drawing a red rectangle around each element passed in via the highlights array + if (highlights) { + ctx.lineWidth = "2"; + ctx.strokeStyle = "red"; + ctx.save(); + + for (var i = 0; i < highlights.length; ++i) { + var elem = highlights[i]; + rect = elem.getBoundingClientRect(); + + var offsetY = 0, offsetX = 0; + if (needsOffset) { + var offset = getChromeOffset(elem); + offsetX = offset.x; + offsetY = offset.y; + } else { + // Don't need to offset the window chrome, just make relative to containing node + offsetY = -top; + offsetX = -left; + } + + // Draw the rectangle + ctx.strokeRect(rect.left + offsetX, rect.top + offsetY, rect.width, rect.height); + } + } + + return canvas.toDataURL("image/jpeg", 0.5); +} + +/** + * Save the dataURL content to the specified file. It will be stored in either the persisted screenshot or temporary folder. + * + * @param {String} aDataURL + * The dataURL to save + * @param {String} aFilename + * Target file name without extension + * + * @returns {Object} The hash containing the path of saved file, and the failure bit + */ +function saveDataURL(aDataURL, aFilename) { + var frame = {}; Cu.import('resource://mozmill/modules/frame.js', frame); + const FILE_PERMISSIONS = parseInt("0644", 8); + + var file; + file = Cc['@mozilla.org/file/local;1'] + .createInstance(Ci.nsIFile); + file.initWithPath(frame.persisted['screenshots']['path']); + file.append(aFilename + ".jpg"); + file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FILE_PERMISSIONS); + + // Create an output stream to write to file + let foStream = Cc["@mozilla.org/network/file-output-stream;1"] + .createInstance(Ci.nsIFileOutputStream); + foStream.init(file, 0x02 | 0x08 | 0x10, FILE_PERMISSIONS, foStream.DEFER_OPEN); + + let dataURI = NetUtil.newURI(aDataURL, "UTF8"); + if (!dataURI.schemeIs("data")) { + throw TypeError("aDataURL parameter has to have 'data'" + + " scheme instead of '" + dataURI.scheme + "'"); + } + + // Write asynchronously to buffer; + // Input and output streams are closed after write + + let ready = false; + let failure = false; + + function sync(aStatus) { + if (!Components.isSuccessCode(aStatus)) { + failure = true; + } + ready = true; + } + + NetUtil.asyncFetch(dataURI, function (aInputStream, aAsyncFetchResult) { + if (!Components.isSuccessCode(aAsyncFetchResult)) { + // An error occurred! + sync(aAsyncFetchResult); + } else { + // Consume the input stream. + NetUtil.asyncCopy(aInputStream, foStream, function (aAsyncCopyResult) { + sync(aAsyncCopyResult); + }); + } + }); + + assert.waitFor(function () { + return ready; + }, "DataURL has been saved to '" + file.path + "'"); + + return {filename: file.path, failure: failure}; +} + +/** + * Some very brain-dead timer functions useful for performance optimizations + * This is only enabled in debug mode + * + **/ +var gutility_mzmltimer = 0; +/** + * Starts timer initializing with current EPOC time in milliseconds + * + * @returns none + **/ +function startTimer(){ + dump("TIMERCHECK:: starting now: " + Date.now() + "\n"); + gutility_mzmltimer = Date.now(); +} + +/** + * Checks the timer and outputs current elapsed time since start of timer. It + * will print out a message you provide with its "time check" so you can + * correlate in the log file and figure out elapsed time of specific functions. + * + * @param aMsg string The debug message to print with the timer check + * + * @returns none + **/ +function checkTimer(aMsg){ + var end = Date.now(); + dump("TIMERCHECK:: at " + aMsg + " is: " + (end - gutility_mzmltimer) + "\n"); +} diff --git a/services/sync/tps/extensions/tps/resource/tps.jsm b/services/sync/tps/extensions/tps/resource/tps.jsm index 037b1e0c223b..81ce5d829288 100644 --- a/services/sync/tps/extensions/tps/resource/tps.jsm +++ b/services/sync/tps/extensions/tps/resource/tps.jsm @@ -56,6 +56,13 @@ XPCOMUtils.defineLazyGetter(this, "fileProtocolHandler", () => { return fileHandler.QueryInterface(Ci.nsIFileProtocolHandler); }); +XPCOMUtils.defineLazyGetter(this, "gTextDecoder", () => { + return new TextDecoder(); +}); + +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); + // Options for wiping data during a sync const SYNC_RESET_CLIENT = "resetClient"; const SYNC_WIPE_CLIENT = "wipeClient"; @@ -794,11 +801,10 @@ var TPS = { let stream = Cc["@mozilla.org/network/file-input-stream;1"] .createInstance(Ci.nsIFileInputStream); - let jsonReader = Cc["@mozilla.org/dom/json;1"] - .createInstance(Components.interfaces.nsIJSON); - stream.init(schemaFile, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0); - let schema = jsonReader.decodeFromStream(stream, stream.available()); + + let bytes = NetUtil.readInputStream(stream, stream.available()); + let schema = JSON.parse(gTextDecoder.decode(bytes)); Logger.logInfo("Successfully loaded schema"); // Importing resource://testing-common/* isn't possible from within TPS, diff --git a/testing/marionette/client/marionette_driver/marionette.py b/testing/marionette/client/marionette_driver/marionette.py index 8bbf449686fa..d5b2e6e28a90 100644 --- a/testing/marionette/client/marionette_driver/marionette.py +++ b/testing/marionette/client/marionette_driver/marionette.py @@ -868,7 +868,7 @@ class Marionette(object): Preferences.reset(arguments[0]); """, script_args=(pref,)) - def get_pref(self, pref, default_branch=False, value_type="nsISupportsString"): + def get_pref(self, pref, default_branch=False, value_type="unspecified"): """Get the value of the specified preference. :param pref: Name of the preference. @@ -876,8 +876,8 @@ class Marionette(object): from the default branch. Otherwise the user-defined value if set is returned. Defaults to `False`. :param value_type: Optional, XPCOM interface of the pref's complex value. - Defaults to `nsISupportsString`. Other possible values are: - `nsIFile`, and `nsIPrefLocalizedString`. + Possible values are: `nsIFile` and + `nsIPrefLocalizedString`. Usage example:: diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py index d9d922f779b4..2af78bdf83c5 100644 --- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -831,11 +831,15 @@ class MochitestArguments(ArgumentContainer): options.leakThresholds = { "default": options.defaultLeakThreshold, - "tab": 3000, # See dependencies of bug 1401764. + "tab": options.defaultLeakThreshold, # GMP rarely gets a log, but when it does, it leaks a little. "geckomediaplugin": 20000, } + # See the dependencies of bug 1401764. + if mozinfo.isWin: + options.leakThresholds["tab"] = 1000 + # XXX We can't normalize test_paths in the non build_obj case here, # because testRoot depends on the flavor, which is determined by the # mach command and therefore not finalized yet. Conversely, test paths diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index 5e4ddedaf79e..3d2ac6863134 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -40,6 +40,9 @@ _register_modules_protocol_handler(); var _Promise = Components.utils.import("resource://gre/modules/Promise.jsm", {}).Promise; var _PromiseTestUtils = Components.utils.import("resource://testing-common/PromiseTestUtils.jsm", {}).PromiseTestUtils; var _Task = Components.utils.import("resource://gre/modules/Task.jsm", {}).Task; + +let _NetUtil = Components.utils.import("resource://gre/modules/NetUtil.jsm", {}).NetUtil; + Components.utils.importGlobalProperties(["XMLHttpRequest"]); // Support a common assertion library, Assert.jsm. @@ -1565,9 +1568,8 @@ function _load_mozinfo() { let stream = Components.classes["@mozilla.org/network/file-input-stream;1"] .createInstance(Components.interfaces.nsIFileInputStream); stream.init(mozinfoFile, -1, 0, 0); - let json = Components.classes["@mozilla.org/dom/json;1"] - .createInstance(Components.interfaces.nsIJSON); - let mozinfo = json.decodeFromStream(stream, stream.available()); + let bytes = _NetUtil.readInputStream(stream, stream.available()); + let mozinfo = JSON.parse((new TextDecoder()).decode(bytes)); stream.close(); return mozinfo; } diff --git a/testing/xpcshell/selftest.py b/testing/xpcshell/selftest.py index ac62c04e6614..701d48fd3863 100755 --- a/testing/xpcshell/selftest.py +++ b/testing/xpcshell/selftest.py @@ -463,7 +463,7 @@ class XPCShellTestsTests(unittest.TestCase): {}, {"tbpl": self.log}) self.x = XPCShellTests(logger) - self.x.harness_timeout = 15 + self.x.harness_timeout = 15 if not mozinfo.info["ccov"] else 60 self.symbols_path = None candidate_path = os.path.join(build_obj.distdir, 'crashreporter-symbols') if (os.path.isdir(candidate_path)): diff --git a/toolkit/components/contextualidentity/ContextualIdentityService.jsm b/toolkit/components/contextualidentity/ContextualIdentityService.jsm index 4cf278ccb8bd..5f30efbaee3a 100644 --- a/toolkit/components/contextualidentity/ContextualIdentityService.jsm +++ b/toolkit/components/contextualidentity/ContextualIdentityService.jsm @@ -33,6 +33,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); function _TabRemovalObserver(resolver, tabParentIds) { this._resolver = resolver; @@ -315,9 +317,8 @@ _ContextualIdentityService.prototype = { inputStream.init(new FileUtils.File(this._path), FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0); try { - let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); - let data = json.decodeFromStream(inputStream, - inputStream.available()); + let bytes = NetUtil.readInputStreamToString(inputStream, inputStream.available()); + let data = JSON.parse(gTextDecoder.decode(bytes)); this._identities = data.identities; this._lastUserContextId = data.lastUserContextId; diff --git a/toolkit/components/perfmonitoring/nsPerformanceStats.cpp b/toolkit/components/perfmonitoring/nsPerformanceStats.cpp index eb84c9961ed5..7b82fb2a1ee7 100644 --- a/toolkit/components/perfmonitoring/nsPerformanceStats.cpp +++ b/toolkit/components/perfmonitoring/nsPerformanceStats.cpp @@ -65,7 +65,7 @@ namespace { */ already_AddRefed GetPrivateWindow(JSContext* cx) { - nsGlobalWindow* win = xpc::CurrentWindowOrNull(cx); + nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(cx); if (!win) { return nullptr; } diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js index aa9ddd8c5c9f..2f9c2155cf9c 100644 --- a/toolkit/components/search/nsSearchService.js +++ b/toolkit/components/search/nsSearchService.js @@ -23,6 +23,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { setTimeout: "resource://gre/modules/Timer.jsm", clearTimeout: "resource://gre/modules/Timer.jsm", Lz4: "resource://gre/modules/lz4.js", + NetUtil: "resource://gre/modules/NetUtil.jsm", }); XPCOMUtils.defineLazyServiceGetters(this, { @@ -46,6 +47,7 @@ XPCOMUtils.defineLazyGetter(this, "gEncoder", return new TextEncoder(); }); + const MODE_RDONLY = 0x01; const MODE_WRONLY = 0x02; const MODE_CREATE = 0x08; @@ -953,9 +955,8 @@ function notifyAction(aEngine, aVerb) { } function parseJsonFromStream(aInputStream) { - const json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); - const data = json.decodeFromStream(aInputStream, aInputStream.available()); - return data; + let bytes = NetUtil.readInputStream(aInputStream, aInputStream.available()); + return JSON.parse(new TextDecoder().decode(bytes)); } /** diff --git a/toolkit/components/search/tests/xpcshell/head_search.js b/toolkit/components/search/tests/xpcshell/head_search.js index 839ab2acd942..65f001c9edca 100644 --- a/toolkit/components/search/tests/xpcshell/head_search.js +++ b/toolkit/components/search/tests/xpcshell/head_search.js @@ -12,6 +12,8 @@ Cu.import("resource://testing-common/AppInfo.jsm"); Cu.import("resource://testing-common/httpd.js"); XPCOMUtils.defineLazyModuleGetter(this, "TestUtils", "resource://testing-common/TestUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); const BROWSER_SEARCH_PREF = "browser.search."; const NS_APP_SEARCH_DIR = "SrchPlugns"; @@ -278,9 +280,8 @@ function promiseAfterCache() { } function parseJsonFromStream(aInputStream) { - const json = Cc["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON); - const data = json.decodeFromStream(aInputStream, aInputStream.available()); - return data; + let bytes = NetUtil.readInputStream(aInputStream, aInputStream.available()); + return JSON.parse((new TextDecoder()).decode(bytes)); } /** diff --git a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp b/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp index 026547074b82..d5006bcfe94f 100644 --- a/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp +++ b/toolkit/components/telemetry/ipc/TelemetryIPCAccumulator.cpp @@ -290,7 +290,7 @@ SendAccumulatedData(TActor* ipcActor) } // Send the accumulated data to the parent process. - mozilla::Unused << NS_WARN_IF(!ipcActor); + MOZ_ASSERT(ipcActor); if (histogramsToSend.Length()) { mozilla::Unused << NS_WARN_IF(!ipcActor->SendAccumulateChildHistograms(histogramsToSend)); diff --git a/toolkit/components/telemetry/tests/unit/head.js b/toolkit/components/telemetry/tests/unit/head.js index 2e78d4ee7f90..76b2bffe03e3 100644 --- a/toolkit/components/telemetry/tests/unit/head.js +++ b/toolkit/components/telemetry/tests/unit/head.js @@ -20,6 +20,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySend", "resource://gre/modules/TelemetrySend.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/Log.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); const gIsWindows = AppConstants.platform == "win"; const gIsMac = AppConstants.platform == "macosx"; @@ -129,7 +131,6 @@ const PingServer = { function decodeRequestPayload(request) { let s = request.bodyInputStream; let payload = null; - let decoder = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); if (request.hasHeader("content-encoding") && request.getHeader("content-encoding") == "gzip") { @@ -157,7 +158,8 @@ function decodeRequestPayload(request) { utf8string += unicodeConverter.Finish(); payload = JSON.parse(utf8string); } else { - payload = decoder.decodeFromStream(s, s.available()); + let bytes = NetUtil.readInputStream(s, s.available()); + payload = JSON.parse((new TextDecoder()).decode(bytes)); } return payload; diff --git a/toolkit/components/windowwatcher/nsWindowWatcher.cpp b/toolkit/components/windowwatcher/nsWindowWatcher.cpp index 31aeedf69381..938e5b9a2dc9 100644 --- a/toolkit/components/windowwatcher/nsWindowWatcher.cpp +++ b/toolkit/components/windowwatcher/nsWindowWatcher.cpp @@ -1116,7 +1116,7 @@ nsWindowWatcher::OpenWindowInternal(mozIDOMWindowProxy* aParent, if (newWindow) { newWindow->SetInitialPrincipalToSubject(); if (aIsPopupSpam) { - nsGlobalWindow* globalWin = nsGlobalWindow::Cast(newWindow); + nsGlobalWindowOuter* globalWin = nsGlobalWindowOuter::Cast(newWindow); MOZ_ASSERT(!globalWin->IsPopupSpamWindow(), "Who marked it as popup spam already???"); if (!globalWin->IsPopupSpamWindow()) { // Make sure we don't mess up our diff --git a/toolkit/content/tests/chrome/test_preferences.xul b/toolkit/content/tests/chrome/test_preferences.xul index 62a1739b009f..82e7446be31c 100644 --- a/toolkit/content/tests/chrome/test_preferences.xul +++ b/toolkit/content/tests/chrome/test_preferences.xul @@ -22,19 +22,16 @@ int: 23, bool: true, string: "rheeet!", + unichar: "äöüßÄÖÜ", wstring_data: "日本語", - unichar_data: "äöüßÄÖÜ", file_data: "/", wstring: Components.classes["@mozilla.org/pref-localizedstring;1"] .createInstance(Components.interfaces.nsIPrefLocalizedString), - unichar: Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString), file: Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsIFile) }; kPrefValueSet1.wstring.data = kPrefValueSet1.wstring_data; - kPrefValueSet1.unichar.data = kPrefValueSet1.unichar_data; SafeFileInit(kPrefValueSet1.file, kPrefValueSet1.file_data); // preference values, set 2 @@ -43,19 +40,16 @@ int: 42, bool: false, string: "Mozilla", + unichar: "áôùšŽ", wstring_data: "헤드라인A", - unichar_data: "áôùšŽ", file_data: "/home", wstring: Components.classes["@mozilla.org/pref-localizedstring;1"] .createInstance(Components.interfaces.nsIPrefLocalizedString), - unichar: Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString), file: Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsIFile) }; kPrefValueSet2.wstring.data = kPrefValueSet2.wstring_data; - kPrefValueSet2.unichar.data = kPrefValueSet2.unichar_data; SafeFileInit(kPrefValueSet2.file, kPrefValueSet2.file_data); @@ -76,11 +70,10 @@ int: undefined, bool: undefined, string: undefined, + unichar: undefined, wstring_data: undefined, - unichar_data: undefined, file_data: undefined, wstring: undefined, - unichar: undefined, file: undefined }; return result; @@ -92,12 +85,10 @@ kPref.setIntPref ("tests.static_preference_int", aPrefValueSet.int); kPref.setBoolPref("tests.static_preference_bool", aPrefValueSet.bool); kPref.setCharPref("tests.static_preference_string", aPrefValueSet.string); + kPref.setStringPref("tests.static_preference_unichar", aPrefValueSet.unichar); kPref.setComplexValue("tests.static_preference_wstring", Components.interfaces.nsIPrefLocalizedString, aPrefValueSet.wstring); - kPref.setComplexValue("tests.static_preference_unichar", - Components.interfaces.nsISupportsString, - aPrefValueSet.unichar); kPref.setComplexValue("tests.static_preference_file", Components.interfaces.nsIFile, aPrefValueSet.file); @@ -112,16 +103,14 @@ try {result.string = kPref.getCharPref("tests.static_preference_string")} catch (ignored) {}; try { - result.wstring = kPref.getComplexValue("tests.static_preference_wstring", - Components.interfaces.nsIPrefLocalizedString); - result.wstring_data = result.wstring.data; + result.unichar = kPref.getStringPref("tests.static_preference_unichar"); } catch (ignored) {}; try { - result.unichar = kPref.getComplexValue("tests.static_preference_unichar", - Components.interfaces.nsISupportsString); - result.unichar_data = result.unichar.data; + result.wstring = kPref.getComplexValue("tests.static_preference_wstring", + Components.interfaces.nsIPrefLocalizedString); + result.wstring_data = result.wstring.data; } catch (ignored) {}; try @@ -145,8 +134,8 @@ GetXULElement(aPrefWindow, "tests.static_preference_int" ).value = aPrefValueSet.int; GetXULElement(aPrefWindow, "tests.static_preference_bool" ).value = aPrefValueSet.bool; GetXULElement(aPrefWindow, "tests.static_preference_string" ).value = aPrefValueSet.string; + GetXULElement(aPrefWindow, "tests.static_preference_unichar").value = aPrefValueSet.unichar; GetXULElement(aPrefWindow, "tests.static_preference_wstring").value = aPrefValueSet.wstring_data; - GetXULElement(aPrefWindow, "tests.static_preference_unichar").value = aPrefValueSet.unichar_data; GetXULElement(aPrefWindow, "tests.static_preference_file" ).value = aPrefValueSet.file_data; } @@ -158,18 +147,15 @@ int: GetXULElement(aPrefWindow, "tests.static_preference_int" ).value, bool: GetXULElement(aPrefWindow, "tests.static_preference_bool" ).value, string: GetXULElement(aPrefWindow, "tests.static_preference_string" ).value, + unichar: GetXULElement(aPrefWindow, "tests.static_preference_unichar").value, wstring_data: GetXULElement(aPrefWindow, "tests.static_preference_wstring").value, - unichar_data: GetXULElement(aPrefWindow, "tests.static_preference_unichar").value, file_data: GetXULElement(aPrefWindow, "tests.static_preference_file" ).value, wstring: Components.classes["@mozilla.org/pref-localizedstring;1"] .createInstance(Components.interfaces.nsIPrefLocalizedString), - unichar: Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString), file: Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsIFile) } result.wstring.data = result.wstring_data; - result.unichar.data = result.unichar_data; SafeFileInit(result.file, result.file_data); return result; } @@ -180,8 +166,8 @@ GetXULElement(aPrefWindow, "static_element_int" ).value = aPrefValueSet.int; GetXULElement(aPrefWindow, "static_element_bool" ).checked = aPrefValueSet.bool; GetXULElement(aPrefWindow, "static_element_string" ).value = aPrefValueSet.string; + GetXULElement(aPrefWindow, "static_element_unichar").value = aPrefValueSet.unichar; GetXULElement(aPrefWindow, "static_element_wstring").value = aPrefValueSet.wstring_data; - GetXULElement(aPrefWindow, "static_element_unichar").value = aPrefValueSet.unichar_data; GetXULElement(aPrefWindow, "static_element_file" ).value = aPrefValueSet.file_data; } @@ -193,18 +179,15 @@ int: GetXULElement(aPrefWindow, "static_element_int" ).value, bool: GetXULElement(aPrefWindow, "static_element_bool" ).checked, string: GetXULElement(aPrefWindow, "static_element_string" ).value, + unichar: GetXULElement(aPrefWindow, "static_element_unichar").value, wstring_data: GetXULElement(aPrefWindow, "static_element_wstring").value, - unichar_data: GetXULElement(aPrefWindow, "static_element_unichar").value, file_data: GetXULElement(aPrefWindow, "static_element_file" ).value, wstring: Components.classes["@mozilla.org/pref-localizedstring;1"] .createInstance(Components.interfaces.nsIPrefLocalizedString), - unichar: Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString), file: Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsIFile) } result.wstring.data = result.wstring_data; - result.unichar.data = result.unichar_data; SafeFileInit(result.file, result.file_data); return result; } @@ -220,8 +203,8 @@ ok(found.int === expected.int, "instant pref init int" ); ok(found.bool === expected.bool, "instant pref init bool" ); ok(found.string === expected.string, "instant pref init string" ); + ok(found.unichar === expected.unichar, "instant pref init unichar"); ok(found.wstring_data === expected.wstring_data, "instant pref init wstring"); - ok(found.unichar_data === expected.unichar_data, "instant pref init unichar"); todo(found.file_data === expected.file_data, "instant pref init file" ); // were all elements correctly initialized? (loose check) @@ -229,8 +212,8 @@ ok(found.int == expected.int, "instant element init int" ); ok(found.bool == expected.bool, "instant element init bool" ); ok(found.string == expected.string, "instant element init string" ); + ok(found.unichar == expected.unichar, "instant element init unichar"); ok(found.wstring_data == expected.wstring_data, "instant element init wstring"); - ok(found.unichar_data == expected.unichar_data, "instant element init unichar"); todo(found.file_data == expected.file_data, "instant element init file" ); // do some changes in the UI @@ -245,8 +228,8 @@ todo(found.int === expected.int, "instant change pref int" ); todo(found.bool === expected.bool, "instant change pref bool" ); todo(found.string === expected.string, "instant change pref string" ); + todo(found.unichar === expected.unichar, "instant change pref unichar"); todo(found.wstring_data === expected.wstring_data, "instant change pref wstring"); - todo(found.unichar_data === expected.unichar_data, "instant change pref unichar"); todo(found.file_data === expected.file_data, "instant change pref file" ); // and these changes should get passed to the system instantly @@ -255,16 +238,16 @@ todo(found.int === expected.int, "instant change element int" ); todo(found.bool === expected.bool, "instant change element bool" ); todo(found.string === expected.string, "instant change element string" ); + todo(found.unichar === expected.unichar, "instant change element unichar"); todo(found.wstring_data === expected.wstring_data, "instant change element wstring"); - todo(found.unichar_data === expected.unichar_data, "instant change element unichar"); todo(found.file_data === expected.file_data, "instant change element file" ); // try resetting the prefs to default values (which should be empty here) GetXULElement(aPrefWindow, "tests.static_preference_int" ).reset(); GetXULElement(aPrefWindow, "tests.static_preference_bool" ).reset(); GetXULElement(aPrefWindow, "tests.static_preference_string" ).reset(); - GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset(); GetXULElement(aPrefWindow, "tests.static_preference_unichar").reset(); + GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset(); GetXULElement(aPrefWindow, "tests.static_preference_file" ).reset(); // check system @@ -273,8 +256,8 @@ ok(found.int === expected.int, "instant reset system int" ); ok(found.bool === expected.bool, "instant reset system bool" ); ok(found.string === expected.string, "instant reset system string" ); + ok(found.unichar === expected.unichar, "instant reset system unichar"); ok(found.wstring_data === expected.wstring_data, "instant reset system wstring"); - ok(found.unichar_data === expected.unichar_data, "instant reset system unichar"); ok(found.file_data === expected.file_data, "instant reset system file" ); // check UI @@ -285,27 +268,26 @@ int: "", bool: false, string: "", + unichar: "", wstring_data: "", - unichar_data: "", file_data: "", wstring: {}, - unichar: {}, file: {} }; found = ReadPrefsFromUI(aPrefWindow); ok(found.int === expected.int, "instant reset element int" ); ok(found.bool === expected.bool, "instant reset element bool" ); ok(found.string === expected.string, "instant reset element string" ); + ok(found.unichar === expected.unichar, "instant reset element unichar"); ok(found.wstring_data === expected.wstring_data, "instant reset element wstring"); - ok(found.unichar_data === expected.unichar_data, "instant reset element unichar"); // ok(found.file_data === expected.file_data, "instant reset element file" ); // check hasUserValue ok(GetXULElement(aPrefWindow, "tests.static_preference_int" ).hasUserValue === false, "instant reset hasUserValue int" ); ok(GetXULElement(aPrefWindow, "tests.static_preference_bool" ).hasUserValue === false, "instant reset hasUserValue bool" ); ok(GetXULElement(aPrefWindow, "tests.static_preference_string" ).hasUserValue === false, "instant reset hasUserValue string" ); - ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "instant reset hasUserValue wstring"); ok(GetXULElement(aPrefWindow, "tests.static_preference_unichar").hasUserValue === false, "instant reset hasUserValue unichar"); + ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "instant reset hasUserValue wstring"); ok(GetXULElement(aPrefWindow, "tests.static_preference_file" ).hasUserValue === false, "instant reset hasUserValue file" ); // done with instant apply checks @@ -325,8 +307,8 @@ ok(found.int === expected.int, "non-instant pref init int" ); ok(found.bool === expected.bool, "non-instant pref init bool" ); ok(found.string === expected.string, "non-instant pref init string" ); + ok(found.unichar === expected.unichar, "non-instant pref init unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant pref init wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant pref init unichar"); todo(found.file_data === expected.file_data, "non-instant pref init file" ); // were all elements correctly initialized? (loose check) @@ -334,8 +316,8 @@ ok(found.int == expected.int, "non-instant element init int" ); ok(found.bool == expected.bool, "non-instant element init bool" ); ok(found.string == expected.string, "non-instant element init string" ); + ok(found.unichar == expected.unichar, "non-instant element init unichar"); ok(found.wstring_data == expected.wstring_data, "non-instant element init wstring"); - ok(found.unichar_data == expected.unichar_data, "non-instant element init unichar"); todo(found.file_data == expected.file_data, "non-instant element init file" ); // do some changes in the UI @@ -350,8 +332,8 @@ todo(found.int === expected.int, "non-instant change pref int" ); todo(found.bool === expected.bool, "non-instant change pref bool" ); todo(found.string === expected.string, "non-instant change pref string" ); + todo(found.unichar === expected.unichar, "non-instant change pref unichar"); todo(found.wstring_data === expected.wstring_data, "non-instant change pref wstring"); - todo(found.unichar_data === expected.unichar_data, "non-instant change pref unichar"); todo(found.file_data === expected.file_data, "non-instant change pref file" ); // and these changes should *NOT* get passed to the system @@ -361,16 +343,16 @@ ok(found.int === expected.int, "non-instant change element int" ); ok(found.bool === expected.bool, "non-instant change element bool" ); ok(found.string === expected.string, "non-instant change element string" ); + ok(found.unichar === expected.unichar, "non-instant change element unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant change element wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant change element unichar"); todo(found.file_data === expected.file_data, "non-instant change element file" ); // try resetting the prefs to default values (which should be empty here) GetXULElement(aPrefWindow, "tests.static_preference_int" ).reset(); GetXULElement(aPrefWindow, "tests.static_preference_bool" ).reset(); GetXULElement(aPrefWindow, "tests.static_preference_string" ).reset(); - GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset(); GetXULElement(aPrefWindow, "tests.static_preference_unichar").reset(); + GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset(); GetXULElement(aPrefWindow, "tests.static_preference_file" ).reset(); // check system: the current values *MUST NOT* change @@ -379,8 +361,8 @@ ok(found.int === expected.int, "non-instant reset system int" ); ok(found.bool === expected.bool, "non-instant reset system bool" ); ok(found.string === expected.string, "non-instant reset system string" ); + ok(found.unichar === expected.unichar, "non-instant reset system unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant reset system wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant reset system unichar"); todo(found.file_data === expected.file_data, "non-instant reset system file" ); // check UI: these values should be reset @@ -391,27 +373,26 @@ int: "", bool: false, string: "", + unichar: "", wstring_data: "", - unichar_data: "", file_data: "", wstring: {}, - unichar: {}, file: {} }; found = ReadPrefsFromUI(aPrefWindow); ok(found.int === expected.int, "non-instant reset element int" ); ok(found.bool === expected.bool, "non-instant reset element bool" ); ok(found.string === expected.string, "non-instant reset element string" ); + ok(found.unichar === expected.unichar, "non-instant reset element unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant reset element wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant reset element unichar"); // ok(found.file_data === expected.file_data, "non-instant reset element file" ); // check hasUserValue ok(GetXULElement(aPrefWindow, "tests.static_preference_int" ).hasUserValue === false, "non-instant reset hasUserValue int" ); ok(GetXULElement(aPrefWindow, "tests.static_preference_bool" ).hasUserValue === false, "non-instant reset hasUserValue bool" ); ok(GetXULElement(aPrefWindow, "tests.static_preference_string" ).hasUserValue === false, "non-instant reset hasUserValue string" ); - ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "non-instant reset hasUserValue wstring"); ok(GetXULElement(aPrefWindow, "tests.static_preference_unichar").hasUserValue === false, "non-instant reset hasUserValue unichar"); + ok(GetXULElement(aPrefWindow, "tests.static_preference_wstring").hasUserValue === false, "non-instant reset hasUserValue wstring"); ok(GetXULElement(aPrefWindow, "tests.static_preference_file" ).hasUserValue === false, "non-instant reset hasUserValue file" ); } @@ -434,8 +415,8 @@ GetXULElement(aPrefWindow, "tests.static_preference_int" ).reset(); GetXULElement(aPrefWindow, "tests.static_preference_bool" ).reset(); GetXULElement(aPrefWindow, "tests.static_preference_string" ).reset(); - GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset(); GetXULElement(aPrefWindow, "tests.static_preference_unichar").reset(); + GetXULElement(aPrefWindow, "tests.static_preference_wstring").reset(); GetXULElement(aPrefWindow, "tests.static_preference_file" ).reset(); } @@ -460,8 +441,8 @@ ok(found.int === expected.int, "instant reset deferred int" ); ok(found.bool === expected.bool, "instant reset deferred bool" ); ok(found.string === expected.string, "instant reset deferred string" ); + ok(found.unichar === expected.unichar, "instant reset deferred unichar"); ok(found.wstring_data === expected.wstring_data, "instant reset deferred wstring"); - ok(found.unichar_data === expected.unichar_data, "instant reset deferred unichar"); todo(found.file_data === expected.file_data, "instant reset deferred file" ); } @@ -480,8 +461,8 @@ ok(found.int === expected.int, "non-instant cancel system int" ); ok(found.bool === expected.bool, "non-instant cancel system bool" ); ok(found.string === expected.string, "non-instant cancel system string" ); + ok(found.unichar === expected.unichar, "non-instant cancel system unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant cancel system wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant cancel system unichar"); todo(found.file_data === expected.file_data, "non-instant cancel system file" ); // - test Accept @@ -492,8 +473,8 @@ ok(found.int === expected.int, "non-instant accept system int" ); ok(found.bool === expected.bool, "non-instant accept system bool" ); ok(found.string === expected.string, "non-instant accept system string" ); + ok(found.unichar === expected.unichar, "non-instant accept system unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant accept system wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant accept system unichar"); todo(found.file_data === expected.file_data, "non-instant accept system file" ); // - test deferred reset in child window @@ -504,8 +485,8 @@ ok(found.int === expected.int, "non-instant reset deferred int" ); ok(found.bool === expected.bool, "non-instant reset deferred bool" ); ok(found.string === expected.string, "non-instant reset deferred string" ); + ok(found.unichar === expected.unichar, "non-instant reset deferred unichar"); ok(found.wstring_data === expected.wstring_data, "non-instant reset deferred wstring"); - ok(found.unichar_data === expected.unichar_data, "non-instant reset deferred unichar"); ok(found.file_data === expected.file_data, "non-instant reset deferred file" ); } diff --git a/toolkit/crashreporter/tools/symbolstore.py b/toolkit/crashreporter/tools/symbolstore.py index 435de4137baf..8a02a8032074 100755 --- a/toolkit/crashreporter/tools/symbolstore.py +++ b/toolkit/crashreporter/tools/symbolstore.py @@ -480,12 +480,9 @@ class Dumper: def RunFileCommand(self, file): """Utility function, returns the output of file(1)""" - try: - # we use -L to read the targets of symlinks, - # and -b to print just the content, not the filename - return os.popen("file -Lb " + file).read() - except: - return "" + # we use -L to read the targets of symlinks, + # and -b to print just the content, not the filename + return read_output('file', '-Lb', file) # This is a no-op except on Win32 def SourceServerIndexing(self, debug_file, guid, sourceFileStream, vcs_root): diff --git a/toolkit/crashreporter/tools/unit-symbolstore.py b/toolkit/crashreporter/tools/unit-symbolstore.py old mode 100644 new mode 100755 index 9805e8b3e109..b6630937b8ed --- a/toolkit/crashreporter/tools/unit-symbolstore.py +++ b/toolkit/crashreporter/tools/unit-symbolstore.py @@ -48,6 +48,9 @@ extension = {'WINNT': ".dll", 'Linux': ".so", 'Sunos5': ".so", 'Darwin': ".dylib"}[target_platform()] +file_output = [{'WINNT': "bogus data", + 'Linux': "ELF executable", + 'Darwin': "Mach-O executable"}[target_platform()]] def add_extension(files): return [f + extension for f in files] @@ -109,8 +112,15 @@ class TestCopyDebug(HelperMixin, unittest.TestCase): stdout_iter = self.next_mock_stdout() def next_popen(*args, **kwargs): m = mock.MagicMock() - m.stdout = stdout_iter.next() + # Get the iterators over whatever output was provided. + stdout_ = stdout_iter.next() + # Eager evaluation for communicate(), below. + stdout_ = list(stdout_) + # stdout is really an iterator, so back to iterators we go. + m.stdout = iter(stdout_) m.wait.return_value = 0 + # communicate returns the full text of stdout and stderr. + m.communicate.return_value = ('\n'.join(stdout_), '') return m self.mock_popen.side_effect = next_popen shutil.rmtree = patch("shutil.rmtree").start() @@ -135,6 +145,9 @@ class TestCopyDebug(HelperMixin, unittest.TestCase): def mock_copy_debug(filename, debug_file, guid, code_file, code_id): copied.append(filename[len(self.symbol_dir):] if filename.startswith(self.symbol_dir) else filename) self.add_test_files(add_extension(["foo"])) + # Windows doesn't call file(1) to figure out if the file should be processed. + if target_platform() != 'WINNT': + self.stdouts.append(file_output) self.stdouts.append(mock_dump_syms("X" * 33, add_extension(["foo"])[0])) self.stdouts.append(mock_dump_syms("Y" * 33, add_extension(["foo"])[0])) def mock_dsymutil(args, **kwargs): diff --git a/toolkit/modules/JSONFile.jsm b/toolkit/modules/JSONFile.jsm index a99b823c0f44..cc58b98c7df6 100644 --- a/toolkit/modules/JSONFile.jsm +++ b/toolkit/modules/JSONFile.jsm @@ -46,6 +46,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); + XPCOMUtils.defineLazyGetter(this, "gTextDecoder", function() { return new TextDecoder(); @@ -241,8 +244,8 @@ JSONFile.prototype = { FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0); try { - let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); - data = json.decodeFromStream(inputStream, inputStream.available()); + let bytes = NetUtil.readInputStream(inputStream, inputStream.available()); + data = JSON.parse(gTextDecoder.decode(bytes)); } finally { inputStream.close(); } diff --git a/toolkit/modules/Preferences.jsm b/toolkit/modules/Preferences.jsm index f7e34e2795df..81965a020192 100644 --- a/toolkit/modules/Preferences.jsm +++ b/toolkit/modules/Preferences.jsm @@ -47,7 +47,7 @@ this.Preferences = * * @returns the value of the pref, if any; otherwise the default value */ -Preferences.get = function(prefName, defaultValue, valueType = Ci.nsISupportsString) { +Preferences.get = function(prefName, defaultValue, valueType = null) { if (Array.isArray(prefName)) return prefName.map(v => this.get(v, defaultValue)); @@ -57,7 +57,13 @@ Preferences.get = function(prefName, defaultValue, valueType = Ci.nsISupportsStr Preferences._get = function(prefName, defaultValue, valueType) { switch (this._prefBranch.getPrefType(prefName)) { case Ci.nsIPrefBranch.PREF_STRING: - return this._prefBranch.getComplexValue(prefName, valueType).data; + if (valueType) { + let ifaces = ["nsIFile", "nsIPrefLocalizedString"]; + if (ifaces.includes(valueType.name)) { + return this._prefBranch.getComplexValue(prefName, valueType).data; + } + } + return this._prefBranch.getStringPref(prefName); case Ci.nsIPrefBranch.PREF_INT: return this._prefBranch.getIntPref(prefName); diff --git a/toolkit/modules/Troubleshoot.jsm b/toolkit/modules/Troubleshoot.jsm index 77dcb0c59583..75687363bc44 100644 --- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -104,7 +104,6 @@ const PREFS_BLACKLIST = [ ]; // Table of getters for various preference types. -// It's important to use getComplexValue for strings: it returns Unicode (wchars), getCharPref returns UTF-8 encoded chars. const PREFS_GETTERS = {}; PREFS_GETTERS[Ci.nsIPrefBranch.PREF_STRING] = (prefs, name) => prefs.getStringPref(name); diff --git a/toolkit/modules/tests/xpcshell/test_Preferences.js b/toolkit/modules/tests/xpcshell/test_Preferences.js index 60c076c1394a..65ecb102b8ad 100644 --- a/toolkit/modules/tests/xpcshell/test_Preferences.js +++ b/toolkit/modules/tests/xpcshell/test_Preferences.js @@ -112,9 +112,7 @@ add_test(function test_set_unsupported_pref() { run_next_test(); }); -// Make sure that we can get a string pref that we didn't set ourselves -// (i.e. that the way we get a string pref using getComplexValue doesn't -// hork us getting a string pref that wasn't set using setComplexValue). +// Make sure that we can get a string pref that we didn't set ourselves. add_test(function test_get_string_pref() { let svc = Cc["@mozilla.org/preferences-service;1"]. getService(Ci.nsIPrefService). diff --git a/toolkit/moz.configure b/toolkit/moz.configure index 1d25c064323d..46723459b232 100644 --- a/toolkit/moz.configure +++ b/toolkit/moz.configure @@ -27,7 +27,7 @@ def gecko_profiler(target): if target.os == 'Android': return target.cpu in ('aarch64', 'arm', 'x86') elif target.kernel == 'Linux': - return target.cpu in ('x86', 'x86_64') + return target.cpu in ('x86', 'x86_64', 'mips64') return target.os in ('OSX', 'WINNT') @depends(gecko_profiler) diff --git a/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp b/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp index b884e2a4965e..6cc33a51671d 100644 --- a/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp +++ b/toolkit/mozapps/extensions/AddonManagerWebAPI.cpp @@ -91,7 +91,7 @@ AddonManagerWebAPI::IsValidSite(nsIURI* uri) bool AddonManagerWebAPI::IsAPIEnabled(JSContext* cx, JSObject* obj) { - nsGlobalWindow* global = xpc::WindowGlobalOrNull(obj); + nsGlobalWindowInner* global = xpc::WindowGlobalOrNull(obj); if (!global) { return false; } diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 587af7cea1f1..8eb1be0a150a 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -57,6 +57,10 @@ XPCOMUtils.defineLazyServiceGetters(this, { aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"], }); +XPCOMUtils.defineLazyGetter(this, "gTextDecoder", () => { + return new TextDecoder(); +}); + Cu.importGlobalProperties(["URL"]); const nsIFile = Components.Constructor("@mozilla.org/file/local;1", "nsIFile", @@ -2920,12 +2924,11 @@ this.XPIProvider = { logger.debug("Found updated metadata for " + id + " in " + location.name); let fis = Cc["@mozilla.org/network/file-input-stream;1"]. createInstance(Ci.nsIFileInputStream); - let json = Cc["@mozilla.org/dom/json;1"]. - createInstance(Ci.nsIJSON); - try { fis.init(jsonfile, -1, 0, 0); - let metadata = json.decodeFromStream(fis, jsonfile.fileSize); + + let bytes = NetUtil.readInputStream(fis, jsonfile.fileSize); + let metadata = JSON.parse(gTextDecoder.decode(bytes)); addon.importMetadata(metadata); // Pass this through to addMetadata so it knows this add-on was diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_bug659772.js b/toolkit/mozapps/extensions/test/xpcshell/test_bug659772.js index 655626847ef8..e0d69354d86b 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bug659772.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug659772.js @@ -4,6 +4,8 @@ // Tests that a pending upgrade during a schema update doesn't break things +Components.utils.importGlobalProperties(["File"]); + var addon1 = { id: "addon1@tests.mozilla.org", version: "2.0", @@ -118,13 +120,16 @@ async function run_test_1() { do_check_true(jsonfile.exists()); // Remove an unnecessary property from the cached manifest - let fis = AM_Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(AM_Ci.nsIFileInputStream); - let json = AM_Cc["@mozilla.org/dom/json;1"]. - createInstance(AM_Ci.nsIJSON); - fis.init(jsonfile, -1, 0, 0); - let addonObj = json.decodeFromStream(fis, jsonfile.fileSize); - fis.close(); + let file = await File.createFromNsIFile(jsonfile); + + let addonObj = await new Promise(resolve => { + let fr = new FileReader(); + fr.readAsText(file); + fr.onloadend = () => { + resolve(JSON.parse(fr.result)); + } + }); + delete addonObj.optionsType; let stream = AM_Cc["@mozilla.org/network/file-output-stream;1"]. @@ -259,13 +264,16 @@ async function run_test_2() { do_check_true(jsonfile.exists()); // Remove an unnecessary property from the cached manifest - let fis = AM_Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(AM_Ci.nsIFileInputStream); - let json = AM_Cc["@mozilla.org/dom/json;1"]. - createInstance(AM_Ci.nsIJSON); - fis.init(jsonfile, -1, 0, 0); - let addonObj = json.decodeFromStream(fis, jsonfile.fileSize); - fis.close(); + let file = await File.createFromNsIFile(jsonfile); + + let addonObj = await new Promise(resolve => { + let fr = new FileReader(); + fr.readAsText(file); + fr.onloadend = () => { + resolve(JSON.parse(fr.result)); + } + }); + delete addonObj.optionsType; let stream = AM_Cc["@mozilla.org/network/file-output-stream;1"]. diff --git a/toolkit/xre/nsNativeAppSupportWin.cpp b/toolkit/xre/nsNativeAppSupportWin.cpp index 9bc18c28fde6..9388492d7269 100644 --- a/toolkit/xre/nsNativeAppSupportWin.cpp +++ b/toolkit/xre/nsNativeAppSupportWin.cpp @@ -963,7 +963,8 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t } // Get content window. - nsCOMPtr internalContent = nsGlobalWindow::Cast(piNavWin)->GetContent(); + nsCOMPtr internalContent = + nsGlobalWindowOuter::Cast(piNavWin)->GetContent(); if ( !internalContent ) { break; } diff --git a/tools/lint/docs/linters/eslint-plugin-mozilla.rst b/tools/lint/docs/linters/eslint-plugin-mozilla.rst index 92646b4fa08c..a95badfe05fb 100644 --- a/tools/lint/docs/linters/eslint-plugin-mozilla.rst +++ b/tools/lint/docs/linters/eslint-plugin-mozilla.rst @@ -59,11 +59,6 @@ avoid-removeChild Rejects using element.parentNode.removeChild(element) when element.remove() can be used instead. -avoid-nsISupportsString-preferences ------------------------------------ - -Rejects using getComplexValue and setComplexValue with nsISupportsString. - balanced-listeners ------------------ diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js index 736d19349e0a..adb3f5baaec7 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js @@ -137,7 +137,6 @@ module.exports = { // Maximum depth callbacks can be nested. "max-nested-callbacks": ["error", 10], - "mozilla/avoid-nsISupportsString-preferences": "error", "mozilla/avoid-removeChild": "error", "mozilla/import-browser-window-globals": "error", "mozilla/import-globals": "error", diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js index e527adfe8472..97cae4f8fb72 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js @@ -32,8 +32,6 @@ module.exports = { rules: { "avoid-Date-timing": require("../lib/rules/avoid-Date-timing"), "avoid-removeChild": require("../lib/rules/avoid-removeChild"), - "avoid-nsISupportsString-preferences": - require("../lib/rules/avoid-nsISupportsString-preferences"), "balanced-listeners": require("../lib/rules/balanced-listeners"), "import-browser-window-globals": require("../lib/rules/import-browser-window-globals"), @@ -66,7 +64,6 @@ module.exports = { rulesConfig: { "avoid-Date-timing": "off", "avoid-removeChild": "off", - "avoid-nsISupportsString-preferences": "off", "balanced-listeners": "off", "import-browser-window-globals": "off", "import-content-task-globals": "off", diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/avoid-nsISupportsString-preferences.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/avoid-nsISupportsString-preferences.js deleted file mode 100644 index 12af205a292c..000000000000 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/avoid-nsISupportsString-preferences.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @fileoverview Rejects using getComplexValue and setComplexValue with - * nsISupportsString. - * - * 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"; - -// ----------------------------------------------------------------------------- -// Rule Definition -// ----------------------------------------------------------------------------- - -function isNsISupportsString(arg) { - let isNsISupportsStringIdentifier = obj => - obj.type == "Identifier" && obj.name == "nsISupportsString"; - return isNsISupportsStringIdentifier(arg) || - (arg.type == "MemberExpression" && - isNsISupportsStringIdentifier(arg.property)); -} - -module.exports = function(context) { - - // --------------------------------------------------------------------------- - // Public - // -------------------------------------------------------------------------- - - return { - "CallExpression": function(node) { - let callee = node.callee; - if (callee.type !== "MemberExpression" || - callee.property.type !== "Identifier" || - node.arguments.length < 2 || - !isNsISupportsString(node.arguments[1])) { - return; - } - - if (callee.property.name == "getComplexValue") { - context.report(node, "use getStringPref instead of " + - "getComplexValue with nsISupportsString"); - } else if (callee.property.name == "setComplexValue") { - context.report(node, "use setStringPref instead of " + - "setComplexValue with nsISupportsString"); - } - } - }; -}; diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package.json b/tools/lint/eslint/eslint-plugin-mozilla/package.json index f83e7aa6ebcc..142f23396cf9 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "0.4.6", + "version": "0.4.7", "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.", "keywords": [ "eslint", diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-nsISupportsString-preferences.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-nsISupportsString-preferences.js deleted file mode 100644 index 883b8508601c..000000000000 --- a/tools/lint/eslint/eslint-plugin-mozilla/tests/avoid-nsISupportsString-preferences.js +++ /dev/null @@ -1,41 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -// ------------------------------------------------------------------------------ -// Requirements -// ------------------------------------------------------------------------------ - -var rule = require("../lib/rules/avoid-nsISupportsString-preferences"); -var RuleTester = require("eslint/lib/testers/rule-tester"); - -const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } }); - -// ------------------------------------------------------------------------------ -// Tests -// ------------------------------------------------------------------------------ - -function invalidCode(code, accessType = "get") { - let message = "use " + accessType + "StringPref instead of " + - accessType + "ComplexValue with nsISupportsString"; - return {code, errors: [{message, type: "CallExpression"}]}; -} - -ruleTester.run("avoid-nsISupportsString-preferences", rule, { - valid: [ - "branch.getStringPref('name');", - "branch.getComplexValue('name', Ci.nsIPrefLocalizedString);", - "branch.setStringPref('name', 'blah');", - "branch.setComplexValue('name', Ci.nsIPrefLocalizedString, pref);" - ], - invalid: [ - invalidCode("branch.getComplexValue('name', Ci.nsISupportsString);"), - invalidCode("branch.getComplexValue('name', nsISupportsString);"), - invalidCode("branch.getComplexValue('name', Ci.nsISupportsString).data;"), - invalidCode("branch.setComplexValue('name', Ci.nsISupportsString, str);", - "set"), - invalidCode("branch.setComplexValue('name', nsISupportsString, str);", - "set") - ] -}); diff --git a/tools/profiler/core/PlatformMacros.h b/tools/profiler/core/PlatformMacros.h index a191a34289d0..ce8682bbd20c 100644 --- a/tools/profiler/core/PlatformMacros.h +++ b/tools/profiler/core/PlatformMacros.h @@ -18,6 +18,7 @@ #undef GP_PLAT_aarch64_android #undef GP_PLAT_x86_linux #undef GP_PLAT_amd64_linux +#undef GP_PLAT_mips64_linux #undef GP_PLAT_amd64_darwin #undef GP_PLAT_x86_windows #undef GP_PLAT_amd64_windows @@ -26,6 +27,7 @@ #undef GP_ARCH_amd64 #undef GP_ARCH_arm #undef GP_ARCH_aarch64 +#undef GP_ARCH_mips64 #undef GP_OS_android #undef GP_OS_linux @@ -60,6 +62,11 @@ # define GP_ARCH_amd64 1 # define GP_OS_linux 1 +#elif defined(__linux__) && defined(__mips64) +# define GP_PLAT_mips64_linux 1 +# define GP_ARCH_mips64 1 +# define GP_OS_linux 1 + #elif defined(__APPLE__) && defined(__x86_64__) # define GP_PLAT_amd64_darwin 1 # define GP_ARCH_amd64 1 diff --git a/tools/profiler/core/platform-linux-android.cpp b/tools/profiler/core/platform-linux-android.cpp index b4239855a005..f40f3ab159e1 100644 --- a/tools/profiler/core/platform-linux-android.cpp +++ b/tools/profiler/core/platform-linux-android.cpp @@ -108,6 +108,11 @@ PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) aRegs.mSP = reinterpret_cast
(mcontext.sp); aRegs.mFP = reinterpret_cast
(mcontext.regs[29]); aRegs.mLR = reinterpret_cast
(mcontext.regs[30]); +#elif defined(GP_ARCH_mips64) + aRegs.mPC = reinterpret_cast
(mcontext.pc); + aRegs.mSP = reinterpret_cast
(mcontext.gregs[29]); + aRegs.mFP = reinterpret_cast
(mcontext.gregs[30]); + #else # error "bad platform" #endif @@ -366,7 +371,7 @@ Sampler::SuspendAndSampleAndResumeThread(PSLockRef aLock, } MOZ_ASSERT(r == 0); break; - } + } // The profiler's critical section ends here. After this point, none of the // critical section limitations documented above apply. diff --git a/widget/WidgetEventImpl.cpp b/widget/WidgetEventImpl.cpp index 6445ceea55a3..2204aaacd7c2 100644 --- a/widget/WidgetEventImpl.cpp +++ b/widget/WidgetEventImpl.cpp @@ -880,8 +880,9 @@ WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray& aCandidates) con // the priority of the charCodes are: // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0] // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],... - if (mCharCode) { - uint32_t ch = mCharCode; + uint32_t pseudoCharCode = PseudoCharCode(); + if (pseudoCharCode) { + uint32_t ch = pseudoCharCode; if (IS_IN_BMP(ch)) { ch = ToLowerCase(static_cast(ch)); } @@ -898,7 +899,7 @@ WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray& aCandidates) con if (IS_IN_BMP(ch[j])) { ch[j] = ToLowerCase(static_cast(ch[j])); } - // Don't append the mCharCode that was already appended. + // Don't append the charcode that was already appended. if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex) { aCandidates.AppendElement(ch[j]); } @@ -910,7 +911,7 @@ WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray& aCandidates) con // press. However, if the space key is assigned to a function key, it // shouldn't work as a space key. if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING && - mCodeNameIndex == CODE_NAME_INDEX_Space && mCharCode != ' ') { + mCodeNameIndex == CODE_NAME_INDEX_Space && pseudoCharCode != ' ') { aCandidates.AppendElement(' '); } } diff --git a/xpfe/appshell/nsWindowMediator.cpp b/xpfe/appshell/nsWindowMediator.cpp index 12fa39a4080a..2e8503e22d8a 100644 --- a/xpfe/appshell/nsWindowMediator.cpp +++ b/xpfe/appshell/nsWindowMediator.cpp @@ -352,7 +352,7 @@ NS_IMETHODIMP nsWindowMediator::GetOuterWindowWithId(uint64_t aWindowID, mozIDOMWindowProxy** aWindow) { - RefPtr window = nsGlobalWindow::GetOuterWindowWithId(aWindowID); + RefPtr window = nsGlobalWindowOuter::GetOuterWindowWithId(aWindowID); nsCOMPtr outer = window ? window->AsOuter() : nullptr; outer.forget(aWindow); return NS_OK; @@ -362,7 +362,7 @@ NS_IMETHODIMP nsWindowMediator::GetCurrentInnerWindowWithId(uint64_t aWindowID, mozIDOMWindow** aWindow) { - RefPtr window = nsGlobalWindow::GetInnerWindowWithId(aWindowID); + RefPtr window = nsGlobalWindowInner::GetInnerWindowWithId(aWindowID); // not found if (!window)