author | Bob Owen <bobowencode@gmail.com> |
Mon, 06 Feb 2017 12:14:21 +0000 | |
changeset 340980 | 662482ab945913174d88816e1dfeada3bf234571 |
parent 340979 | efc2b3d143d0b422e391a015d6112b90ef66f066 |
child 340981 | d7651c30f604c3f532ad37256821f8c3102c7e29 |
push id | 31322 |
push user | kwierso@gmail.com |
push date | Tue, 07 Feb 2017 01:45:28 +0000 |
treeherder | mozilla-central@af8a2573d0f1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Gijs |
bugs | 1317921 |
milestone | 54.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/modules/E10SUtils.jsm +++ b/browser/modules/E10SUtils.jsm @@ -8,18 +8,22 @@ this.EXPORTED_SYMBOLS = ["E10SUtils"]; const {interfaces: Ci, utils: Cu, classes: Cc} = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyPreferenceGetter(this, "useRemoteWebExtensions", "extensions.webextensions.remote", false); +XPCOMUtils.defineLazyPreferenceGetter(this, "useSeparateFileUriProcess", + "browser.tabs.remote.separateFileUriProcess", false); XPCOMUtils.defineLazyModuleGetter(this, "Utils", "resource://gre/modules/sessionstore/Utils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "console", + "resource://gre/modules/Console.jsm"); function getAboutModule(aURL) { // Needs to match NS_GetAboutModuleName let moduleName = aURL.path.replace(/[#?].*/, "").toLowerCase(); let contract = "@mozilla.org/network/protocol/about;1?what=" + moduleName; try { return Cc[contract].getService(Ci.nsIAboutModule); } catch (e) { @@ -51,112 +55,125 @@ this.E10SUtils = { canLoadURIInProcess(aURL, aProcess) { let remoteType = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT ? DEFAULT_REMOTE_TYPE : NOT_REMOTE; return remoteType == this.getRemoteTypeForURI(aURL, true, remoteType); }, getRemoteTypeForURI(aURL, aMultiProcess, - aPreferredRemoteType = DEFAULT_REMOTE_TYPE) { + aPreferredRemoteType = DEFAULT_REMOTE_TYPE) { if (!aMultiProcess) { return NOT_REMOTE; } // loadURI in browser.xml treats null as about:blank if (!aURL) { aURL = "about:blank"; } - // Javascript urls can load in any process, they apply to the current document - if (aURL.startsWith("javascript:")) { - return aPreferredRemoteType; - } - - // We need data: URI's to load in a remote process, because some of our - // tests rely on this. For blob: URI's, load them in their originating - // process unless it is non-remote. In that case, favor a remote (sandboxed) - // process with fewer privileges to limit exposure. - if (aURL.startsWith("data:") || aURL.startsWith("blob:")) { - return aPreferredRemoteType == NOT_REMOTE ? DEFAULT_REMOTE_TYPE - : aPreferredRemoteType; - } - - if (aURL.startsWith("file:")) { - return Services.prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess") - ? FILE_REMOTE_TYPE : DEFAULT_REMOTE_TYPE; + let uri; + try { + uri = Services.io.newURI(aURL); + } catch (e) { + // If we have an invalid URI, it's still possible that it might get + // fixed-up into a valid URI later on. However, we don't want to return + // aPreferredRemoteType here, in case the URI gets fixed-up into + // something that wouldn't normally run in that process. + return DEFAULT_REMOTE_TYPE; } - if (aURL.startsWith("about:")) { - // We need to special case about:blank because it needs to load in any. - if (aURL == "about:blank") { - return aPreferredRemoteType; - } + return this.getRemoteTypeForURIObject(uri, aMultiProcess, + aPreferredRemoteType); + }, - let url = Services.io.newURI(aURL); - let module = getAboutModule(url); - // If the module doesn't exist then an error page will be loading, that - // should be ok to load in any process - if (!module) { - return aPreferredRemoteType; - } - - let flags = module.getURIFlags(url); - if (flags & Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD) { - return DEFAULT_REMOTE_TYPE; - } - - // If the about page can load in parent or child, it should be safe to - // load in any remote type. - if (flags & Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD) { - return aPreferredRemoteType; - } - + getRemoteTypeForURIObject(aURI, aMultiProcess, + aPreferredRemoteType = DEFAULT_REMOTE_TYPE) { + if (!aMultiProcess) { return NOT_REMOTE; } - if (aURL.startsWith("chrome:")) { - let url; - try { - // This can fail for invalid Chrome URIs, in which case we will end up - // not loading anything anyway. - url = Services.io.newURI(aURL); - } catch (ex) { + switch (aURI.scheme) { + case "javascript": + // javascript URIs can load in any, they apply to the current document. return aPreferredRemoteType; - } + + case "data": + case "blob": + // We need data: and blob: URIs to load in any remote process, because + // they need to be able to load in whatever is the current process + // unless it is non-remote. In that case we don't want to load them in + // the parent process, so we load them in the default remote process, + // which is sandboxed and limits any risk. + return aPreferredRemoteType == NOT_REMOTE ? DEFAULT_REMOTE_TYPE + : aPreferredRemoteType; - let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]. - getService(Ci.nsIXULChromeRegistry); - if (chromeReg.mustLoadURLRemotely(url)) { - return DEFAULT_REMOTE_TYPE; - } + case "file": + return useSeparateFileUriProcess ? FILE_REMOTE_TYPE + : DEFAULT_REMOTE_TYPE; + + case "about": + let module = getAboutModule(aURI); + // If the module doesn't exist then an error page will be loading, that + // should be ok to load in any process + if (!module) { + return aPreferredRemoteType; + } + + let flags = module.getURIFlags(aURI); + if (flags & Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD) { + return DEFAULT_REMOTE_TYPE; + } - if (chromeReg.canLoadURLRemotely(url) && - aPreferredRemoteType != NOT_REMOTE) { - return DEFAULT_REMOTE_TYPE; - } + // If the about page can load in parent or child, it should be safe to + // load in any remote type. + if (flags & Ci.nsIAboutModule.URI_CAN_LOAD_IN_CHILD) { + return aPreferredRemoteType; + } + + return NOT_REMOTE; - return NOT_REMOTE; - } + case "chrome": + let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]. + getService(Ci.nsIXULChromeRegistry); + if (chromeReg.mustLoadURLRemotely(aURI)) { + return DEFAULT_REMOTE_TYPE; + } + + if (chromeReg.canLoadURLRemotely(aURI) && + aPreferredRemoteType != NOT_REMOTE) { + return DEFAULT_REMOTE_TYPE; + } - if (aURL.startsWith("moz-extension:")) { - return useRemoteWebExtensions ? EXTENSION_REMOTE_TYPE : NOT_REMOTE; - } + return NOT_REMOTE; + + case "moz-extension": + return useRemoteWebExtensions ? EXTENSION_REMOTE_TYPE : NOT_REMOTE; - if (aURL.startsWith("view-source:")) { - return this.getRemoteTypeForURI(aURL.substr("view-source:".length), - aMultiProcess, aPreferredRemoteType); + default: + // For any other nested URIs, we use the innerURI to determine the + // remote type. In theory we should use the innermost URI, but some URIs + // have fake inner URIs (e.g. about URIs with inner moz-safe-about) and + // if such URIs are wrapped in other nested schemes like view-source:, + // we don't want to "skip" past "about:" by going straight to the + // innermost URI. Any URIs like this will need to be handled in the + // cases above, so we don't still end up using the fake inner URI here. + if (aURI instanceof Ci.nsINestedURI) { + let innerURI = aURI.QueryInterface(Ci.nsINestedURI).innerURI; + return this.getRemoteTypeForURIObject(innerURI, aMultiProcess, + aPreferredRemoteType); + } + + return validatedWebRemoteType(aPreferredRemoteType); } - - return validatedWebRemoteType(aPreferredRemoteType); }, shouldLoadURIInThisProcess(aURI) { let remoteType = Services.appinfo.remoteType; - return remoteType == this.getRemoteTypeForURI(aURI.spec, true, remoteType); + return remoteType == this.getRemoteTypeForURIObject(aURI, true, remoteType); }, shouldLoadURI(aDocShell, aURI, aReferrer) { // Inner frames should always load in the current process if (aDocShell.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeParent) return true; // If we are in a Large-Allocation process, and it wouldn't be content visible