/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /** * This runs the xpcshell binary with different cases for the executable path. * They should all result in the same installation hash. */ const { Subprocess } = ChromeUtils.importESModule( "resource://gre/modules/Subprocess.sys.mjs" ); const XRE = Cc["@mozilla.org/xre/directory-provider;1"].getService( Ci.nsIXREDirProvider ); const HASH = XRE.getInstallHash(false); const EXE = Services.dirsvc.get("XREExeF", Ci.nsIFile); const SCRIPT = do_get_file("show_hash.js", false); async function getHash(bin) { try { // If this test is running through firefox.exe -xpcshell, we need // to make sure to execute the script through it as well. let args = []; if (!bin.leafName.startsWith("xpcshell")) { args.push("-xpcshell"); } args.push(SCRIPT.path); let proc = await Subprocess.call({ command: bin.path, arguments: args, }); let result = ""; let string; while ((string = await proc.stdout.readString())) { result += string; } return result.trim(); } catch (e) { if (e.errorCode == Subprocess.ERROR_BAD_EXECUTABLE) { return null; } throw e; } } // Walks through a path's entries and calls a mutator function to change the // case of each. function mutatePath(path, mutator) { let parts = []; let index = 0; while (path.parent != null) { parts.push(mutator(path.leafName, index++)); path = path.parent; } while (parts.length) { path.append(parts.pop()); } return path; } // Counts how many path parts a mutator will be called for. function countParts(path) { let index = 0; while (path.parent != null) { path = path.parent; index++; } return index; } add_task(async function testSameBinary() { // Running with the same binary path should definitely work and give the same // hash. Assert.equal( await getHash(EXE), HASH, "Should have the same hash when running the same binary." ); }); add_task(async function testUpperCase() { let upper = mutatePath(EXE, p => p.toLocaleUpperCase()); let hash = await getHash(upper); // We may not get a hash if any part of the filesystem is case sensitive. if (hash) { Assert.equal( hash, HASH, `Should have seen the same hash from ${upper.path}.` ); } }); add_task(async function testLowerCase() { let lower = mutatePath(EXE, p => p.toLocaleLowerCase()); let hash = await getHash(lower); // We may not get a hash if any part of the filesystem is case sensitive. if (hash) { Assert.equal( hash, HASH, `Should have seen the same hash from ${lower.path}.` ); } }); add_task(async function testEachPart() { // We need to check the case where only some of the directories in the path // are case insensitive. let count = countParts(EXE); for (let i = 0; i < count; i++) { let upper = mutatePath(EXE, (p, index) => index == i ? p.toLocaleUpperCase() : p ); let lower = mutatePath(EXE, (p, index) => index == i ? p.toLocaleLowerCase() : p ); let upperHash = await getHash(upper); if (upperHash) { Assert.equal( upperHash, HASH, `Should have seen the same hash from ${upper.path}.` ); } let lowerHash = await getHash(lower); if (lowerHash) { Assert.equal( lowerHash, HASH, `Should have seen the same hash from ${lower.path}.` ); } } });