Skip to content

Commit 3a7fc91

Browse files
committed
fix: escape all regex metacharacters in glob-to-regex conversion for Office file filtering
The filePattern filter for Excel (xlsx) and DOCX content searches converted glob patterns to regex by only escaping '.' and '*'. Characters like '(', ')', '[', ']', '+', '^', '$', '{', '}' and '|' were left unescaped, causing incorrect filename matches for real-world patterns such as: - report(2024).xlsx -> '(' treated as regex group start - [draft].xlsx -> '[draft]' treated as character class - file+notes.docx -> '+' treated as quantifier Fix: escape all regex special characters first (excluding '*'), then convert the remaining glob '*' wildcards to '.*'. Both the Excel and DOCX filter paths are updated. Addresses CodeRabbit major finding on PR wonderwhy-er#400.
1 parent c5c434b commit 3a7fc91

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

src/search-manager.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,13 @@ export interface SearchSessionOptions {
408408
return patterns.some(pat => {
409409
// Support glob-like patterns
410410
if (pat.includes('*')) {
411-
// Glob patterns are safe (generated from sanitized file extensions, not user regex)
412-
const regexPat = pat.replace(/\./g, '\\.').replace(/\*/g, '.*');
411+
// Escape all regex metacharacters first (preserving * for glob expansion),
412+
// then convert the remaining * wildcards to .* for glob matching.
413+
// Without this, patterns like report(2024).xlsx or [draft].xlsx would be
414+
// misinterpreted as regex groups/character-classes.
415+
const regexPat = pat
416+
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // escape metacharacters except *
417+
.replace(/\*/g, '.*'); // glob * → regex .*
413418
return new RegExp(`^${regexPat}$`, 'i').test(fileName);
414419
}
415420
// Exact match (case-insensitive)
@@ -582,7 +587,9 @@ export interface SearchSessionOptions {
582587
const fileName = path.basename(filePath);
583588
return patterns.some(pat => {
584589
if (pat.includes('*')) {
585-
const regexPat = pat.replace(/\./g, '\\.').replace(/\*/g, '.*');
590+
const regexPat = pat
591+
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // escape metacharacters except *
592+
.replace(/\*/g, '.*'); // glob * → regex .*
586593
return new RegExp(`^${regexPat}$`, 'i').test(fileName);
587594
}
588595
return fileName.toLowerCase() === pat.toLowerCase();

0 commit comments

Comments
 (0)