From 85ee71223f0dc4f5322b1c4732e262b9c1af82e8 Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Mon, 29 Jun 2026 21:02:00 -0700 Subject: [PATCH] fix(matrix): use fixed crypto bootstrap command (#97181) * fix(matrix): use fixed crypto bootstrap command * chore(matrix): drop release metadata bump --- extensions/matrix/src/matrix/deps.test.ts | 95 +++++++++++------------ extensions/matrix/src/matrix/deps.ts | 16 +--- 2 files changed, 49 insertions(+), 62 deletions(-) diff --git a/extensions/matrix/src/matrix/deps.test.ts b/extensions/matrix/src/matrix/deps.test.ts index ec2de968f798..3f504c6c9d24 100644 --- a/extensions/matrix/src/matrix/deps.test.ts +++ b/extensions/matrix/src/matrix/deps.test.ts @@ -56,55 +56,54 @@ function resolveTestNativeBindingFilename(): string | null { describe("ensureMatrixCryptoRuntime", () => { it("returns immediately when matrix SDK loads", async () => { - const runCommand = vi.fn(); const requireFn = vi.fn(() => ({})); await ensureMatrixCryptoRuntime({ log: logStub, requireFn, - runCommand, resolveFn: () => "/tmp/download-lib.js", - nodeExecutable: "/usr/bin/node", }); expect(requireFn).toHaveBeenCalledTimes(1); - expect(runCommand).not.toHaveBeenCalled(); }); it("bootstraps missing crypto runtime and retries matrix SDK load", async () => { - let bootstrapped = false; + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-crypto-bootstrap-")); + const scriptPath = path.join(tmpDir, "download-lib.js"); + const markerPath = path.join(tmpDir, "bootstrapped"); + fs.writeFileSync( + scriptPath, + [ + 'const fs = require("node:fs");', + `if (fs.realpathSync(process.cwd()) !== ${JSON.stringify(fs.realpathSync(tmpDir))}) process.exit(2);`, + 'if (process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT !== "0") process.exit(3);', + `fs.writeFileSync(${JSON.stringify(markerPath)}, "ok");`, + ].join("\n"), + ); const requireFn = vi.fn(() => { - if (!bootstrapped) { + if (!fs.existsSync(markerPath)) { throw new Error( "Cannot find module '@matrix-org/matrix-sdk-crypto-nodejs-linux-x64-gnu' (required by matrix sdk)", ); } return {}; }); - const runCommand = vi.fn(async () => { - bootstrapped = true; - return { code: 0, stdout: "", stderr: "" }; - }); - await ensureMatrixCryptoRuntime({ - log: logStub, - requireFn, - runCommand, - resolveFn: () => "/tmp/download-lib.js", - nodeExecutable: "/usr/bin/node", - }); + try { + await ensureMatrixCryptoRuntime({ + log: logStub, + requireFn, + resolveFn: () => scriptPath, + }); - expect(runCommand).toHaveBeenCalledWith({ - argv: ["/usr/bin/node", "/tmp/download-lib.js"], - cwd: "/tmp", - timeoutMs: 300_000, - env: { COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" }, - }); - expect(requireFn).toHaveBeenCalledTimes(2); + expect(fs.readFileSync(markerPath, "utf8")).toBe("ok"); + expect(requireFn).toHaveBeenCalledTimes(2); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } }); it("rethrows non-crypto module errors without bootstrapping", async () => { - const runCommand = vi.fn(); const requireFn = vi.fn(() => { throw new Error("Cannot find module 'not-the-matrix-crypto-runtime'"); }); @@ -113,13 +112,10 @@ describe("ensureMatrixCryptoRuntime", () => { ensureMatrixCryptoRuntime({ log: logStub, requireFn, - runCommand, resolveFn: () => "/tmp/download-lib.js", - nodeExecutable: "/usr/bin/node", }), ).rejects.toThrow("Cannot find module 'not-the-matrix-crypto-runtime'"); - expect(runCommand).not.toHaveBeenCalled(); expect(requireFn).toHaveBeenCalledTimes(1); }); @@ -132,38 +128,39 @@ describe("ensureMatrixCryptoRuntime", () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-crypto-runtime-")); const scriptPath = path.join(tmpDir, "download-lib.js"); const nativeBindingPath = path.join(tmpDir, nativeBindingFilename); - fs.writeFileSync(scriptPath, ""); + fs.writeFileSync( + scriptPath, + [ + 'const fs = require("node:fs");', + `fs.writeFileSync(${JSON.stringify(nativeBindingPath)}, Buffer.alloc(1_000_000));`, + ].join("\n"), + ); fs.writeFileSync(nativeBindingPath, Buffer.alloc(16)); - let bootstrapped = false; const requireFn = vi.fn(() => { - if (!bootstrapped) { + if (!fs.existsSync(nativeBindingPath) || fs.statSync(nativeBindingPath).size < 1_000_000) { throw new Error( "Cannot find module '@matrix-org/matrix-sdk-crypto-nodejs-linux-x64-gnu' (required by matrix sdk)", ); } return {}; }); - const runCommand = vi.fn(async () => { - bootstrapped = true; - fs.writeFileSync(nativeBindingPath, Buffer.alloc(1_000_000)); - return { code: 0, stdout: "", stderr: "" }; - }); - await ensureMatrixCryptoRuntime({ - log: logStub, - requireFn, - runCommand, - resolveFn: () => scriptPath, - nodeExecutable: "/usr/bin/node", - }); + try { + await ensureMatrixCryptoRuntime({ + log: logStub, + requireFn, + resolveFn: () => scriptPath, + }); - expect(runCommand).toHaveBeenCalledTimes(1); - expect(requireFn).toHaveBeenCalledTimes(2); - expect(fs.statSync(nativeBindingPath).size).toBe(1_000_000); - expect(logStub).toHaveBeenCalledWith( - "matrix: removed incomplete native crypto runtime (16 bytes); it will be downloaded again", - ); + expect(requireFn).toHaveBeenCalledTimes(2); + expect(fs.statSync(nativeBindingPath).size).toBe(1_000_000); + expect(logStub).toHaveBeenCalledWith( + "matrix: removed incomplete native crypto runtime (16 bytes); it will be downloaded again", + ); + } finally { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } }); }); diff --git a/extensions/matrix/src/matrix/deps.ts b/extensions/matrix/src/matrix/deps.ts index 4df8fe656704..0c72fa06dcf2 100644 --- a/extensions/matrix/src/matrix/deps.ts +++ b/extensions/matrix/src/matrix/deps.ts @@ -16,14 +16,7 @@ export const MATRIX_COMMAND_OUTPUT_TAIL_BYTES = 64 * 1024; type MatrixCryptoRuntimeDeps = { requireFn?: (id: string) => unknown; - runCommand?: (params: { - argv: string[]; - cwd: string; - timeoutMs: number; - env?: NodeJS.ProcessEnv; - }) => Promise; resolveFn?: (id: string) => string; - nodeExecutable?: string; log?: (message: string) => void; }; @@ -266,8 +259,7 @@ function removeIncompleteMatrixCryptoNativeBinding(params: { export async function ensureMatrixCryptoRuntime( params: MatrixCryptoRuntimeDeps = {}, ): Promise { - const usesDefaultRuntime = - !params.requireFn && !params.runCommand && !params.resolveFn && !params.nodeExecutable; + const usesDefaultRuntime = !params.requireFn && !params.resolveFn; if (usesDefaultRuntime && defaultMatrixCryptoRuntimeEnsurePromise) { await defaultMatrixCryptoRuntimeEnsurePromise; return; @@ -300,10 +292,8 @@ async function ensureMatrixCryptoRuntimeOnce(params: MatrixCryptoRuntimeDeps): P const scriptPath = resolveFn("@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js"); params.log?.("matrix: bootstrapping native crypto runtime"); - const runCommand = params.runCommand ?? runFixedCommandWithTimeout; - const nodeExecutable = params.nodeExecutable ?? process.execPath; - const result = await runCommand({ - argv: [nodeExecutable, scriptPath], + const result = await runFixedCommandWithTimeout({ + argv: [process.execPath, scriptPath], cwd: path.dirname(scriptPath), timeoutMs: 300_000, env: { COREPACK_ENABLE_DOWNLOAD_PROMPT: "0" },