From 8617c0662318bacdd0953303618ba3c1f9539c53 Mon Sep 17 00:00:00 2001 From: Muhammad Yusuf Date: Wed, 3 Jun 2026 12:05:37 +0800 Subject: [PATCH] chore: refer code from https://github.com/actions/toolkit/pull/2057 --- packages/glob/__tests__/internal-pattern.test.ts | 12 ++++++++++++ packages/glob/src/internal-pattern.ts | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/glob/__tests__/internal-pattern.test.ts b/packages/glob/__tests__/internal-pattern.test.ts index 2f101d9fba..b0682b8e6b 100644 --- a/packages/glob/__tests__/internal-pattern.test.ts +++ b/packages/glob/__tests__/internal-pattern.test.ts @@ -4,6 +4,7 @@ import * as path from 'path' import {MatchKind} from '../src/internal-match-kind.js' import {promises as fs} from 'fs' import {Pattern} from '../src/internal-pattern.js' +import {performance} from 'perf_hooks' const IS_WINDOWS = process.platform === 'win32' @@ -356,6 +357,17 @@ describe('pattern', () => { }) }) +describe('globEscape ReDoS', () => { + it('done in 1s', () => { + const attackString = `${'['.repeat(100000)}\u0000` + const startTime = performance.now() + Pattern.globEscape(attackString) + const endTime = performance.now() + const timeTaken = endTime - startTime + expect(timeTaken).toBeLessThan(1000) + }) +}) + function getTestTemp(): string { return path.join(__dirname, '_temp', 'internal-pattern') } diff --git a/packages/glob/src/internal-pattern.ts b/packages/glob/src/internal-pattern.ts index f6fb740b4d..640f7ee0ee 100644 --- a/packages/glob/src/internal-pattern.ts +++ b/packages/glob/src/internal-pattern.ts @@ -188,7 +188,7 @@ export class Pattern { */ static globEscape(s: string): string { return (IS_WINDOWS ? s : s.replace(/\\/g, '\\\\')) // escape '\' on Linux/macOS - .replace(/(\[)(?=[^/]+\])/g, '[[]') // escape '[' when ']' follows within the path segment + .replace(/(\[)(?!\[{500})([^/]+\])/g, '[[]$2') // escape '[' when ']' follows within the path segment .replace(/\?/g, '[?]') // escape '?' .replace(/\*/g, '[*]') // escape '*' }