@cortexkit/aft-bridge 0.18.5 → 0.19.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/dist/active-logger.js +44 -0
- package/dist/active-logger.js.map +1 -0
- package/dist/bridge.js +653 -0
- package/dist/bridge.js.map +1 -0
- package/dist/downloader.js +193 -0
- package/dist/downloader.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -1387
- package/dist/index.js.map +1 -0
- package/dist/logger.js +2 -0
- package/dist/logger.js.map +1 -0
- package/dist/onnx-runtime.js +631 -0
- package/dist/onnx-runtime.js.map +1 -0
- package/dist/platform.js +31 -0
- package/dist/platform.js.map +1 -0
- package/dist/pool.js +159 -0
- package/dist/pool.js.map +1 -0
- package/dist/protocol.js +10 -0
- package/dist/protocol.js.map +1 -0
- package/dist/resolver.js +186 -0
- package/dist/resolver.js.map +1 -0
- package/dist/url-fetch.d.ts +33 -0
- package/dist/url-fetch.d.ts.map +1 -0
- package/dist/url-fetch.js +387 -0
- package/dist/url-fetch.js.map +1 -0
- package/package.json +6 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQrD,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,4BAA4B;AAC5B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,EACX,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,uBAAuB;AACvB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAcvC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACxE,mEAAmE;AACnE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-download and manage ONNX Runtime shared library for semantic search.
|
|
3
|
+
*
|
|
4
|
+
* Downloads the CPU-only ONNX Runtime from Microsoft's GitHub releases.
|
|
5
|
+
* The library is cached in the storage directory alongside semantic index data.
|
|
6
|
+
*
|
|
7
|
+
* Audit-3 v0.17 #1 hardening (v0.17.1): the previous implementation used
|
|
8
|
+
* `curl` with no size cap, no archive containment validation, no install
|
|
9
|
+
* lock, and no integrity verification — leaving an entire parallel install
|
|
10
|
+
* path that bypassed every defense the LSP GitHub installer had earned in
|
|
11
|
+
* Phase A through Phase E. This rewrite brings ONNX onto the same security
|
|
12
|
+
* floor:
|
|
13
|
+
*
|
|
14
|
+
* - Streaming size cap via fetch + ReadableStream transformer (`MAX_DOWNLOAD_BYTES`).
|
|
15
|
+
* - Streaming SHA-256 of the downloaded archive, persisted in `.aft-onnx-installed`.
|
|
16
|
+
* - Atomic O_EXCL install lock with PID-aware stale-lock recovery.
|
|
17
|
+
* - Containment-checked extraction: every file under the staging dir
|
|
18
|
+
* must be inside the staging root, no symlinks allowed before move.
|
|
19
|
+
* - Total extracted size cap (`MAX_EXTRACT_BYTES`) to defeat decompression
|
|
20
|
+
* bombs.
|
|
21
|
+
* - TOFU verification: if `.aft-onnx-installed` already records a hash for
|
|
22
|
+
* this version, refuse to use a binary that doesn't match.
|
|
23
|
+
*
|
|
24
|
+
* Supported platforms:
|
|
25
|
+
* - macOS ARM64 (osx-arm64)
|
|
26
|
+
* - Linux x64 (linux-x64)
|
|
27
|
+
* - Linux ARM64 (linux-aarch64)
|
|
28
|
+
* - Windows x64 (win-x64)
|
|
29
|
+
* - Windows ARM64 (win-arm64)
|
|
30
|
+
*
|
|
31
|
+
* macOS x64 (Intel) is not provided by Microsoft — users must install via:
|
|
32
|
+
* brew install onnxruntime
|
|
33
|
+
*/
|
|
34
|
+
import { execFileSync } from "node:child_process";
|
|
35
|
+
import { createHash } from "node:crypto";
|
|
36
|
+
import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync, lstatSync, mkdirSync, openSync, readdirSync, readFileSync, readlinkSync, realpathSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
37
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
38
|
+
import { Readable } from "node:stream";
|
|
39
|
+
import { pipeline } from "node:stream/promises";
|
|
40
|
+
import { error, log, warn } from "./active-logger.js";
|
|
41
|
+
const ORT_VERSION = "1.24.4";
|
|
42
|
+
const ORT_REPO = "microsoft/onnxruntime";
|
|
43
|
+
// Audit-3 v0.17 #1: streaming + extraction size caps.
|
|
44
|
+
//
|
|
45
|
+
// ONNX Runtime archives are around 60–80 MB on most platforms and 250 MB
|
|
46
|
+
// extracted (Windows ships extra debug binaries). 256 MB and 1 GiB give
|
|
47
|
+
// generous headroom while preventing a malicious or corrupted CDN response
|
|
48
|
+
// from filling the user's disk. Same numbers as the GitHub LSP installer.
|
|
49
|
+
const MAX_DOWNLOAD_BYTES = 256 * 1024 * 1024;
|
|
50
|
+
const MAX_EXTRACT_BYTES = 1 * 1024 * 1024 * 1024;
|
|
51
|
+
const ONNX_LOCK_FILE = ".aft-onnx-installing";
|
|
52
|
+
const ONNX_INSTALLED_META_FILE = ".aft-onnx-installed";
|
|
53
|
+
const STALE_LOCK_MS = 30 * 60 * 1000;
|
|
54
|
+
const ORT_PLATFORM_MAP = {
|
|
55
|
+
darwin: {
|
|
56
|
+
arm64: {
|
|
57
|
+
assetName: `onnxruntime-osx-arm64-${ORT_VERSION}`,
|
|
58
|
+
libName: "libonnxruntime.dylib",
|
|
59
|
+
archiveType: "tgz",
|
|
60
|
+
},
|
|
61
|
+
// x64 not available from Microsoft — users need brew install onnxruntime
|
|
62
|
+
},
|
|
63
|
+
linux: {
|
|
64
|
+
x64: {
|
|
65
|
+
assetName: `onnxruntime-linux-x64-${ORT_VERSION}`,
|
|
66
|
+
libName: "libonnxruntime.so",
|
|
67
|
+
archiveType: "tgz",
|
|
68
|
+
},
|
|
69
|
+
arm64: {
|
|
70
|
+
assetName: `onnxruntime-linux-aarch64-${ORT_VERSION}`,
|
|
71
|
+
libName: "libonnxruntime.so",
|
|
72
|
+
archiveType: "tgz",
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
win32: {
|
|
76
|
+
x64: {
|
|
77
|
+
assetName: `onnxruntime-win-x64-${ORT_VERSION}`,
|
|
78
|
+
libName: "onnxruntime.dll",
|
|
79
|
+
archiveType: "zip",
|
|
80
|
+
},
|
|
81
|
+
arm64: {
|
|
82
|
+
assetName: `onnxruntime-win-arm64-${ORT_VERSION}`,
|
|
83
|
+
libName: "onnxruntime.dll",
|
|
84
|
+
archiveType: "zip",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
/** Get platform info for the current system, or null if unsupported */
|
|
89
|
+
function getPlatformInfo() {
|
|
90
|
+
const platformMap = ORT_PLATFORM_MAP[process.platform];
|
|
91
|
+
if (!platformMap)
|
|
92
|
+
return null;
|
|
93
|
+
return platformMap[process.arch] || null;
|
|
94
|
+
}
|
|
95
|
+
/** Check if this platform can auto-download ONNX Runtime */
|
|
96
|
+
export function isOrtAutoDownloadSupported() {
|
|
97
|
+
return getPlatformInfo() !== null;
|
|
98
|
+
}
|
|
99
|
+
/** Get the install hint for platforms where auto-download isn't available */
|
|
100
|
+
export function getManualInstallHint() {
|
|
101
|
+
if (process.platform === "darwin" && process.arch === "x64") {
|
|
102
|
+
return "brew install onnxruntime";
|
|
103
|
+
}
|
|
104
|
+
if (process.platform === "linux") {
|
|
105
|
+
return "apt install libonnxruntime or download from https://github.com/microsoft/onnxruntime/releases";
|
|
106
|
+
}
|
|
107
|
+
return "Download from https://github.com/microsoft/onnxruntime/releases";
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Ensure ONNX Runtime is available. Returns the directory containing the library,
|
|
111
|
+
* or null if unavailable.
|
|
112
|
+
*
|
|
113
|
+
* Resolution order:
|
|
114
|
+
* 1. Cached in storageDir/onnxruntime/<version>/ (with TOFU verification)
|
|
115
|
+
* 2. System install (brew, apt, etc.)
|
|
116
|
+
* 3. Auto-download from GitHub releases (if platform supported)
|
|
117
|
+
* 4. null (user needs manual install)
|
|
118
|
+
*/
|
|
119
|
+
export async function ensureOnnxRuntime(storageDir) {
|
|
120
|
+
const info = getPlatformInfo();
|
|
121
|
+
// 1. Cached location with TOFU.
|
|
122
|
+
const ortDir = join(storageDir, "onnxruntime", ORT_VERSION);
|
|
123
|
+
const libPath = join(ortDir, info?.libName ?? "libonnxruntime.dylib");
|
|
124
|
+
if (existsSync(libPath)) {
|
|
125
|
+
// Audit-3 v0.17 #1 (TOFU): if we recorded a hash for this version,
|
|
126
|
+
// verify the library still matches. A mismatch means tampering or
|
|
127
|
+
// partial install corruption. Refuse to use it and let the caller
|
|
128
|
+
// either retry the download (after the user clears the cache) or
|
|
129
|
+
// fall back to system install.
|
|
130
|
+
const meta = readOnnxInstalledMeta(ortDir);
|
|
131
|
+
if (meta?.sha256) {
|
|
132
|
+
try {
|
|
133
|
+
const currentHash = sha256File(libPath);
|
|
134
|
+
if (currentHash !== meta.sha256) {
|
|
135
|
+
error(`ONNX Runtime at ${ortDir}: TOFU sha256 mismatch — refusing to use ` +
|
|
136
|
+
`tampered binary. Recorded ${meta.sha256}, current ${currentHash}. ` +
|
|
137
|
+
`Run \`aft doctor --clear\` to re-download from scratch.`);
|
|
138
|
+
// Fall through to system path / re-download attempt below.
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
log(`ONNX Runtime found at ${ortDir} (TOFU verified)`);
|
|
142
|
+
return ortDir;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
warn(`Could not verify ONNX Runtime hash at ${ortDir}: ${err}`);
|
|
147
|
+
// Treat unreadable hash as "trust on existence" since we already
|
|
148
|
+
// owned this install — better than blocking semantic search.
|
|
149
|
+
return ortDir;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
log(`ONNX Runtime found at ${ortDir} (no recorded hash, accepting)`);
|
|
154
|
+
return ortDir;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// 2. System locations.
|
|
158
|
+
const systemPath = findSystemOnnxRuntime(info?.libName);
|
|
159
|
+
if (systemPath) {
|
|
160
|
+
log(`ONNX Runtime found at system path: ${systemPath}`);
|
|
161
|
+
return systemPath;
|
|
162
|
+
}
|
|
163
|
+
// 3. Auto-download.
|
|
164
|
+
if (!info) {
|
|
165
|
+
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
// Audit-3 v0.17 #1: serialize concurrent installs.
|
|
169
|
+
//
|
|
170
|
+
// Two AFT plugin instances starting at the same time would otherwise both
|
|
171
|
+
// download and extract into overlapping temp dirs and clobber each other.
|
|
172
|
+
// The lock is held for the full install duration via the manual try/finally
|
|
173
|
+
// below (we don't reuse withInstallLock from lsp-cache because that helper
|
|
174
|
+
// is keyed on lspPackageDir, while ONNX lives in storageDir).
|
|
175
|
+
const onnxBaseDir = join(storageDir, "onnxruntime");
|
|
176
|
+
mkdirSync(onnxBaseDir, { recursive: true });
|
|
177
|
+
const lockPath = join(onnxBaseDir, ONNX_LOCK_FILE);
|
|
178
|
+
if (!acquireLock(lockPath)) {
|
|
179
|
+
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
return await downloadOnnxRuntime(info, ortDir);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
releaseLock(lockPath);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Check common system locations for ONNX Runtime */
|
|
190
|
+
function findSystemOnnxRuntime(libName) {
|
|
191
|
+
if (!libName)
|
|
192
|
+
return null;
|
|
193
|
+
const searchPaths = [];
|
|
194
|
+
if (process.platform === "darwin") {
|
|
195
|
+
// Homebrew locations
|
|
196
|
+
searchPaths.push("/opt/homebrew/lib", "/usr/local/lib");
|
|
197
|
+
}
|
|
198
|
+
else if (process.platform === "linux") {
|
|
199
|
+
searchPaths.push("/usr/lib", "/usr/lib/x86_64-linux-gnu", "/usr/lib/aarch64-linux-gnu", "/usr/local/lib");
|
|
200
|
+
}
|
|
201
|
+
for (const dir of searchPaths) {
|
|
202
|
+
if (existsSync(join(dir, libName))) {
|
|
203
|
+
return dir;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Streaming download with size cap. Mirrors the hardened path in
|
|
210
|
+
* `lsp-github-install.ts:downloadFile` so ONNX gets the same defenses
|
|
211
|
+
* the LSP installer already has.
|
|
212
|
+
*
|
|
213
|
+
* The URL is hardcoded to `https://github.com/${ORT_REPO}/...` so we don't
|
|
214
|
+
* need a hostname allowlist — the constant cannot be attacker-influenced.
|
|
215
|
+
*/
|
|
216
|
+
async function downloadFileWithCap(url, destPath) {
|
|
217
|
+
const controller = new AbortController();
|
|
218
|
+
const timeout = setTimeout(() => controller.abort(), 300_000);
|
|
219
|
+
try {
|
|
220
|
+
const res = await fetch(url, {
|
|
221
|
+
headers: { accept: "application/octet-stream" },
|
|
222
|
+
redirect: "follow",
|
|
223
|
+
signal: controller.signal,
|
|
224
|
+
});
|
|
225
|
+
if (!res.ok || !res.body) {
|
|
226
|
+
throw new Error(`download failed (HTTP ${res.status})`);
|
|
227
|
+
}
|
|
228
|
+
const advertised = Number.parseInt(res.headers.get("content-length") ?? "", 10);
|
|
229
|
+
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES) {
|
|
230
|
+
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES}`);
|
|
231
|
+
}
|
|
232
|
+
mkdirSync(dirname(destPath), { recursive: true });
|
|
233
|
+
let bytesWritten = 0;
|
|
234
|
+
const guard = new TransformStream({
|
|
235
|
+
transform(chunk, transformController) {
|
|
236
|
+
bytesWritten += chunk.byteLength;
|
|
237
|
+
if (bytesWritten > MAX_DOWNLOAD_BYTES) {
|
|
238
|
+
transformController.error(new Error(`download exceeded ${MAX_DOWNLOAD_BYTES} bytes after streaming (server lied about size or sent unbounded body)`));
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
transformController.enqueue(chunk);
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
const guarded = res.body.pipeThrough(guard);
|
|
245
|
+
// biome-ignore lint/suspicious/noExplicitAny: ReadableStream→Node stream conversion
|
|
246
|
+
const nodeStream = Readable.fromWeb(guarded);
|
|
247
|
+
await pipeline(nodeStream, createWriteStream(destPath), { signal: controller.signal });
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
try {
|
|
251
|
+
unlinkSync(destPath);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
// partial file may not exist — fine
|
|
255
|
+
}
|
|
256
|
+
throw err;
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
clearTimeout(timeout);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Validate that every file/dir under `stagingRoot` is contained inside it
|
|
264
|
+
* AND that the total extracted bytes do not exceed `MAX_EXTRACT_BYTES`.
|
|
265
|
+
*
|
|
266
|
+
* Audit-3 v0.17 #1: zip-slip + symlink containment + decompression-bomb
|
|
267
|
+
* defense. tar and unzip both can produce paths like `../../etc/passwd`;
|
|
268
|
+
* Windows tar.exe and unzip can also produce symlinks that point outside
|
|
269
|
+
* the destination. We walk the tree post-extraction and reject anything
|
|
270
|
+
* suspicious before moving files into the final cache.
|
|
271
|
+
*/
|
|
272
|
+
function validateExtractedTree(stagingRoot) {
|
|
273
|
+
const realRoot = realpathSync(stagingRoot);
|
|
274
|
+
let totalBytes = 0;
|
|
275
|
+
const walk = (dir) => {
|
|
276
|
+
const entries = readdirSync(dir);
|
|
277
|
+
for (const entry of entries) {
|
|
278
|
+
const fullPath = join(dir, entry);
|
|
279
|
+
const lst = lstatSync(fullPath);
|
|
280
|
+
if (lst.isSymbolicLink()) {
|
|
281
|
+
// Symlinks must be either rejected outright or contained. Tarballs
|
|
282
|
+
// from Microsoft's official ONNX Runtime release ship with versioned
|
|
283
|
+
// .so symlinks (libonnxruntime.so → libonnxruntime.so.1.24.4), so
|
|
284
|
+
// we cannot simply reject all of them. Instead resolve the link
|
|
285
|
+
// target (relative to the symlink's directory) and verify it stays
|
|
286
|
+
// inside the staging root.
|
|
287
|
+
const linkTarget = readlinkSync(fullPath);
|
|
288
|
+
const resolvedTarget = resolve(dirname(fullPath), linkTarget);
|
|
289
|
+
const rel = relative(realRoot, resolvedTarget);
|
|
290
|
+
if (rel.startsWith("..") || (process.platform !== "win32" && rel.startsWith("/"))) {
|
|
291
|
+
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
292
|
+
}
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const rel = relative(realRoot, fullPath);
|
|
296
|
+
if (rel.startsWith("..") || (process.platform !== "win32" && rel.startsWith("/"))) {
|
|
297
|
+
throw new Error(`extracted entry ${fullPath} escapes staging root`);
|
|
298
|
+
}
|
|
299
|
+
if (lst.isDirectory()) {
|
|
300
|
+
walk(fullPath);
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (lst.isFile()) {
|
|
304
|
+
totalBytes += lst.size;
|
|
305
|
+
if (totalBytes > MAX_EXTRACT_BYTES) {
|
|
306
|
+
throw new Error(`extracted size ${totalBytes} exceeds max ${MAX_EXTRACT_BYTES} (decompression bomb defense)`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
walk(realRoot);
|
|
312
|
+
}
|
|
313
|
+
/** Download and extract ONNX Runtime from GitHub releases */
|
|
314
|
+
async function downloadOnnxRuntime(info, targetDir) {
|
|
315
|
+
const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
|
|
316
|
+
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
317
|
+
// Use a parent-of-targetDir staging path so the validation walk can compare
|
|
318
|
+
// resolved paths via realpathSync without rejecting symlinks that happen to
|
|
319
|
+
// resolve into the parent (e.g. when storageDir is itself behind a symlink).
|
|
320
|
+
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
321
|
+
try {
|
|
322
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
323
|
+
const archivePath = join(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
324
|
+
// Audit-3 v0.17 #1: download with streaming size cap (no more curl).
|
|
325
|
+
await downloadFileWithCap(url, archivePath);
|
|
326
|
+
// Audit-3 v0.17 #1: hash the archive for TOFU.
|
|
327
|
+
const archiveSha256 = sha256File(archivePath);
|
|
328
|
+
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
329
|
+
// Extract.
|
|
330
|
+
if (info.archiveType === "tgz") {
|
|
331
|
+
execFileSync("tar", ["xzf", archivePath, "-C", tmpDir], {
|
|
332
|
+
stdio: "pipe",
|
|
333
|
+
timeout: 120_000,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
await extractZipArchive(archivePath, tmpDir);
|
|
338
|
+
}
|
|
339
|
+
// Drop the archive itself before validation so it doesn't double-count
|
|
340
|
+
// toward the extracted-size budget.
|
|
341
|
+
try {
|
|
342
|
+
unlinkSync(archivePath);
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
// ignore
|
|
346
|
+
}
|
|
347
|
+
// Audit-3 v0.17 #1: containment + size-bomb check.
|
|
348
|
+
validateExtractedTree(tmpDir);
|
|
349
|
+
// Find and copy the library file.
|
|
350
|
+
const extractedDir = join(tmpDir, info.assetName, "lib");
|
|
351
|
+
if (!existsSync(extractedDir)) {
|
|
352
|
+
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
353
|
+
}
|
|
354
|
+
// Create target directory and copy library files.
|
|
355
|
+
mkdirSync(targetDir, { recursive: true });
|
|
356
|
+
// Copy all library files (main + versioned symlinks).
|
|
357
|
+
// On Linux, .so files are often symlinks (libonnxruntime.so → libonnxruntime.so.1.24.4).
|
|
358
|
+
// Process real files first, then recreate symlinks in the target directory to avoid
|
|
359
|
+
// ENOENT when renaming a symlink whose target was already moved.
|
|
360
|
+
const libFiles = readdirSync(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
|
|
361
|
+
// Separate real files from symlinks
|
|
362
|
+
const realFiles = [];
|
|
363
|
+
const symlinks = [];
|
|
364
|
+
for (const libFile of libFiles) {
|
|
365
|
+
const src = join(extractedDir, libFile);
|
|
366
|
+
try {
|
|
367
|
+
const stat = lstatSync(src);
|
|
368
|
+
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
369
|
+
if (stat.isSymbolicLink()) {
|
|
370
|
+
symlinks.push({ name: libFile, target: readlinkSync(src) });
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
realFiles.push(libFile);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
catch (e) {
|
|
377
|
+
log(`ORT extract: ${libFile} — stat failed: ${e}`);
|
|
378
|
+
realFiles.push(libFile);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
// Copy real files first
|
|
382
|
+
for (const libFile of realFiles) {
|
|
383
|
+
const src = join(extractedDir, libFile);
|
|
384
|
+
const dst = join(targetDir, libFile);
|
|
385
|
+
try {
|
|
386
|
+
copyFileSync(src, dst);
|
|
387
|
+
if (process.platform !== "win32") {
|
|
388
|
+
chmodSync(dst, 0o755);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
catch (copyErr) {
|
|
392
|
+
log(`ORT extract: failed to copy ${libFile}: ${copyErr}`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// Recreate symlinks in target directory
|
|
396
|
+
for (const link of symlinks) {
|
|
397
|
+
const dst = join(targetDir, link.name);
|
|
398
|
+
try {
|
|
399
|
+
unlinkSync(dst); // remove if exists from a previous partial install
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
// ignore
|
|
403
|
+
}
|
|
404
|
+
symlinkSync(link.target, dst);
|
|
405
|
+
}
|
|
406
|
+
// Audit-3 v0.17 #1: persist version + archive sha256 for TOFU on
|
|
407
|
+
// future sessions. Hash the actual main library file (not the
|
|
408
|
+
// archive) because that's what we'll re-hash on the next ensure call.
|
|
409
|
+
const libPath = join(targetDir, info.libName);
|
|
410
|
+
let libHash = null;
|
|
411
|
+
try {
|
|
412
|
+
libHash = sha256File(libPath);
|
|
413
|
+
}
|
|
414
|
+
catch (err) {
|
|
415
|
+
// If we can't even hash our just-installed library, skip TOFU rather
|
|
416
|
+
// than blocking semantic search. Future sessions will trust the path.
|
|
417
|
+
warn(`Could not hash newly-installed ONNX library at ${libPath}: ${err}`);
|
|
418
|
+
}
|
|
419
|
+
writeOnnxInstalledMeta(targetDir, ORT_VERSION, libHash, archiveSha256);
|
|
420
|
+
// Cleanup temp directory
|
|
421
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
422
|
+
log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
|
|
423
|
+
return targetDir;
|
|
424
|
+
}
|
|
425
|
+
catch (err) {
|
|
426
|
+
error(`Failed to download ONNX Runtime: ${err}`);
|
|
427
|
+
// Cleanup on failure — both the staging dir and any partially populated
|
|
428
|
+
// target dir, so the next attempt starts from a clean slate.
|
|
429
|
+
try {
|
|
430
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// ignore cleanup errors
|
|
434
|
+
}
|
|
435
|
+
try {
|
|
436
|
+
rmSync(targetDir, { recursive: true, force: true });
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
// ignore
|
|
440
|
+
}
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
async function extractZipArchive(archivePath, destinationDir) {
|
|
445
|
+
if (process.platform === "win32") {
|
|
446
|
+
// Audit-2 v0.17 #12: drop PowerShell. Even via execFileSync, PowerShell
|
|
447
|
+
// applies its own quoting rules to `$args[N]` lookups that could allow
|
|
448
|
+
// attacker-controlled fragments to escape into command interpretation.
|
|
449
|
+
// tar.exe ships in System32 on Windows 10 build 17063+ — execFileSync
|
|
450
|
+
// with argv has no shell parser in the chain.
|
|
451
|
+
execFileSync("tar.exe", ["-xf", archivePath, "-C", destinationDir], {
|
|
452
|
+
stdio: "pipe",
|
|
453
|
+
timeout: 120_000,
|
|
454
|
+
});
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
execFileSync("unzip", ["-q", archivePath, "-d", destinationDir], {
|
|
458
|
+
stdio: "pipe",
|
|
459
|
+
timeout: 120_000,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
463
|
+
try {
|
|
464
|
+
const meta = {
|
|
465
|
+
version,
|
|
466
|
+
installedAt: new Date().toISOString(),
|
|
467
|
+
...(sha256 ? { sha256 } : {}),
|
|
468
|
+
archiveSha256,
|
|
469
|
+
};
|
|
470
|
+
writeFileSync(join(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
471
|
+
}
|
|
472
|
+
catch (err) {
|
|
473
|
+
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function readOnnxInstalledMeta(installDir) {
|
|
477
|
+
const path = join(installDir, ONNX_INSTALLED_META_FILE);
|
|
478
|
+
try {
|
|
479
|
+
if (!statSync(path).isFile())
|
|
480
|
+
return null;
|
|
481
|
+
const raw = readFileSync(path, "utf8");
|
|
482
|
+
const parsed = JSON.parse(raw);
|
|
483
|
+
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
484
|
+
return null;
|
|
485
|
+
return {
|
|
486
|
+
version: parsed.version,
|
|
487
|
+
installedAt: typeof parsed.installedAt === "string" ? parsed.installedAt : "",
|
|
488
|
+
...(typeof parsed.sha256 === "string" && parsed.sha256.length > 0
|
|
489
|
+
? { sha256: parsed.sha256 }
|
|
490
|
+
: {}),
|
|
491
|
+
...(typeof parsed.archiveSha256 === "string" && parsed.archiveSha256.length > 0
|
|
492
|
+
? { archiveSha256: parsed.archiveSha256 }
|
|
493
|
+
: {}),
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Synchronous SHA-256 of a file. ONNX libs are ~50 MB so a single
|
|
502
|
+
* `readFileSync` is fine — we accept the brief blocking read in exchange
|
|
503
|
+
* for keeping the call sites simple (no awaits inside the path-resolution
|
|
504
|
+
* fast path that runs every plugin start).
|
|
505
|
+
*/
|
|
506
|
+
function sha256File(path) {
|
|
507
|
+
const hash = createHash("sha256");
|
|
508
|
+
hash.update(readFileSync(path));
|
|
509
|
+
return hash.digest("hex");
|
|
510
|
+
}
|
|
511
|
+
/* ─────────────────────────── install lock ─────────────────────────── */
|
|
512
|
+
/**
|
|
513
|
+
* Acquire a process-exclusive lock. Atomic O_EXCL create with PID-aware
|
|
514
|
+
* stale-lock recovery. Mirrors `acquireInstallLock` in lsp-cache.ts but
|
|
515
|
+
* lives here because the ONNX install dir is keyed on `storageDir`,
|
|
516
|
+
* not `lspPackageDir`.
|
|
517
|
+
*/
|
|
518
|
+
function acquireLock(lockPath) {
|
|
519
|
+
const tryClaim = () => {
|
|
520
|
+
try {
|
|
521
|
+
const fd = openSync(lockPath, "wx");
|
|
522
|
+
try {
|
|
523
|
+
writeFileSync(fd, `${process.pid}\n${new Date().toISOString()}\n`);
|
|
524
|
+
}
|
|
525
|
+
finally {
|
|
526
|
+
closeSync(fd);
|
|
527
|
+
}
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
catch (err) {
|
|
531
|
+
const code = err.code;
|
|
532
|
+
if (code === "EEXIST")
|
|
533
|
+
return false;
|
|
534
|
+
warn(`[onnx] unexpected error acquiring lock ${lockPath}: ${err}`);
|
|
535
|
+
return false;
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
if (tryClaim())
|
|
539
|
+
return true;
|
|
540
|
+
let owningPid = null;
|
|
541
|
+
let lockMtimeMs = 0;
|
|
542
|
+
try {
|
|
543
|
+
const raw = readFileSync(lockPath, "utf8");
|
|
544
|
+
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
545
|
+
const parsed = Number.parseInt(firstLine, 10);
|
|
546
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
547
|
+
owningPid = parsed;
|
|
548
|
+
lockMtimeMs = statSync(lockPath).mtimeMs;
|
|
549
|
+
}
|
|
550
|
+
catch {
|
|
551
|
+
return tryClaim();
|
|
552
|
+
}
|
|
553
|
+
const age = Date.now() - lockMtimeMs;
|
|
554
|
+
const ageWithinFresh = Math.abs(age) < STALE_LOCK_MS;
|
|
555
|
+
const skipLiveness = process.platform === "win32";
|
|
556
|
+
const ownerAlive = !skipLiveness && owningPid !== null && isProcessAlive(owningPid);
|
|
557
|
+
if (skipLiveness ? ageWithinFresh : ownerAlive && ageWithinFresh) {
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
log(`[onnx] reclaiming install lock (owner_pid=${owningPid ?? "unknown"}, alive=${ownerAlive}, age_ms=${age})`);
|
|
561
|
+
try {
|
|
562
|
+
unlinkSync(lockPath);
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
// ignore
|
|
566
|
+
}
|
|
567
|
+
return tryClaim();
|
|
568
|
+
}
|
|
569
|
+
function releaseLock(lockPath) {
|
|
570
|
+
// Same TOCTOU-safe release as releaseInstallLock — only unlink if our PID owns it.
|
|
571
|
+
try {
|
|
572
|
+
let owningPid = null;
|
|
573
|
+
try {
|
|
574
|
+
const raw = readFileSync(lockPath, "utf8");
|
|
575
|
+
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
576
|
+
const parsed = Number.parseInt(firstLine, 10);
|
|
577
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
578
|
+
owningPid = parsed;
|
|
579
|
+
}
|
|
580
|
+
catch (readErr) {
|
|
581
|
+
const code = readErr.code;
|
|
582
|
+
if (code === "ENOENT")
|
|
583
|
+
return;
|
|
584
|
+
warn(`[onnx] could not read lock ${lockPath} during release: ${readErr}`);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (owningPid !== process.pid) {
|
|
588
|
+
log(`[onnx] not releasing lock ${lockPath}: owned by pid ${owningPid ?? "unknown"} (we are ${process.pid})`);
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
try {
|
|
592
|
+
unlinkSync(lockPath);
|
|
593
|
+
}
|
|
594
|
+
catch (unlinkErr) {
|
|
595
|
+
const code = unlinkErr.code;
|
|
596
|
+
if (code !== "ENOENT") {
|
|
597
|
+
warn(`[onnx] failed to release lock ${lockPath}: ${unlinkErr}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
catch (err) {
|
|
602
|
+
warn(`[onnx] unexpected error releasing lock ${lockPath}: ${err}`);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
function isProcessAlive(pid) {
|
|
606
|
+
try {
|
|
607
|
+
process.kill(pid, 0);
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
catch (err) {
|
|
611
|
+
const code = err.code;
|
|
612
|
+
if (code === "ESRCH")
|
|
613
|
+
return false;
|
|
614
|
+
return true;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Remove ONNX Runtime from temp files. Cleanup helper for test isolation.
|
|
619
|
+
*/
|
|
620
|
+
export function cleanupOnnxRuntime(storageDir) {
|
|
621
|
+
try {
|
|
622
|
+
const ortBase = join(storageDir, "onnxruntime");
|
|
623
|
+
if (existsSync(ortBase)) {
|
|
624
|
+
rmSync(ortBase, { recursive: true, force: true });
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
catch {
|
|
628
|
+
// ignore
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
//# sourceMappingURL=onnx-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onnx-runtime.js","sourceRoot":"","sources":["../src/onnx-runtime.ts"],"names":[],"mappings":"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"}
|