diff --git a/packages/isomorphic/urlMatch.ts b/packages/isomorphic/urlMatch.ts index 938195e54ff57..7afe1df3a9eb3 100644 --- a/packages/isomorphic/urlMatch.ts +++ b/packages/isomorphic/urlMatch.ts @@ -63,13 +63,29 @@ export function globToRegexPattern(glob: string): string { } switch (c) { - case '{': - inGroup = true; - tokens.push('('); + case '{': { + // Only treat '{' as a group opener when a matching '}' exists ahead; + // otherwise emit it as a literal to avoid producing an invalid regex. + let hasMatchingClose = false; + for (let j = i + 1; j < glob.length; j++) { + if (glob[j] === '\\' && j + 1 < glob.length) { j++; continue; } + if (glob[j] === '}') { hasMatchingClose = true; break; } + } + if (hasMatchingClose) { + inGroup = true; + tokens.push('('); + } else { + tokens.push('\\{'); + } break; + } case '}': - inGroup = false; - tokens.push(')'); + if (inGroup) { + inGroup = false; + tokens.push(')'); + } else { + tokens.push('\\}'); + } break; case ',': if (inGroup) { diff --git a/tests/page/interception.spec.ts b/tests/page/interception.spec.ts index e96e126f00b97..44ec056d3a2e0 100644 --- a/tests/page/interception.spec.ts +++ b/tests/page/interception.spec.ts @@ -114,6 +114,15 @@ it('should work with glob', async () => { expect(globToRegex('[a-z]')).toEqual(/^\[a-z\]$/); expect(globToRegex('$^+.\\*()|\\?\\{\\}\\[\\]')).toEqual(/^\$\^\+\.\*\(\)\|\?\{\}\[\]$/); + // unbalanced braces must be treated as literals, not produce invalid regexes + expect(globToRegex('{foo').test('{foo')).toBeTruthy(); + expect(globToRegex('{foo').test('foo')).toBeFalsy(); + expect(globToRegex('foo}').test('foo}')).toBeTruthy(); + expect(globToRegex('foo}').test('foo')).toBeFalsy(); + expect(globToRegex('**/*.png?{').test('https://localhost:8080/c.png?{')).toBeTruthy(); + expect(globToRegex('**/*.png?{').test('https://localhost:8080/c.png?')).toBeFalsy(); + expect(globToRegex('}foo{').test('}foo{')).toBeTruthy(); + expect(urlMatches(undefined, 'http://playwright.dev/', 'http://playwright.dev')).toBeTruthy(); expect(urlMatches(undefined, 'http://playwright.dev/?a=b', 'http://playwright.dev?a=b')).toBeTruthy(); expect(urlMatches(undefined, 'http://playwright.dev/', 'h*://playwright.dev')).toBeTruthy();