mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-27 17:58:07 +00:00
fix(desktop): resolve unpacked spawn-helper before chmod (#71171)
This commit is contained in:
parent
46815f4910
commit
ac327dfa38
2 changed files with 36 additions and 2 deletions
|
|
@ -8,7 +8,8 @@ import {
|
|||
needsExecBit,
|
||||
spawnHelperCandidates,
|
||||
type SpawnHelperFs,
|
||||
withExecBits
|
||||
withExecBits,
|
||||
writableNodePtyRoot
|
||||
} from './spawn-helper-perms'
|
||||
|
||||
interface FakeFile {
|
||||
|
|
@ -56,6 +57,30 @@ function fakeFs(
|
|||
}
|
||||
}
|
||||
|
||||
test('rewrites an archived node-pty root to the matching unpacked tree exactly once', () => {
|
||||
assert.equal(
|
||||
writableNodePtyRoot('/Hermes.app/Contents/Resources/app.asar/dist/node_modules/node-pty'),
|
||||
'/Hermes.app/Contents/Resources/app.asar.unpacked/dist/node_modules/node-pty'
|
||||
)
|
||||
assert.equal(
|
||||
writableNodePtyRoot('/Hermes.app/Contents/Resources/app.asar.unpacked/dist/node_modules/node-pty'),
|
||||
'/Hermes.app/Contents/Resources/app.asar.unpacked/dist/node_modules/node-pty'
|
||||
)
|
||||
})
|
||||
|
||||
test('uses the unpacked helper when resolution reports an app.asar node-pty root', () => {
|
||||
const archivedRoot = '/Hermes.app/Contents/Resources/app.asar/dist/node_modules/node-pty'
|
||||
const unpackedRoot = writableNodePtyRoot(archivedRoot)
|
||||
const helper = join(unpackedRoot, 'prebuilds', 'darwin-arm64', 'spawn-helper')
|
||||
const fs = fakeFs({ [helper]: { mode: 0o644 } }, { [join(unpackedRoot, 'prebuilds')]: ['darwin-arm64'] })
|
||||
|
||||
const result = ensureSpawnHelperExecutable(archivedRoot, fs)
|
||||
|
||||
assert.deepEqual(result.fixed, [helper])
|
||||
assert.deepEqual(result.errors, [])
|
||||
assert.deepEqual(fs.chmods, [{ path: helper, mode: 0o755 }])
|
||||
})
|
||||
|
||||
test('needsExecBit / withExecBits treat any missing exec bit as non-executable', () => {
|
||||
assert.equal(needsExecBit(0o644), true)
|
||||
assert.equal(needsExecBit(0o755), false)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,14 @@ import { join } from 'node:path'
|
|||
|
||||
const EXEC_BITS = 0o111
|
||||
|
||||
// Electron exposes module paths inside app.asar even when electron-builder has
|
||||
// unpacked the native payload beside it. `stat` can read an archived path, but
|
||||
// chmod cannot mutate it (ENOTDIR). Native node-pty helpers belong in the
|
||||
// writable app.asar.unpacked tree; leave an already-unpacked path unchanged.
|
||||
export function writableNodePtyRoot(nodePtyRoot: string): string {
|
||||
return nodePtyRoot.replace(/app\.asar(?!\.unpacked)/, 'app.asar.unpacked')
|
||||
}
|
||||
|
||||
export interface SpawnHelperFs {
|
||||
existsSync(path: string): boolean
|
||||
readdirSync(path: string): string[]
|
||||
|
|
@ -81,8 +89,9 @@ export function ensureSpawnHelperExecutable(
|
|||
fs: SpawnHelperFs = defaultFs
|
||||
): EnsureSpawnHelperResult {
|
||||
const result: EnsureSpawnHelperResult = { fixed: [], errors: [] }
|
||||
const writableRoot = writableNodePtyRoot(nodePtyRoot)
|
||||
|
||||
for (const path of spawnHelperCandidates(nodePtyRoot, fs)) {
|
||||
for (const path of spawnHelperCandidates(writableRoot, fs)) {
|
||||
if (!fs.existsSync(path)) {
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue