tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit b652076c527679b102ff06d4926b2277c263ec43
parent 397c3187280dfa84ce9da56a9944d945bf73977d
Author: Mark Banner <standard8@mozilla.com>
Date:   Wed, 29 Oct 2025 13:58:47 +0000

Bug 1997053 - Add a warning, and set a preference if a search engine matches the ignore lists. r=search-reviewers,daleharvey

Differential Revision: https://phabricator.services.mozilla.com/D270470

Diffstat:
Mtoolkit/components/search/SearchService.sys.mjs | 13++++++++++++-
Mtoolkit/components/search/tests/xpcshell/settings/ignorelist.json | 3++-
Mtoolkit/components/search/tests/xpcshell/test_ignorelist.js | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mtoolkit/modules/Troubleshoot.sys.mjs | 1+
4 files changed, 123 insertions(+), 6 deletions(-)

diff --git a/toolkit/components/search/SearchService.sys.mjs b/toolkit/components/search/SearchService.sys.mjs @@ -1690,7 +1690,18 @@ export class SearchService { * Returns true if the engine matches a ignorelists entry. */ #engineMatchesIgnoreLists(engine) { + /** @type {(name: string, url: string, type: string) => void} */ + let logIgnored = (name, url, type) => { + lazy.logConsole.warn("Search engine", name, `matches ${type}`, url); + Services.prefs.setCharPref( + lazy.SearchUtils.BROWSER_SEARCH_PREF + "lastEngineIgnored", + // Limit length of url to avoid storing too much in prefs. + `${Math.trunc(Date.now() / 1000)} Search engine '${name}' matches ${type} ignore list ${url.substring(0, 200)}` + ); + }; + if (this.#loadPathIgnoreList.includes(engine._loadPath)) { + logIgnored(engine.name, engine._loadPath, "load path"); return true; } let url = engine.searchURLWithNoTerms.spec.toLowerCase(); @@ -1699,6 +1710,7 @@ export class SearchService { url.includes(code.toLowerCase()) ) ) { + logIgnored(engine.name, url, "submission url"); return true; } return false; @@ -2486,7 +2498,6 @@ export class SearchService { */ #addEngineToStore(engine, skipDuplicateCheck = false) { if (this.#engineMatchesIgnoreLists(engine)) { - lazy.logConsole.debug("#addEngineToStore: Ignoring engine"); return; } diff --git a/toolkit/components/search/tests/xpcshell/settings/ignorelist.json b/toolkit/components/search/tests/xpcshell/settings/ignorelist.json @@ -63,7 +63,8 @@ "_definedAliases": [], "_updateInterval": null, "_updateURL": null, - "_iconUpdateURL": null + "_iconUpdateURL": null, + "_loadPath": "[https]www.example.com/search.xml" } ] } diff --git a/toolkit/components/search/tests/xpcshell/test_ignorelist.js b/toolkit/components/search/tests/xpcshell/test_ignorelist.js @@ -41,7 +41,7 @@ add_setup(async () => { }); add_task(async function test_ignoreListOnLoadSettings() { - consoleAllowList.push("Failed to load"); + let finishListening = TestUtils.listenForConsoleMessages(); Assert.ok( !Services.search.isInitialized, @@ -63,12 +63,12 @@ add_task(async function test_ignoreListOnLoadSettings() { await ignoreListUpdateCompleted; Assert.ok( - !(await Services.search.getEngineByName("Test search engine")), + !Services.search.getEngineByName("Test search engine"), "Should not have installed the add-on engine from settings" ); Assert.ok( - !(await Services.search.getEngineByName("OpenSearchTest")), + !Services.search.getEngineByName("OpenSearchTest"), "Should not have installed the OpenSearch engine from settings" ); @@ -77,6 +77,45 @@ add_task(async function test_ignoreListOnLoadSettings() { ["defaultEngine"], "Should have correctly started and installed only the default engine" ); + + assertPreference( + "OpenSearchTest", + "submission url", + "https://www.example.com/test?search_query=&opensearch=sng" + ); + + let consoleMessages = await finishListening(); + Assert.deepEqual( + consoleMessages + .filter(msg => msg.level == "warn") + .map(msg => { + return { + level: msg.level, + arguments: msg.arguments, + }; + }), + [ + { + level: "warn", + arguments: [ + "Search engine", + "Test search engine", + "matches submission url", + "https://www.example.com/search?q=&ignore=true&channel=sng", + ], + }, + { + level: "warn", + arguments: [ + "Search engine", + "OpenSearchTest", + "matches submission url", + "https://www.example.com/test?search_query=&opensearch=sng", + ], + }, + ], + "Should log console warnings for both search engines" + ); }); add_task(async function test_ignoreListOnInstall() { @@ -88,18 +127,26 @@ add_task(async function test_ignoreListOnInstall() { await SearchTestUtils.installSearchExtension({ name: kSearchEngineID1, search_url: kSearchEngineURL1, + search_url_get_params: "", }); let engine = Services.search.getEngineByName(kSearchEngineID1); Assert.equal( engine, null, - "Engine with ignored search params should not exist" + "Engine with ignored search params should not be added" + ); + + assertPreference( + kSearchEngineID1, + "submission url", + kSearchEngineURL1.replace("{searchTerms}", "") ); await SearchTestUtils.installSearchExtension({ name: kSearchEngineID2, search_url: kSearchEngineURL2, + search_url_get_params: "", }); // An ignored engine shouldn't be available at all @@ -110,10 +157,19 @@ add_task(async function test_ignoreListOnInstall() { "Engine with ignored search params of a different case should not exist" ); + assertPreference( + kSearchEngineID2, + "submission url", + kSearchEngineURL2.replace("{searchTerms}", "").toLowerCase() + ); + + let finishListening = TestUtils.listenForConsoleMessages(); + await SearchTestUtils.installSearchExtension({ id: kExtensionID, name: kSearchEngineID3, search_url: kSearchEngineURL3, + search_url_get_params: "", }); // An ignored engine shouldn't be available at all @@ -123,4 +179,52 @@ add_task(async function test_ignoreListOnInstall() { null, "Engine with ignored extension id should not exist" ); + + assertPreference(kSearchEngineID3, "load path", `[addon]${kExtensionID}`); + + let consoleMessages = await finishListening(); + Assert.deepEqual( + consoleMessages + .filter(msg => msg.level == "warn") + .map(msg => { + return { + level: msg.level, + arguments: msg.arguments, + }; + }), + [ + { + level: "warn", + arguments: [ + "Search engine", + kSearchEngineID3, + "matches load path", + `[addon]${kExtensionID}`, + ], + }, + ], + "Should have logged a console message" + ); }); + +/** + * Asserts that the lastEngineIgnored preference is set correctly. + * + * @param {string} engineName + * @param {string} ignoreListtype + * @param {string} url + */ +function assertPreference(engineName, ignoreListtype, url) { + let prefValue = Services.prefs.getCharPref( + SearchUtils.BROWSER_SEARCH_PREF + "lastEngineIgnored" + ); + let matchResult = prefValue.match(/\d+ (.*?) (?:(https.*|\[.*))/); + Assert.deepEqual( + matchResult.slice(1), + [ + `Search engine '${engineName}' matches ${ignoreListtype} ignore list`, + url, + ], + "Should have set the preference to the last engine ignored" + ); +} diff --git a/toolkit/modules/Troubleshoot.sys.mjs b/toolkit/modules/Troubleshoot.sys.mjs @@ -41,6 +41,7 @@ const PREFS_FOR_DISPLAY = [ "browser.places.", "browser.privatebrowsing.", "browser.search.context.loadInBackground", + "browser.search.lastEngineIgnored", "browser.search.lastSettingsCorruptTime", "browser.search.log", "browser.search.openintab",