From a90a5cba08fdf6c0ceb95101c275108a152a3aed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:35:37 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- .../test/unit/test_FirefoxBridgeExtensionUtils.js | 461 ++++++++++++--------- ...st_FirefoxBridgeExtensionUtilsNativeManifest.js | 115 +++++ 2 files changed, 380 insertions(+), 196 deletions(-) (limited to 'browser/modules/test/unit') diff --git a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js index 77db0d8286..d4dcd4fad6 100644 --- a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js +++ b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtils.js @@ -7,9 +7,10 @@ const { FirefoxBridgeExtensionUtils } = ChromeUtils.importESModule( "resource:///modules/FirefoxBridgeExtensionUtils.sys.mjs" ); -const FIREFOX_SHELL_OPEN_COMMAND_PATH = "firefox\\shell\\open\\command"; -const FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH = - "firefox-private\\shell\\open\\command"; +const OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL}\\shell\\open\\command`; +const OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL}\\shell\\open\\command`; +const FIREFOX_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL}\\shell\\open\\command`; +const FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH = `${FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL}\\shell\\open\\command`; class StubbedRegistryKey { #children; @@ -145,206 +146,274 @@ class StubbedDeleteBridgeProtocolRegistryEntryHelper { } add_task(async function test_DeleteWhenSameFirefoxInstall() { - const applicationPath = "testPath"; - - const firefoxEntries = new Map(); - firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`); - - const firefoxProtocolRegKey = new StubbedRegistryKey( - new Map(), - firefoxEntries - ); - - const firefoxPrivateEntries = new Map(); - firefoxPrivateEntries.set( - "", - `\"${applicationPath}\" -osint -private-window \"%1\"` - ); - const firefoxPrivateProtocolRegKey = new StubbedRegistryKey( - new Map(), - firefoxPrivateEntries - ); - - const children = new Map(); - children.set(FIREFOX_SHELL_OPEN_COMMAND_PATH, firefoxProtocolRegKey); - children.set( - FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, - firefoxPrivateProtocolRegKey - ); - - const registryRootKey = new StubbedRegistryKey(children, new Map()); - - const stubbedDeleteBridgeProtocolRegistryHelper = - new StubbedDeleteBridgeProtocolRegistryEntryHelper({ - applicationPath, - registryRootKey, - }); - - FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( - stubbedDeleteBridgeProtocolRegistryHelper - ); - - ok(registryRootKey.wasCloseCalled, "Root key closed"); - - ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened"); - ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed"); - ok( - registryRootKey.isChildDeleted("firefox"), - "Firefox protocol registry entry deleted" - ); - - ok( - firefoxPrivateProtocolRegKey.wasOpenedForRead, - "Firefox private key opened" - ); - ok(firefoxPrivateProtocolRegKey.wasCloseCalled, "Firefox private key closed"); - ok( - registryRootKey.isChildDeleted("firefox-private"), - "Firefox private protocol registry entry deleted" - ); + for (let protocols of [ + [ + FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL, + OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH, + OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, + ], + [ + FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL, + FIREFOX_SHELL_OPEN_COMMAND_PATH, + FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, + ], + ]) { + let [publicProtocol, privateProtocol, publicPath, privatePath] = protocols; + const applicationPath = "testPath"; + + const firefoxEntries = new Map(); + firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`); + + const firefoxProtocolRegKey = new StubbedRegistryKey( + new Map(), + firefoxEntries + ); + + const firefoxPrivateEntries = new Map(); + firefoxPrivateEntries.set( + "", + `\"${applicationPath}\" -osint -private-window \"%1\"` + ); + const firefoxPrivateProtocolRegKey = new StubbedRegistryKey( + new Map(), + firefoxPrivateEntries + ); + + const children = new Map(); + children.set(publicPath, firefoxProtocolRegKey); + children.set(privatePath, firefoxPrivateProtocolRegKey); + + const registryRootKey = new StubbedRegistryKey(children, new Map()); + + const stubbedDeleteBridgeProtocolRegistryHelper = + new StubbedDeleteBridgeProtocolRegistryEntryHelper({ + applicationPath, + registryRootKey, + }); + + FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( + publicProtocol, + privateProtocol, + stubbedDeleteBridgeProtocolRegistryHelper + ); + + ok(registryRootKey.wasCloseCalled, "Root key closed"); + + ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened"); + ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed"); + ok( + registryRootKey.isChildDeleted(publicProtocol), + "Firefox protocol registry entry deleted" + ); + + ok( + firefoxPrivateProtocolRegKey.wasOpenedForRead, + "Firefox private key opened" + ); + ok( + firefoxPrivateProtocolRegKey.wasCloseCalled, + "Firefox private key closed" + ); + ok( + registryRootKey.isChildDeleted(privateProtocol), + "Firefox private protocol registry entry deleted" + ); + } }); add_task(async function test_DeleteWhenDifferentFirefoxInstall() { - const applicationPath = "testPath"; - const badApplicationPath = "testPath2"; - - const firefoxEntries = new Map(); - firefoxEntries.set("", `\"${badApplicationPath}\" -osint -url \"%1\"`); - - const firefoxProtocolRegKey = new StubbedRegistryKey( - new Map(), - firefoxEntries - ); - - const firefoxPrivateEntries = new Map(); - firefoxPrivateEntries.set( - "", - `\"${badApplicationPath}\" -osint -private-window \"%1\"` - ); - const firefoxPrivateProtocolRegKey = new StubbedRegistryKey( - new Map(), - firefoxPrivateEntries - ); - - const children = new Map(); - children.set(FIREFOX_SHELL_OPEN_COMMAND_PATH, firefoxProtocolRegKey); - children.set( - FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, - firefoxPrivateProtocolRegKey - ); - - const registryRootKey = new StubbedRegistryKey(children, new Map()); - - const stubbedDeleteBridgeProtocolRegistryHelper = - new StubbedDeleteBridgeProtocolRegistryEntryHelper({ - applicationPath, - registryRootKey, - }); - - FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( - stubbedDeleteBridgeProtocolRegistryHelper - ); - - ok(registryRootKey.wasCloseCalled, "Root key closed"); - - ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened"); - ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed"); - ok( - !registryRootKey.isChildDeleted("firefox"), - "Firefox protocol registry entry not deleted" - ); - - ok( - firefoxPrivateProtocolRegKey.wasOpenedForRead, - "Firefox private key opened" - ); - ok(firefoxPrivateProtocolRegKey.wasCloseCalled, "Firefox private key closed"); - ok( - !registryRootKey.isChildDeleted("firefox-private"), - "Firefox private protocol registry entry not deleted" - ); + for (let protocols of [ + [ + FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL, + OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH, + OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, + ], + [ + FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL, + FIREFOX_SHELL_OPEN_COMMAND_PATH, + FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, + ], + ]) { + let [publicProtocol, privateProtocol, publicPath, privatePath] = protocols; + const applicationPath = "testPath"; + const badApplicationPath = "testPath2"; + + const firefoxEntries = new Map(); + firefoxEntries.set("", `\"${badApplicationPath}\" -osint -url \"%1\"`); + + const firefoxProtocolRegKey = new StubbedRegistryKey( + new Map(), + firefoxEntries + ); + + const firefoxPrivateEntries = new Map(); + firefoxPrivateEntries.set( + "", + `\"${badApplicationPath}\" -osint -private-window \"%1\"` + ); + const firefoxPrivateProtocolRegKey = new StubbedRegistryKey( + new Map(), + firefoxPrivateEntries + ); + + const children = new Map(); + children.set(publicPath, firefoxProtocolRegKey); + children.set(privatePath, firefoxPrivateProtocolRegKey); + + const registryRootKey = new StubbedRegistryKey(children, new Map()); + + const stubbedDeleteBridgeProtocolRegistryHelper = + new StubbedDeleteBridgeProtocolRegistryEntryHelper({ + applicationPath, + registryRootKey, + }); + + FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( + publicProtocol, + privateProtocol, + stubbedDeleteBridgeProtocolRegistryHelper + ); + + ok(registryRootKey.wasCloseCalled, "Root key closed"); + + ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened"); + ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed"); + ok( + !registryRootKey.isChildDeleted(publicProtocol), + "Firefox protocol registry entry not deleted" + ); + + ok( + firefoxPrivateProtocolRegKey.wasOpenedForRead, + "Firefox private key opened" + ); + ok( + firefoxPrivateProtocolRegKey.wasCloseCalled, + "Firefox private key closed" + ); + ok( + !registryRootKey.isChildDeleted(privateProtocol), + "Firefox private protocol registry entry not deleted" + ); + } }); add_task(async function test_DeleteWhenNoRegistryEntries() { - const applicationPath = "testPath"; - - const firefoxPrivateEntries = new Map(); - const firefoxPrivateProtocolRegKey = new StubbedRegistryKey( - new Map(), - firefoxPrivateEntries - ); - - const children = new Map(); - children.set( - FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, - firefoxPrivateProtocolRegKey - ); - - const registryRootKey = new StubbedRegistryKey(children, new Map()); - - const stubbedDeleteBridgeProtocolRegistryHelper = - new StubbedDeleteBridgeProtocolRegistryEntryHelper({ - applicationPath, - registryRootKey, - }); - - FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( - stubbedDeleteBridgeProtocolRegistryHelper - ); - - ok(registryRootKey.wasCloseCalled, "Root key closed"); - - ok( - firefoxPrivateProtocolRegKey.wasOpenedForRead, - "Firefox private key opened" - ); - ok(firefoxPrivateProtocolRegKey.wasCloseCalled, "Firefox private key closed"); - ok( - !registryRootKey.isChildDeleted("firefox"), - "Firefox protocol registry entry deleted when it shouldn't be" - ); - ok( - !registryRootKey.isChildDeleted("firefox-private"), - "Firefox private protocol registry deleted when it shouldn't be" - ); + for (let protocols of [ + [ + FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL, + OLD_FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, + ], + [ + FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL, + FIREFOX_PRIVATE_SHELL_OPEN_COMMAND_PATH, + ], + ]) { + let [publicProtocol, privateProtocol, privatePath] = protocols; + const applicationPath = "testPath"; + + const firefoxPrivateEntries = new Map(); + const firefoxPrivateProtocolRegKey = new StubbedRegistryKey( + new Map(), + firefoxPrivateEntries + ); + + const children = new Map(); + children.set(privatePath, firefoxPrivateProtocolRegKey); + + const registryRootKey = new StubbedRegistryKey(children, new Map()); + + const stubbedDeleteBridgeProtocolRegistryHelper = + new StubbedDeleteBridgeProtocolRegistryEntryHelper({ + applicationPath, + registryRootKey, + }); + + FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( + publicProtocol, + privateProtocol, + stubbedDeleteBridgeProtocolRegistryHelper + ); + + ok(registryRootKey.wasCloseCalled, "Root key closed"); + + ok( + firefoxPrivateProtocolRegKey.wasOpenedForRead, + "Firefox private key opened" + ); + ok( + firefoxPrivateProtocolRegKey.wasCloseCalled, + "Firefox private key closed" + ); + ok( + !registryRootKey.isChildDeleted(publicProtocol), + "Firefox protocol registry entry deleted when it shouldn't be" + ); + ok( + !registryRootKey.isChildDeleted(privateProtocol), + "Firefox private protocol registry deleted when it shouldn't be" + ); + } }); add_task(async function test_DeleteWhenUnexpectedRegistryEntries() { - const applicationPath = "testPath"; - - const firefoxEntries = new Map(); - firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`); - firefoxEntries.set("extraEntry", "extraValue"); - const firefoxProtocolRegKey = new StubbedRegistryKey( - new Map(), - firefoxEntries - ); - - const children = new Map(); - children.set(FIREFOX_SHELL_OPEN_COMMAND_PATH, firefoxProtocolRegKey); - - const registryRootKey = new StubbedRegistryKey(children, new Map()); - - const stubbedDeleteBridgeProtocolRegistryHelper = - new StubbedDeleteBridgeProtocolRegistryEntryHelper({ - applicationPath, - registryRootKey, - }); - - FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( - stubbedDeleteBridgeProtocolRegistryHelper - ); - - ok(registryRootKey.wasCloseCalled, "Root key closed"); - - ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened"); - ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed"); - ok( - !registryRootKey.isChildDeleted("firefox"), - "Firefox protocol registry entry deleted when it shouldn't be" - ); - ok( - !registryRootKey.isChildDeleted("firefox-private"), - "Firefox private protocol registry deleted when it shouldn't be" - ); + for (let protocols of [ + [ + FirefoxBridgeExtensionUtils.OLD_PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.OLD_PRIVATE_PROTOCOL, + OLD_FIREFOX_SHELL_OPEN_COMMAND_PATH, + ], + [ + FirefoxBridgeExtensionUtils.PUBLIC_PROTOCOL, + FirefoxBridgeExtensionUtils.PRIVATE_PROTOCOL, + FIREFOX_SHELL_OPEN_COMMAND_PATH, + ], + ]) { + let [publicProtocol, privateProtocol, publicPath] = protocols; + const applicationPath = "testPath"; + + const firefoxEntries = new Map(); + firefoxEntries.set("", `\"${applicationPath}\" -osint -url \"%1\"`); + firefoxEntries.set("extraEntry", "extraValue"); + const firefoxProtocolRegKey = new StubbedRegistryKey( + new Map(), + firefoxEntries + ); + + const children = new Map(); + children.set(publicPath, firefoxProtocolRegKey); + + const registryRootKey = new StubbedRegistryKey(children, new Map()); + + const stubbedDeleteBridgeProtocolRegistryHelper = + new StubbedDeleteBridgeProtocolRegistryEntryHelper({ + applicationPath, + registryRootKey, + }); + + FirefoxBridgeExtensionUtils.maybeDeleteBridgeProtocolRegistryEntries( + publicProtocol, + privateProtocol, + stubbedDeleteBridgeProtocolRegistryHelper + ); + + ok(registryRootKey.wasCloseCalled, "Root key closed"); + + ok(firefoxProtocolRegKey.wasOpenedForRead, "Firefox key opened"); + ok(firefoxProtocolRegKey.wasCloseCalled, "Firefox key closed"); + ok( + !registryRootKey.isChildDeleted(publicProtocol), + "Firefox protocol registry entry deleted when it shouldn't be" + ); + ok( + !registryRootKey.isChildDeleted(privateProtocol), + "Firefox private protocol registry deleted when it shouldn't be" + ); + } }); diff --git a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js index cef550d705..8686871255 100644 --- a/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js +++ b/browser/modules/test/unit/test_FirefoxBridgeExtensionUtilsNativeManifest.js @@ -16,6 +16,30 @@ const { FirefoxBridgeExtensionUtils } = ChromeUtils.importESModule( const DUAL_BROWSER_EXTENSION_ORIGIN = ["chrome-extension://fake-origin/"]; const NATIVE_MESSAGING_HOST_ID = "org.mozilla.firefox_bridge_test"; +if (AppConstants.platform == "win") { + var { MockRegistry } = ChromeUtils.importESModule( + "resource://testing-common/MockRegistry.sys.mjs" + ); +} + +let registry = null; +add_setup(() => { + if (AppConstants.platform == "win") { + registry = new MockRegistry(); + registerCleanupFunction(() => { + registry.shutdown(); + }); + } +}); + +function resetMockRegistry() { + if (AppConstants.platform != "win") { + return; + } + registry.shutdown(); + registry = new MockRegistry(); +} + let dir = FileUtils.getDir("TmpD", ["NativeMessagingHostsTest"]); dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); @@ -75,6 +99,35 @@ function getExpectedOutput() { }; } +function DumpWindowsRegistry() { + let key = ""; + let pathBuffer = []; + + if (AppConstants.platform == "win") { + function bufferPrint(line) { + let regPath = line.trimStart(); + if (regPath.includes(":")) { + // After trimming white space, keys are formatted as + // ": ()". We can assume it's only ever + // going to be of type REG_SZ for this test. + key = regPath.slice(2, regPath.length - " (REG_SZ)".length); + } else { + pathBuffer.push(regPath); + } + } + + MockRegistry.dump( + MockRegistry.getRoot(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER), + "", + bufferPrint + ); + } else { + Assert.ok(false, "Only windows has a registry!"); + } + + return [pathBuffer, key]; +} + add_task(async function test_maybeWriteManifestFiles() { await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles( USER_TEST_PATH, @@ -196,6 +249,7 @@ add_task(async function test_ensureRegistered() { appDir.path, "Mozilla\\Firefox" ); + resetMockRegistry(); } else { throw new Error("Unsupported platform"); } @@ -219,4 +273,65 @@ add_task(async function test_ensureRegistered() { let JSONContent = await IOUtils.readUTF8(expectedJSONPath); await IOUtils.remove(expectedJSONPath); Assert.equal(JSONContent, expectedOutput); + + // Test that the registry key is written for Windows only + if (AppConstants.platform == "win") { + let [pathBuffer, key] = DumpWindowsRegistry(); + Assert.equal( + pathBuffer.toString(), + [ + "Software", + "Google", + "Chrome", + "NativeMessagingHosts", + nativeHostId, + ].toString() + ); + Assert.equal(key, expectedJSONPath); + } +}); + +add_task(async function test_maybeWriteNativeMessagingRegKeys() { + if (AppConstants.platform != "win") { + return; + } + resetMockRegistry(); + FirefoxBridgeExtensionUtils.maybeWriteNativeMessagingRegKeys( + "Test\\Path\\For\\Reg\\Key", + binFile.parent.path, + NATIVE_MESSAGING_HOST_ID + ); + let [pathBuffer, key] = DumpWindowsRegistry(); + registry.shutdown(); + Assert.equal( + pathBuffer.toString(), + ["Test", "Path", "For", "Reg", "Key", NATIVE_MESSAGING_HOST_ID].toString() + ); + console.log("The key is: " + key); + Assert.equal(key, `${binFile.parent.path}\\${NATIVE_MESSAGING_HOST_ID}.json`); +}); + +add_task(async function test_maybeWriteNativeMessagingRegKeysIncorrectValue() { + if (AppConstants.platform != "win") { + return; + } + resetMockRegistry(); + registry.setValue( + Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, + `Test\\Path\\For\\Reg\\Key\\${NATIVE_MESSAGING_HOST_ID}`, + "", + "IncorrectValue" + ); + FirefoxBridgeExtensionUtils.maybeWriteNativeMessagingRegKeys( + "Test\\Path\\For\\Reg\\Key", + binFile.parent.path, + NATIVE_MESSAGING_HOST_ID + ); + let [pathBuffer, key] = DumpWindowsRegistry(); + registry.shutdown(); + Assert.equal( + pathBuffer.toString(), + ["Test", "Path", "For", "Reg", "Key", NATIVE_MESSAGING_HOST_ID].toString() + ); + Assert.equal(key, `${binFile.parent.path}\\${NATIVE_MESSAGING_HOST_ID}.json`); }); -- cgit v1.2.3