freebuff 0.0.135 → 0.0.136
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/launcher.js +61 -56
- package/package.json +1 -1
package/launcher.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { spawn
|
|
3
|
+
const { spawn } = require('child_process')
|
|
4
4
|
const fs = require('fs')
|
|
5
5
|
const http = require('http')
|
|
6
6
|
const https = require('https')
|
|
@@ -21,6 +21,9 @@ function createLauncher(productConfig) {
|
|
|
21
21
|
telemetryEvent = 'cli.update_codebuff_failed',
|
|
22
22
|
telemetryProperties = {},
|
|
23
23
|
tempDownloadDirName = `.${packageName}-download-temp`,
|
|
24
|
+
// Tests only. os.homedir() ignores $HOME under `bun test`, so pointing HOME
|
|
25
|
+
// at a temp dir is not enough to keep a test off the real ~/.config.
|
|
26
|
+
configDir: configDirOverride = null,
|
|
24
27
|
} = productConfig
|
|
25
28
|
|
|
26
29
|
/**
|
|
@@ -96,7 +99,8 @@ function createLauncher(productConfig) {
|
|
|
96
99
|
|
|
97
100
|
function createConfig(packageName) {
|
|
98
101
|
const homeDir = os.homedir()
|
|
99
|
-
const configDir =
|
|
102
|
+
const configDir =
|
|
103
|
+
configDirOverride || path.join(homeDir, '.config', 'manicode')
|
|
100
104
|
const binaryName =
|
|
101
105
|
process.platform === 'win32' ? `${packageName}.exe` : packageName
|
|
102
106
|
|
|
@@ -245,35 +249,6 @@ function createLauncher(productConfig) {
|
|
|
245
249
|
}
|
|
246
250
|
}
|
|
247
251
|
|
|
248
|
-
// Returns true (AVX2 present), false (absent), or null (couldn't determine).
|
|
249
|
-
// Ask the OS directly via IsProcessorFeaturePresent (kernel32), which is
|
|
250
|
-
// backed by CPUID — far more reliable than matching CPU model names, and it
|
|
251
|
-
// works on the stock Windows PowerShell that ships with every supported
|
|
252
|
-
// Windows version. Feature 40 = PF_AVX2_INSTRUCTIONS_AVAILABLE.
|
|
253
|
-
function probeWindowsAvx2() {
|
|
254
|
-
const script =
|
|
255
|
-
'$f = Add-Type -MemberDefinition \'[DllImport("kernel32.dll")] ' +
|
|
256
|
-
"public static extern bool IsProcessorFeaturePresent(uint feature);' " +
|
|
257
|
-
'-Name Cpu -Namespace Win32 -PassThru; $f::IsProcessorFeaturePresent(40)'
|
|
258
|
-
try {
|
|
259
|
-
const out = execFileSync(
|
|
260
|
-
'powershell.exe',
|
|
261
|
-
['-NoProfile', '-NonInteractive', '-Command', script],
|
|
262
|
-
{
|
|
263
|
-
encoding: 'utf8',
|
|
264
|
-
timeout: 5000,
|
|
265
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
266
|
-
},
|
|
267
|
-
).trim()
|
|
268
|
-
if (out === 'True') return true
|
|
269
|
-
if (out === 'False') return false
|
|
270
|
-
return null
|
|
271
|
-
} catch {
|
|
272
|
-
// No PowerShell, locked-down policy, timeout, etc. — inconclusive.
|
|
273
|
-
return null
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
252
|
let _hasAvx2Cache
|
|
278
253
|
|
|
279
254
|
function machineHasAvx2() {
|
|
@@ -288,31 +263,41 @@ function createLauncher(productConfig) {
|
|
|
288
263
|
return true
|
|
289
264
|
}
|
|
290
265
|
|
|
291
|
-
//
|
|
266
|
+
// A recorded illegal-instruction crash outranks everything below it: the
|
|
267
|
+
// binary actually failed on this machine, which beats any inference we
|
|
268
|
+
// could make about the CPU.
|
|
269
|
+
const recorded = readCachedAvx2()
|
|
270
|
+
if (recorded !== null) {
|
|
271
|
+
return recorded
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Linux can just ask, and a file read is cheap enough not to cache.
|
|
292
275
|
if (process.platform === 'linux') {
|
|
293
276
|
return linuxCpuHasAvx2()
|
|
294
277
|
}
|
|
295
278
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
279
|
+
// Everything else assumes AVX2 — true of every x64 CPU since ~2013.
|
|
280
|
+
//
|
|
281
|
+
// Windows is the case that matters, since it's the only other platform with
|
|
282
|
+
// a baseline build. It has no /proc/cpuinfo equivalent we can read without
|
|
283
|
+
// spawning something, and the probe that used to fill the gap asked
|
|
284
|
+
// PowerShell to compile a C# stub and P/Invoke
|
|
285
|
+
// kernel32!IsProcessorFeaturePresent — accurate, but a textbook malware
|
|
286
|
+
// shape that Windows Defender flagged as a "Suspicious PowerShell command
|
|
287
|
+
// line" on real user machines. The illegal-instruction handler corrects us
|
|
288
|
+
// instead: tryFallbackToBaseline() calls recordMachineLacksAvx2(), so a
|
|
289
|
+
// machine without AVX2 pays exactly one failed launch and is answered by
|
|
290
|
+
// the cache read above from then on.
|
|
291
|
+
return true
|
|
292
|
+
}
|
|
299
293
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const detected = probeWindowsAvx2()
|
|
308
|
-
if (detected === null) {
|
|
309
|
-
// Inconclusive probe: assume AVX2 for this launch and rely on the SIGILL
|
|
310
|
-
// fallback, but don't persist it — a transient failure must not lock in a
|
|
311
|
-
// wrong answer for the lifetime of the install. We'll re-probe next launch.
|
|
312
|
-
return true
|
|
313
|
-
}
|
|
314
|
-
writeCachedAvx2(detected)
|
|
315
|
-
return detected
|
|
294
|
+
// Called from the illegal-instruction fallback. Persisting here is what keeps
|
|
295
|
+
// the optimistic assumption above from costing more than a single crash — and
|
|
296
|
+
// it is deliberately separate from the metadata target, so a lost or rewritten
|
|
297
|
+
// metadata file can't resurrect the AVX2 build on a CPU that can't run it.
|
|
298
|
+
function recordMachineLacksAvx2() {
|
|
299
|
+
_hasAvx2Cache = false
|
|
300
|
+
writeCachedAvx2(false)
|
|
316
301
|
}
|
|
317
302
|
|
|
318
303
|
function getCpuFeatureCachePath() {
|
|
@@ -349,11 +334,12 @@ function createLauncher(productConfig) {
|
|
|
349
334
|
}
|
|
350
335
|
|
|
351
336
|
const platformKey = getPlatformKey()
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
//
|
|
355
|
-
//
|
|
356
|
-
//
|
|
337
|
+
// Linux still detects up front (reading /proc/cpuinfo is free). Windows
|
|
338
|
+
// cannot without spawning a process, and the PowerShell probe that used to
|
|
339
|
+
// do it tripped Defender, so Windows is optimistic-then-corrected: see
|
|
340
|
+
// detectMachineHasAvx2() and tryFallbackToBaseline(). Once a machine has
|
|
341
|
+
// failed once, readCachedAvx2() answers here and baseline is chosen up front
|
|
342
|
+
// exactly as it used to be.
|
|
357
343
|
//
|
|
358
344
|
// This assumes every baseline target is gated on AVX2 specifically, which
|
|
359
345
|
// holds today (only linux-x64 and win32-x64 have baseline builds, both
|
|
@@ -1145,6 +1131,11 @@ function createLauncher(productConfig) {
|
|
|
1145
1131
|
return false
|
|
1146
1132
|
}
|
|
1147
1133
|
|
|
1134
|
+
// The optimized build just died on an illegal instruction, so this machine
|
|
1135
|
+
// cannot run it. Persist that before downloading, so even if the download
|
|
1136
|
+
// or the relaunch fails we never optimistically pick the AVX2 build again.
|
|
1137
|
+
recordMachineLacksAvx2()
|
|
1138
|
+
|
|
1148
1139
|
const version = metadata?.version || (await getLatestVersion())
|
|
1149
1140
|
if (!version) {
|
|
1150
1141
|
return false
|
|
@@ -1211,6 +1202,20 @@ function createLauncher(productConfig) {
|
|
|
1211
1202
|
config: productConfig,
|
|
1212
1203
|
main,
|
|
1213
1204
|
stopRunningProcess,
|
|
1205
|
+
// Internals exposed for tests only. The AVX2 path is optimistic-then-
|
|
1206
|
+
// corrected (see detectMachineHasAvx2), so the correction has to be
|
|
1207
|
+
// exercised directly — there is no way to make a CI runner lack AVX2.
|
|
1208
|
+
__testing: {
|
|
1209
|
+
detectMachineHasAvx2,
|
|
1210
|
+
recordMachineLacksAvx2,
|
|
1211
|
+
readCachedAvx2,
|
|
1212
|
+
isIllegalInstructionExit,
|
|
1213
|
+
getDefaultTargetKey,
|
|
1214
|
+
getCpuFeatureCachePath,
|
|
1215
|
+
getCurrentVersion,
|
|
1216
|
+
isTargetAllowedForThisMachine,
|
|
1217
|
+
CONFIG,
|
|
1218
|
+
},
|
|
1214
1219
|
}
|
|
1215
1220
|
}
|
|
1216
1221
|
|