mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-13 22:40:59 +02:00
Merge origin/main (v1.64.0.0) into garrytan/time-attack-fork-review
Both waves fixed several of the same bugs; resolutions keep whichever shape this branch's tests pin (#2018 jq bind, #1798 set-- pattern, stop-ack, lock errors, polyfill windowsHide) and take main's richer codex Step 2A (it absorbed the same mktemp fix). True unions: memory- ingest keeps main's capability-probed --include-gitignored inside our GIT_CEILING defense; setup wraps main's Playwright platform override in our stale-healing install lock; package.json takes main's diff@^9 and the combined test glob (design/test + ios-qa/daemon/test, 30s timeout). Generated SKILL.md files regenerated from resolved templates, never hand-picked. Ship goldens refreshed; parity/carve budgets re-measured for the summed preamble growth of both waves (itemized per entry).
This commit is contained in:
241 files changed
+7683
-4716
No files matched your search
@@ -78,6 +78,26 @@ describe('restrictDirectoryPermissions', () => {
|
||||
fs.mkdirSync(d);
|
||||
expect(() => restrictDirectoryPermissions(d)).not.toThrow();
|
||||
});
|
||||
|
||||
test('on Windows, the directory stays usable by the calling process', () => {
|
||||
if (process.platform !== 'win32') return;
|
||||
const d = path.join(tmpDir, 'still-usable');
|
||||
fs.mkdirSync(d);
|
||||
fs.writeFileSync(path.join(d, 'before'), 'x');
|
||||
|
||||
restrictDirectoryPermissions(d);
|
||||
|
||||
// Regression: an unqualified username passed to icacls can resolve to
|
||||
// the machine SID rather than the user account. Combined with
|
||||
// /inheritance:r that leaves a directory whose only ACE matches nobody,
|
||||
// so the process that just "secured" it can no longer enumerate or
|
||||
// write to it. icacls still reports success, so a not-toThrow assertion
|
||||
// sails straight past it — hence these access checks.
|
||||
expect(() => fs.readdirSync(d)).not.toThrow();
|
||||
expect(fs.readdirSync(d)).toContain('before');
|
||||
expect(() => fs.writeFileSync(path.join(d, 'after'), 'y')).not.toThrow();
|
||||
expect(fs.readFileSync(path.join(d, 'after'), 'utf8')).toBe('y');
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeSecureFile', () => {
|
||||
@@ -139,6 +159,16 @@ describe('mkdirSecure', () => {
|
||||
expect(() => mkdirSecure(d)).not.toThrow();
|
||||
});
|
||||
|
||||
test('on Windows, the created directory stays usable by the caller', () => {
|
||||
if (process.platform !== 'win32') return;
|
||||
// The state-dir path that broke: mkdirSecure() creates .gstack/, hardens
|
||||
// it, and the very next thing the daemon does is write a lockfile inside.
|
||||
const d = path.join(tmpDir, 'state', '.gstack');
|
||||
mkdirSecure(d);
|
||||
expect(() => fs.writeFileSync(path.join(d, 'browse.json.lock'), '1')).not.toThrow();
|
||||
expect(fs.readdirSync(d)).toContain('browse.json.lock');
|
||||
});
|
||||
|
||||
test('recursive behavior: creates intermediate directories', () => {
|
||||
const d = path.join(tmpDir, 'a', 'b', 'c');
|
||||
mkdirSecure(d);
|
||||
|
||||
Reference in new issue
Block a user