From a06bf8fe0dbd6cedb245e0a75590242c9d8776c5 Mon Sep 17 00:00:00 2001 From: go165 <196723798+go165@users.noreply.github.com> Date: Mon, 15 Jun 2026 02:10:50 +0800 Subject: [PATCH] fix(filesystem): normalize glob match paths --- src/filesystem/__tests__/lib.test.ts | 23 +++++++++++++++++++++++ src/filesystem/lib.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/filesystem/__tests__/lib.test.ts b/src/filesystem/__tests__/lib.test.ts index e0ae61224f..27a47670d4 100644 --- a/src/filesystem/__tests__/lib.test.ts +++ b/src/filesystem/__tests__/lib.test.ts @@ -380,6 +380,29 @@ describe('Lib Functions', () => { expect(result).toEqual([expectedResult]); }); + it('matches glob patterns against Windows-style relative paths', async () => { + const mockEntries = [ + { name: 'index.ts', isDirectory: () => false } + ]; + + mockFs.readdir.mockResolvedValueOnce(mockEntries as any); + mockFs.realpath.mockImplementation(async (inputPath: any) => inputPath.toString()); + vi.spyOn(path, 'relative').mockReturnValueOnce('src\\index.ts'); + + const testDir = process.platform === 'win32' ? 'C:\\allowed\\dir' : '/allowed/dir'; + const allowedDirs = process.platform === 'win32' ? ['C:\\allowed'] : ['/allowed']; + + const result = await searchFilesWithValidation( + testDir, + '**/*.ts', + allowedDirs, + {} + ); + + const expectedResult = process.platform === 'win32' ? 'C:\\allowed\\dir\\index.ts' : '/allowed/dir/index.ts'; + expect(result).toEqual([expectedResult]); + }); + it('handles complex exclude patterns with wildcards', async () => { const mockEntries = [ { name: 'test.txt', isDirectory: () => false }, diff --git a/src/filesystem/lib.ts b/src/filesystem/lib.ts index ce4af9f38a..f3b8eba35b 100644 --- a/src/filesystem/lib.ts +++ b/src/filesystem/lib.ts @@ -389,7 +389,7 @@ export async function searchFilesWithValidation( try { await validatePath(fullPath); - const relativePath = path.relative(rootPath, fullPath); + const relativePath = path.relative(rootPath, fullPath).replace(/\\/g, '/'); const shouldExclude = excludePatterns.some(excludePattern => minimatch(relativePath, excludePattern, { dot: true }) );