From c85769fef1e1813e51e29d380d87b8337e2bfd18 Mon Sep 17 00:00:00 2001 From: Alex Catarineu Date: Fri, 10 Jan 2020 17:54:18 +0100 Subject: [PATCH] Bug 32414: Make Services.search.addEngine obey FPI --- browser/base/content/browser-pageActions.js | 70 +++++++++++-------- mobile/android/chrome/content/browser.js | 15 +++- .../processsingleton/MainProcessSingleton.jsm | 8 ++- toolkit/components/search/SearchEngine.jsm | 6 +- toolkit/components/search/SearchService.jsm | 5 +- toolkit/components/search/SearchUtils.jsm | 4 +- .../components/search/nsISearchService.idl | 7 +- 7 files changed, 74 insertions(+), 41 deletions(-) diff --git a/browser/base/content/browser-pageActions.js b/browser/base/content/browser-pageActions.js index 33680b2b4c1ad..b2aefba866ddf 100644 --- a/browser/base/content/browser-pageActions.js +++ b/browser/base/content/browser-pageActions.js @@ -1248,38 +1248,46 @@ BrowserPageActions.addSearchEngine = { }, _installEngine(uri, image) { - Services.search.addEngine(uri, image, false).then( - engine => { - showBrowserPageActionFeedback(this.action); - }, - errorCode => { - if (errorCode != Ci.nsISearchService.ERROR_DUPLICATE_ENGINE) { - // Download error is shown by the search service - return; + Services.search + .addEngine( + uri, + image, + false, + null, + gBrowser.selectedBrowser.contentPrincipal + ) + .then( + engine => { + showBrowserPageActionFeedback(this.action); + }, + errorCode => { + if (errorCode != Ci.nsISearchService.ERROR_DUPLICATE_ENGINE) { + // Download error is shown by the search service + return; + } + const kSearchBundleURI = + "chrome://global/locale/search/search.properties"; + let searchBundle = Services.strings.createBundle(kSearchBundleURI); + let brandBundle = document.getElementById("bundle_brand"); + let brandName = brandBundle.getString("brandShortName"); + let title = searchBundle.GetStringFromName( + "error_invalid_engine_title" + ); + let text = searchBundle.formatStringFromName( + "error_duplicate_engine_msg", + [brandName, uri], + 2 + ); + Services.prompt.QueryInterface(Ci.nsIPromptFactory); + let prompt = Services.prompt.getPrompt( + gBrowser.contentWindow, + Ci.nsIPrompt + ); + prompt.QueryInterface(Ci.nsIWritablePropertyBag2); + prompt.setPropertyAsBool("allowTabModal", true); + prompt.alert(title, text); } - const kSearchBundleURI = - "chrome://global/locale/search/search.properties"; - let searchBundle = Services.strings.createBundle(kSearchBundleURI); - let brandBundle = document.getElementById("bundle_brand"); - let brandName = brandBundle.getString("brandShortName"); - let title = searchBundle.GetStringFromName( - "error_invalid_engine_title" - ); - let text = searchBundle.formatStringFromName( - "error_duplicate_engine_msg", - [brandName, uri], - 2 - ); - Services.prompt.QueryInterface(Ci.nsIPromptFactory); - let prompt = Services.prompt.getPrompt( - gBrowser.contentWindow, - Ci.nsIPrompt - ); - prompt.QueryInterface(Ci.nsIWritablePropertyBag2); - prompt.setPropertyAsBool("allowTabModal", true); - prompt.alert(title, text); - } - ); + ); }, }; diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 5f5ac123835c6..cacf265870914 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -7253,7 +7253,10 @@ var SearchEngines = { return; } - this.addOpenSearchEngine(engines[data.button]); + this.addOpenSearchEngine( + engines[data.button], + browser.contentPrincipal + ); engines.splice(data.button, 1); if (engines.length < 1) { @@ -7269,9 +7272,15 @@ var SearchEngines = { }); }, - addOpenSearchEngine: async function addOpenSearchEngine(engine) { + addOpenSearchEngine: async function addOpenSearchEngine(engine, principal) { try { - await Services.search.addEngine(engine.url, engine.iconURL, false); + await Services.search.addEngine( + engine.url, + engine.iconURL, + false, + null, + principal + ); // Display a toast confirming addition of new search engine. Snackbars.show( Strings.browser.formatStringFromName( diff --git a/toolkit/components/processsingleton/MainProcessSingleton.jsm b/toolkit/components/processsingleton/MainProcessSingleton.jsm index 1e8caebd6ebc8..69372bef17428 100644 --- a/toolkit/components/processsingleton/MainProcessSingleton.jsm +++ b/toolkit/components/processsingleton/MainProcessSingleton.jsm @@ -69,7 +69,13 @@ MainProcessSingleton.prototype = { } Services.search - .addEngine(engineURL.spec, iconURL ? iconURL.spec : null, true) + .addEngine( + engineURL.spec, + iconURL ? iconURL.spec : null, + true, + null, + browser.contentPrincipal + ) .catch(ex => Cu.reportError( "Unable to add search engine to the search service: " + ex diff --git a/toolkit/components/search/SearchEngine.jsm b/toolkit/components/search/SearchEngine.jsm index d84a3a23516cd..c4b5b1ce556e2 100644 --- a/toolkit/components/search/SearchEngine.jsm +++ b/toolkit/components/search/SearchEngine.jsm @@ -806,6 +806,8 @@ SearchEngine.prototype = { _iconUpdateURL: null, /* The extension ID if added by an extension. */ _extensionID: null, + /* The principal from which the engine was added. */ + _contentPrincipal: null, // Built in search engine extensions. _isBuiltin: false, @@ -851,7 +853,7 @@ SearchEngine.prototype = { '_initFromURIAndLoad: Downloading engine from: "' + loadURI.spec + '".' ); - var chan = SearchUtils.makeChannel(loadURI); + var chan = SearchUtils.makeChannel(loadURI, this._contentPrincipal); if (this._engineToUpdate && chan instanceof Ci.nsIHttpChannel) { var lastModified = this._engineToUpdate.getAttr("updatelastmodified"); @@ -1231,7 +1233,7 @@ SearchEngine.prototype = { this.name + '"' ); - var chan = SearchUtils.makeChannel(uri); + var chan = SearchUtils.makeChannel(uri, this._contentPrincipal); let iconLoadCallback = function(byteArray, engine) { // This callback may run after we've already set a preferred icon, diff --git a/toolkit/components/search/SearchService.jsm b/toolkit/components/search/SearchService.jsm index e869be458c7da..772edada7bfd0 100644 --- a/toolkit/components/search/SearchService.jsm +++ b/toolkit/components/search/SearchService.jsm @@ -2311,7 +2311,7 @@ SearchService.prototype = { return this.addEngineWithDetails(params.name, params, isReload); }, - async addEngine(engineURL, iconURL, confirm, extensionID) { + async addEngine(engineURL, iconURL, confirm, extensionID, contentPrincipal) { SearchUtils.log('addEngine: Adding "' + engineURL + '".'); await this.init(true); let errCode; @@ -2325,6 +2325,9 @@ SearchService.prototype = { if (extensionID) { engine._extensionID = extensionID; } + if (contentPrincipal) { + engine._contentPrincipal = contentPrincipal; + } errCode = await new Promise(resolve => { engine._installCallback = function(errorCode) { resolve(errorCode); diff --git a/toolkit/components/search/SearchUtils.jsm b/toolkit/components/search/SearchUtils.jsm index f9550307e875b..8b630afbdd6ee 100644 --- a/toolkit/components/search/SearchUtils.jsm +++ b/toolkit/components/search/SearchUtils.jsm @@ -133,13 +133,13 @@ var SearchUtils = { * The URL string from which to create an nsIChannel. * @returns an nsIChannel object, or null if the url is invalid. */ - makeChannel(url) { + makeChannel(url, principal) { try { let uri = typeof url == "string" ? Services.io.newURI(url) : url; return Services.io.newChannelFromURI( uri, null /* loadingNode */, - Services.scriptSecurityManager.getSystemPrincipal(), + principal || Services.scriptSecurityManager.getSystemPrincipal(), null /* triggeringPrincipal */, Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, Ci.nsIContentPolicy.TYPE_OTHER diff --git a/toolkit/components/search/nsISearchService.idl b/toolkit/components/search/nsISearchService.idl index 2e085985a976d..4a8f4015fb282 100644 --- a/toolkit/components/search/nsISearchService.idl +++ b/toolkit/components/search/nsISearchService.idl @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" +#include "nsIPrincipal.idl" interface nsIURI; interface nsIInputStream; @@ -288,11 +289,15 @@ interface nsISearchService : nsISupports * @param extensionID [optional] * Optional: The correct extensionID if called by an add-on. * + * @param principal [optional] + * Optional: The principal from which the search engine was added. + * * @throws NS_ERROR_FAILURE if the description file cannot be successfully * loaded. */ Promise addEngine(in AString engineURL, in AString iconURL, in boolean confirm, - [optional] in AString extensionID); + [optional] in AString extensionID, + [optional] in nsIPrincipal principal); /** * Adds a new search engine, without asking the user for confirmation and -- GitLab