fallow-similar-code 3.21.0 → 3.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -9
- package/scripts/run-binary.js +3 -4
- package/scripts/run-binary.test.js +72 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fallow-similar-code",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.23.0",
|
|
4
4
|
"description": "First-party local embedding sidecar for Fallow similar-code analysis",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"detect-libc": "2.1.2"
|
|
27
27
|
},
|
|
28
28
|
"optionalDependencies": {
|
|
29
|
-
"@fallow-cli/fallow-similar-code-darwin-arm64": "3.
|
|
30
|
-
"@fallow-cli/fallow-similar-code-darwin-x64": "3.
|
|
31
|
-
"@fallow-cli/fallow-similar-code-linux-x64-gnu": "3.
|
|
32
|
-
"@fallow-cli/fallow-similar-code-linux-arm64-gnu": "3.
|
|
33
|
-
"@fallow-cli/fallow-similar-code-linux-x64-musl": "3.
|
|
34
|
-
"@fallow-cli/fallow-similar-code-linux-arm64-musl": "3.
|
|
35
|
-
"@fallow-cli/fallow-similar-code-win32-x64-msvc": "3.
|
|
36
|
-
"@fallow-cli/fallow-similar-code-win32-arm64-msvc": "3.
|
|
29
|
+
"@fallow-cli/fallow-similar-code-darwin-arm64": "3.23.0",
|
|
30
|
+
"@fallow-cli/fallow-similar-code-darwin-x64": "3.23.0",
|
|
31
|
+
"@fallow-cli/fallow-similar-code-linux-x64-gnu": "3.23.0",
|
|
32
|
+
"@fallow-cli/fallow-similar-code-linux-arm64-gnu": "3.23.0",
|
|
33
|
+
"@fallow-cli/fallow-similar-code-linux-x64-musl": "3.23.0",
|
|
34
|
+
"@fallow-cli/fallow-similar-code-linux-arm64-musl": "3.23.0",
|
|
35
|
+
"@fallow-cli/fallow-similar-code-win32-x64-msvc": "3.23.0",
|
|
36
|
+
"@fallow-cli/fallow-similar-code-win32-arm64-msvc": "3.23.0"
|
|
37
37
|
}
|
|
38
38
|
}
|
package/scripts/run-binary.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require("node:fs");
|
|
4
4
|
const path = require("node:path");
|
|
5
|
+
const os = require("node:os");
|
|
5
6
|
const { spawn, spawnSync } = require("node:child_process");
|
|
6
7
|
const { once } = require("node:events");
|
|
7
8
|
const { getPlatformPackage, isPlatformPackage } = require("./platform-package");
|
|
@@ -72,8 +73,6 @@ const resolveBinaryArtifact = (
|
|
|
72
73
|
});
|
|
73
74
|
};
|
|
74
75
|
|
|
75
|
-
const resolveBinary = (...args) => resolveBinaryArtifact(...args).binaryPath;
|
|
76
|
-
|
|
77
76
|
const setupTimeoutFor = (args) => (args[0] === "setup" ? SETUP_PROCESS_TIMEOUT_MS : null);
|
|
78
77
|
|
|
79
78
|
const spawnNative = (binaryPath, args, spawnProcess = spawnSync) => {
|
|
@@ -177,7 +176,8 @@ const run = async (args) => {
|
|
|
177
176
|
}
|
|
178
177
|
if (result.signal) {
|
|
179
178
|
process.stderr.write(`fallow-similar-code terminated by signal ${result.signal}\n`);
|
|
180
|
-
|
|
179
|
+
const signalNumber = os.constants.signals[result.signal];
|
|
180
|
+
process.exit(result.status ?? (signalNumber ? 128 + signalNumber : 1));
|
|
181
181
|
}
|
|
182
182
|
process.exit(result.status ?? 1);
|
|
183
183
|
} catch (error) {
|
|
@@ -191,7 +191,6 @@ module.exports = {
|
|
|
191
191
|
SETUP_PROCESS_TIMEOUT_MS,
|
|
192
192
|
SETUP_TIMEOUT_EXIT_CODE,
|
|
193
193
|
SETUP_TIMEOUT_MESSAGE,
|
|
194
|
-
resolveBinary,
|
|
195
194
|
resolveBinaryArtifact,
|
|
196
195
|
resolvePlatformPackage,
|
|
197
196
|
run,
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
const assert = require("node:assert/strict");
|
|
4
4
|
const test = require("node:test");
|
|
5
5
|
const path = require("node:path");
|
|
6
|
+
const crypto = require("node:crypto");
|
|
7
|
+
const fs = require("node:fs");
|
|
8
|
+
const os = require("node:os");
|
|
9
|
+
const { spawn } = require("node:child_process");
|
|
10
|
+
const { once } = require("node:events");
|
|
11
|
+
const { resolvePlatformPackage } = require("./run-binary");
|
|
6
12
|
const ownManifest = require("../package.json");
|
|
7
13
|
const {
|
|
8
14
|
SETUP_PROCESS_TIMEOUT_MS,
|
|
9
15
|
SETUP_TIMEOUT_EXIT_CODE,
|
|
10
16
|
SETUP_TIMEOUT_MESSAGE,
|
|
11
|
-
resolveBinary,
|
|
12
17
|
resolveBinaryArtifact,
|
|
13
18
|
setupTimeoutFor,
|
|
14
19
|
spawnNative,
|
|
@@ -21,19 +26,19 @@ const manifest = (overrides = {}) =>
|
|
|
21
26
|
|
|
22
27
|
test("resolves an exact-version regular native binary", () => {
|
|
23
28
|
const manifestPath = path.join("/packages", "native", "package.json");
|
|
24
|
-
const resolved =
|
|
29
|
+
const resolved = resolveBinaryArtifact(
|
|
25
30
|
PACKAGE_NAME,
|
|
26
31
|
() => manifestPath,
|
|
27
32
|
() => manifest(),
|
|
28
33
|
() => ({ isFile: () => true, isSymbolicLink: () => false }),
|
|
29
34
|
);
|
|
30
|
-
assert.equal(resolved, path.join("/packages", "native", "fallow-similar-code"));
|
|
35
|
+
assert.equal(resolved.binaryPath, path.join("/packages", "native", "fallow-similar-code"));
|
|
31
36
|
});
|
|
32
37
|
|
|
33
38
|
test("rejects a platform package from another release", () => {
|
|
34
39
|
assert.throws(
|
|
35
40
|
() =>
|
|
36
|
-
|
|
41
|
+
resolveBinaryArtifact(
|
|
37
42
|
PACKAGE_NAME,
|
|
38
43
|
() => "/native/package.json",
|
|
39
44
|
() => manifest({ version: "0.0.0" }),
|
|
@@ -46,7 +51,7 @@ test("rejects a platform package from another release", () => {
|
|
|
46
51
|
test("rejects symlinked binaries", () => {
|
|
47
52
|
assert.throws(
|
|
48
53
|
() =>
|
|
49
|
-
|
|
54
|
+
resolveBinaryArtifact(
|
|
50
55
|
PACKAGE_NAME,
|
|
51
56
|
() => "/native/package.json",
|
|
52
57
|
() => manifest(),
|
|
@@ -163,3 +168,65 @@ test("spawns non-setup commands without a wrapper timeout", () => {
|
|
|
163
168
|
assert.deepEqual(captured.args, ["status", "--json"]);
|
|
164
169
|
assert.deepEqual(captured.options, { env: process.env, stdio: "inherit" });
|
|
165
170
|
});
|
|
171
|
+
|
|
172
|
+
test(
|
|
173
|
+
"the signed setup launcher preserves forwarded SIGTERM as exit 143",
|
|
174
|
+
{ skip: process.platform === "win32", timeout: 10_000 },
|
|
175
|
+
async (t) => {
|
|
176
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "fallow-setup-signal-"));
|
|
177
|
+
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
178
|
+
const packageName = resolvePlatformPackage();
|
|
179
|
+
const packageDir = path.join(root, "node_modules", packageName);
|
|
180
|
+
fs.mkdirSync(packageDir, { recursive: true });
|
|
181
|
+
const binaryName = "fallow-similar-code";
|
|
182
|
+
const binaryPath = path.join(packageDir, binaryName);
|
|
183
|
+
const binary = Buffer.from(
|
|
184
|
+
"#!/usr/bin/env node\nprocess.on('SIGTERM', () => process.exit(0)); process.stdout.write('READY\\n'); setInterval(() => {}, 1000);\n",
|
|
185
|
+
);
|
|
186
|
+
const { privateKey, publicKey } = crypto.generateKeyPairSync("ed25519");
|
|
187
|
+
fs.writeFileSync(binaryPath, binary, { mode: 0o755 });
|
|
188
|
+
fs.writeFileSync(`${binaryPath}.sig`, crypto.sign(null, binary, privateKey));
|
|
189
|
+
fs.writeFileSync(
|
|
190
|
+
path.join(packageDir, "package.json"),
|
|
191
|
+
JSON.stringify({
|
|
192
|
+
name: packageName,
|
|
193
|
+
version: ownManifest.version,
|
|
194
|
+
fallowDigests: {
|
|
195
|
+
[binaryName]: `sha256:${crypto.createHash("sha256").update(binary).digest("hex")}`,
|
|
196
|
+
},
|
|
197
|
+
}),
|
|
198
|
+
);
|
|
199
|
+
// The real verifier checks a signed fixture using an ephemeral trust key.
|
|
200
|
+
// Package resolution, digest verification, spawning and signal forwarding all run.
|
|
201
|
+
const driver = `
|
|
202
|
+
const crypto = require("node:crypto");
|
|
203
|
+
const verifier = require(${JSON.stringify(require.resolve("./verify-binary"))});
|
|
204
|
+
const verify = verifier.verifyBinary;
|
|
205
|
+
const publicKey = crypto.createPublicKey(${JSON.stringify(publicKey.export({ type: "spki", format: "pem" }))});
|
|
206
|
+
verifier.verifyBinary = artifact => verify(artifact, { createPublicKey: () => publicKey });
|
|
207
|
+
require(${JSON.stringify(require.resolve("./run-binary"))}).run(["setup"]);
|
|
208
|
+
`;
|
|
209
|
+
const child = spawn(process.execPath, ["-e", driver], {
|
|
210
|
+
env: { ...process.env, NODE_PATH: path.join(root, "node_modules") },
|
|
211
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
212
|
+
});
|
|
213
|
+
t.after(() => child.kill("SIGKILL"));
|
|
214
|
+
let ready = false;
|
|
215
|
+
let stdout = "";
|
|
216
|
+
let stderr = "";
|
|
217
|
+
child.stdout.on("data", (chunk) => {
|
|
218
|
+
stdout += chunk.toString();
|
|
219
|
+
if (!ready && stdout.includes("READY")) {
|
|
220
|
+
ready = true;
|
|
221
|
+
child.kill("SIGTERM");
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
child.stderr.on("data", (chunk) => {
|
|
225
|
+
stderr += chunk.toString();
|
|
226
|
+
});
|
|
227
|
+
const [status, signal] = await once(child, "close");
|
|
228
|
+
assert.equal(ready, true, stderr);
|
|
229
|
+
assert.equal(signal, null);
|
|
230
|
+
assert.equal(status, 143, stderr);
|
|
231
|
+
},
|
|
232
|
+
);
|