Loading docshell/base/URIFixup.jsm +33 −2 Original line number Diff line number Diff line Loading @@ -55,6 +55,13 @@ XPCOMUtils.defineLazyServiceGetter( "nsIDNSService" ); XPCOMUtils.defineLazyServiceGetter( lazy, "handlerService", "@mozilla.org/uriloader/handler-service;1", "nsIHandlerService" ); XPCOMUtils.defineLazyPreferenceGetter( lazy, "fixupSchemeTypos", Loading Loading @@ -259,7 +266,15 @@ XPCOMUtils.defineLazyGetter(lazy, "knownSuffixes", () => { return suffixes; }); function URIFixup() {} function URIFixup() { // There are cases that nsIExternalProtocolService.externalProtocolHandlerExists() does // not work well and returns always true due to flatpak. In this case, in order to // fallback to nsIHandlerService.exits(), we test whether can trust // nsIExternalProtocolService here. this._trustExternalProtocolService = !lazy.externalProtocolService.externalProtocolHandlerExists( `__dummy${Date.now()}__` ); } URIFixup.prototype = { get FIXUP_FLAG_NONE() { Loading Loading @@ -329,7 +344,7 @@ URIFixup.prototype = { scheme && (isCommonProtocol || Services.io.getProtocolHandler(scheme) != lazy.defaultProtocolHandler || lazy.externalProtocolService.externalProtocolHandlerExists(scheme)); this._isKnownExternalProtocol(scheme)); if ( canHandleProtocol || Loading Loading @@ -631,6 +646,22 @@ URIFixup.prototype = { isDomainKnown, _isKnownExternalProtocol(scheme) { if (this._trustExternalProtocolService) { return lazy.externalProtocolService.externalProtocolHandlerExists(scheme); } try { // nsIExternalProtocolService.getProtocolHandlerInfo() on Android throws // error due to not implemented. return lazy.handlerService.exists( lazy.externalProtocolService.getProtocolHandlerInfo(scheme) ); } catch (e) { return false; } }, classID: Components.ID("{c6cf88b7-452e-47eb-bdc9-86e3561648ef}"), QueryInterface: ChromeUtils.generateQI(["nsIURIFixup"]), }; Loading docshell/test/unit/test_URIFixup_external_protocol_fallback.js 0 → 100644 +100 −0 Original line number Diff line number Diff line /* 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"; // Test whether fallback mechanism is working if don't trust nsIExternalProtocolService. const { MockRegistrar } = ChromeUtils.import( "resource://testing-common/MockRegistrar.jsm" ); add_task(async function setup() { info( "Prepare mock nsIExternalProtocolService whose externalProtocolHandlerExists returns always true" ); const externalProtocolService = Cc[ "@mozilla.org/uriloader/external-protocol-service;1" ].getService(Ci.nsIExternalProtocolService); const mockId = MockRegistrar.register( "@mozilla.org/uriloader/external-protocol-service;1", { getProtocolHandlerInfo: scheme => externalProtocolService.getProtocolHandlerInfo(scheme), externalProtocolHandlerExists: () => true, QueryInterface: ChromeUtils.generateQI(["nsIExternalProtocolService"]), } ); const mockExternalProtocolService = Cc[ "@mozilla.org/uriloader/external-protocol-service;1" ].getService(Ci.nsIExternalProtocolService); Assert.ok( mockExternalProtocolService.externalProtocolHandlerExists("__invalid__"), "Mock service is working" ); info("Register new dummy protocol"); const dummyProtocolHandlerInfo = externalProtocolService.getProtocolHandlerInfo( "dummy" ); const handlerService = Cc[ "@mozilla.org/uriloader/handler-service;1" ].getService(Ci.nsIHandlerService); handlerService.store(dummyProtocolHandlerInfo); info("Prepare test search engine"); await setupSearchService(); await addTestEngines(); await Services.search.setDefault( Services.search.getEngineByName(kSearchEngineID) ); registerCleanupFunction(() => { handlerService.remove(dummyProtocolHandlerInfo); MockRegistrar.unregister(mockId); }); }); add_task(function basic() { const testData = [ { input: "mailto:test@example.com", expected: isSupportedInHandlerService("mailto") ? "mailto:test@example.com" : "http://mailto:test@example.com/", }, { input: "keyword:search", expected: "https://www.example.org/?search=keyword%3Asearch", }, { input: "dummy:protocol", expected: "dummy:protocol", }, ]; for (const { input, expected } of testData) { assertFixup(input, expected); } }); function assertFixup(input, expected) { const { preferredURI } = Services.uriFixup.getFixupURIInfo( input, Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS ); Assert.equal(preferredURI.spec, expected); } function isSupportedInHandlerService(scheme) { const externalProtocolService = Cc[ "@mozilla.org/uriloader/external-protocol-service;1" ].getService(Ci.nsIExternalProtocolService); const handlerService = Cc[ "@mozilla.org/uriloader/handler-service;1" ].getService(Ci.nsIHandlerService); return handlerService.exists( externalProtocolService.getProtocolHandlerInfo(scheme) ); } docshell/test/unit/xpcshell.ini +3 −1 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ support-files = [test_browsing_context_structured_clone.js] [test_URIFixup.js] [test_URIFixup_check_host.js] [test_URIFixup_external_protocol_fallback.js] skip-if = os == 'android' [test_URIFixup_forced.js] # Disabled for 1563343 -- URI fixup should be done at the app level in GV. skip-if = os == 'android' Loading Loading
docshell/base/URIFixup.jsm +33 −2 Original line number Diff line number Diff line Loading @@ -55,6 +55,13 @@ XPCOMUtils.defineLazyServiceGetter( "nsIDNSService" ); XPCOMUtils.defineLazyServiceGetter( lazy, "handlerService", "@mozilla.org/uriloader/handler-service;1", "nsIHandlerService" ); XPCOMUtils.defineLazyPreferenceGetter( lazy, "fixupSchemeTypos", Loading Loading @@ -259,7 +266,15 @@ XPCOMUtils.defineLazyGetter(lazy, "knownSuffixes", () => { return suffixes; }); function URIFixup() {} function URIFixup() { // There are cases that nsIExternalProtocolService.externalProtocolHandlerExists() does // not work well and returns always true due to flatpak. In this case, in order to // fallback to nsIHandlerService.exits(), we test whether can trust // nsIExternalProtocolService here. this._trustExternalProtocolService = !lazy.externalProtocolService.externalProtocolHandlerExists( `__dummy${Date.now()}__` ); } URIFixup.prototype = { get FIXUP_FLAG_NONE() { Loading Loading @@ -329,7 +344,7 @@ URIFixup.prototype = { scheme && (isCommonProtocol || Services.io.getProtocolHandler(scheme) != lazy.defaultProtocolHandler || lazy.externalProtocolService.externalProtocolHandlerExists(scheme)); this._isKnownExternalProtocol(scheme)); if ( canHandleProtocol || Loading Loading @@ -631,6 +646,22 @@ URIFixup.prototype = { isDomainKnown, _isKnownExternalProtocol(scheme) { if (this._trustExternalProtocolService) { return lazy.externalProtocolService.externalProtocolHandlerExists(scheme); } try { // nsIExternalProtocolService.getProtocolHandlerInfo() on Android throws // error due to not implemented. return lazy.handlerService.exists( lazy.externalProtocolService.getProtocolHandlerInfo(scheme) ); } catch (e) { return false; } }, classID: Components.ID("{c6cf88b7-452e-47eb-bdc9-86e3561648ef}"), QueryInterface: ChromeUtils.generateQI(["nsIURIFixup"]), }; Loading
docshell/test/unit/test_URIFixup_external_protocol_fallback.js 0 → 100644 +100 −0 Original line number Diff line number Diff line /* 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"; // Test whether fallback mechanism is working if don't trust nsIExternalProtocolService. const { MockRegistrar } = ChromeUtils.import( "resource://testing-common/MockRegistrar.jsm" ); add_task(async function setup() { info( "Prepare mock nsIExternalProtocolService whose externalProtocolHandlerExists returns always true" ); const externalProtocolService = Cc[ "@mozilla.org/uriloader/external-protocol-service;1" ].getService(Ci.nsIExternalProtocolService); const mockId = MockRegistrar.register( "@mozilla.org/uriloader/external-protocol-service;1", { getProtocolHandlerInfo: scheme => externalProtocolService.getProtocolHandlerInfo(scheme), externalProtocolHandlerExists: () => true, QueryInterface: ChromeUtils.generateQI(["nsIExternalProtocolService"]), } ); const mockExternalProtocolService = Cc[ "@mozilla.org/uriloader/external-protocol-service;1" ].getService(Ci.nsIExternalProtocolService); Assert.ok( mockExternalProtocolService.externalProtocolHandlerExists("__invalid__"), "Mock service is working" ); info("Register new dummy protocol"); const dummyProtocolHandlerInfo = externalProtocolService.getProtocolHandlerInfo( "dummy" ); const handlerService = Cc[ "@mozilla.org/uriloader/handler-service;1" ].getService(Ci.nsIHandlerService); handlerService.store(dummyProtocolHandlerInfo); info("Prepare test search engine"); await setupSearchService(); await addTestEngines(); await Services.search.setDefault( Services.search.getEngineByName(kSearchEngineID) ); registerCleanupFunction(() => { handlerService.remove(dummyProtocolHandlerInfo); MockRegistrar.unregister(mockId); }); }); add_task(function basic() { const testData = [ { input: "mailto:test@example.com", expected: isSupportedInHandlerService("mailto") ? "mailto:test@example.com" : "http://mailto:test@example.com/", }, { input: "keyword:search", expected: "https://www.example.org/?search=keyword%3Asearch", }, { input: "dummy:protocol", expected: "dummy:protocol", }, ]; for (const { input, expected } of testData) { assertFixup(input, expected); } }); function assertFixup(input, expected) { const { preferredURI } = Services.uriFixup.getFixupURIInfo( input, Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS ); Assert.equal(preferredURI.spec, expected); } function isSupportedInHandlerService(scheme) { const externalProtocolService = Cc[ "@mozilla.org/uriloader/external-protocol-service;1" ].getService(Ci.nsIExternalProtocolService); const handlerService = Cc[ "@mozilla.org/uriloader/handler-service;1" ].getService(Ci.nsIHandlerService); return handlerService.exists( externalProtocolService.getProtocolHandlerInfo(scheme) ); }
docshell/test/unit/xpcshell.ini +3 −1 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ support-files = [test_browsing_context_structured_clone.js] [test_URIFixup.js] [test_URIFixup_check_host.js] [test_URIFixup_external_protocol_fallback.js] skip-if = os == 'android' [test_URIFixup_forced.js] # Disabled for 1563343 -- URI fixup should be done at the app level in GV. skip-if = os == 'android' Loading