mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-04 15:57:33 +01:00
fix(harness): any saved plugin root is checked for symlinks before an opt-out deletes through it
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2b0b503c60
commit
f276da838f
2 files changed
+9
-1
No files matched your search
@@ -540,7 +540,8 @@ function hookPlan(opts: RegisterOptions, dest: string, prev: Ledger | null): Hoo
|
||||
const profile = prevOn ? prev!.meta.hook_profile : hookProfile(t.name, opts.env, opts.home);
|
||||
const root = hookRoot(t.name, profile);
|
||||
const plan = { on: choice.on, prevOn, explicit: choice.source === 'flag', retry: prevOn && prev!.meta.hook_active === 'no', profile, root, files: new Map<string, Buffer>() };
|
||||
if (prevOn && !choice.on) assertHookRoot(t.name, profile, root, root, (code, msg) => { throw new HarnessError(code, msg); });
|
||||
const saved = prev?.meta.hook_root && prev.meta.hook_profile ? { profile: prev.meta.hook_profile, root: prev.meta.hook_root } : null;
|
||||
if (saved && !choice.on) assertHookRoot(t.name, saved.profile, saved.root, saved.root, (code, msg) => { throw new HarnessError(code, msg); });
|
||||
if (!choice.on) return plan;
|
||||
const why = dest !== profileSkills(t.name, profile) ? 'this registration uses another skills folder (' + dest + ')'
|
||||
: t.name === 'openclaw' && opts.env.OPENCLAW_CONFIG_PATH ? 'OPENCLAW_CONFIG_PATH points OpenClaw at a config outside that profile' : '';
|
||||
|
||||
@@ -420,6 +420,13 @@ describe('start hook: teardown keeps what gstack did not write (fake CLI)', () =
|
||||
expect(() => register(r.o({ startHook: false }))).toThrow(/EACCES/);
|
||||
expect(readLedger(on.ledger)!.meta.hook_root).toBe(r.root);
|
||||
} finally { fs.chmodSync(r.root, 0o755); }
|
||||
const ext = path.join(r.profile, 'extensions'), moved = path.join(r.d, 'moved');
|
||||
fs.renameSync(ext, moved);
|
||||
fs.symlinkSync(moved, ext);
|
||||
expect(() => register(r.o({ startHook: false }))).toThrow(expect.objectContaining({ code: 'HARNESS_UNSAFE_DESTINATION' }));
|
||||
expect(fs.existsSync(path.join(moved, HOOK_ID, 'index.js'))).toBe(true);
|
||||
fs.unlinkSync(ext);
|
||||
fs.renameSync(moved, ext);
|
||||
const off = register(r.o({ startHook: false }));
|
||||
expect(off.hook?.state).toBe('off');
|
||||
expect(fs.existsSync(path.join(r.profile, 'extensions'))).toBe(false);
|
||||
|
||||
Reference in new issue
Block a user