From 2c0fe6b2e140b5ab377ba9b371de0fc9e2d9e8f0 Mon Sep 17 00:00:00 2001 From: neverland Date: Thu, 30 Jul 2026 11:41:37 +0800 Subject: [PATCH] fix(setup): reject parent hooks directories --- packages/rstack/src/setup/install.ts | 4 ++++ packages/rstack/tests/cli/setup/index.test.ts | 6 +++++- website/docs/en/guide/cli/setup.mdx | 2 ++ website/docs/zh/guide/cli/setup.mdx | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/rstack/src/setup/install.ts b/packages/rstack/src/setup/install.ts index 0873226..dabab0d 100644 --- a/packages/rstack/src/setup/install.ts +++ b/packages/rstack/src/setup/install.ts @@ -43,6 +43,10 @@ const resolveHooksDir = (hooksDir: string): string | FailedInstallResult => { ); } + if (resolvedDir.includes('..')) { + return fail('invalid-hooks-directory', 'Git hooks directory must not contain "..".'); + } + return resolvedDir; }; diff --git a/packages/rstack/tests/cli/setup/index.test.ts b/packages/rstack/tests/cli/setup/index.test.ts index 209695b..63d2e67 100644 --- a/packages/rstack/tests/cli/setup/index.test.ts +++ b/packages/rstack/tests/cli/setup/index.test.ts @@ -67,7 +67,7 @@ test('reports missing and repeated hooks directory options', ({ expect }) => { expect(repeated.stderr).toContain('The --hooks-dir option cannot be specified more than once.'); }); -test('rejects empty and absolute hooks directory options', ({ expect }) => { +test('rejects invalid hooks directory options', ({ expect }) => { const empty = runSetup(['--hooks-dir', '']); expect(empty.status).toBe(1); expect(empty.stderr).toContain('Git hooks directory must not be empty.'); @@ -77,6 +77,10 @@ test('rejects empty and absolute hooks directory options', ({ expect }) => { expect(absolute.stderr).toContain( 'Git hooks directory must be relative to the current directory.', ); + + const parent = runSetup(['--hooks-dir', '../hooks']); + expect(parent.status).toBe(1); + expect(parent.stderr).toContain('Git hooks directory must not contain "..".'); }); test('installs hooks silently without loading Rstack config', ({ execCli, expect }) => { diff --git a/website/docs/en/guide/cli/setup.mdx b/website/docs/en/guide/cli/setup.mdx index 243fa37..186a46d 100644 --- a/website/docs/en/guide/cli/setup.mdx +++ b/website/docs/en/guide/cli/setup.mdx @@ -68,6 +68,8 @@ When using a custom directory, add the full command to the `prepare` script in t } ``` +> To prevent Git hook files from being created or overwritten outside the current project through parent directory paths, the path must not contain `..`. + ### `--help` `--help` (or `-h`) displays the command's usage and options. diff --git a/website/docs/zh/guide/cli/setup.mdx b/website/docs/zh/guide/cli/setup.mdx index 6661e64..ab78d95 100644 --- a/website/docs/zh/guide/cli/setup.mdx +++ b/website/docs/zh/guide/cli/setup.mdx @@ -68,6 +68,8 @@ rs setup --hooks-dir "config/git hooks" } ``` +> 为避免通过父目录路径在当前项目之外创建或覆盖 Git hook 文件,路径中不能包含 `..`。 + ### `--help` `--help`(或 `-h`)用于显示命令的用法和选项。