Skip to content

Commit 53c3810

Browse files
themr0cclaude
andcommitted
[RHIDP-12950]: Fix S5852 regex hotspots in cqa-00a-orphaned.js
Replace regex-based include path extraction with indexOf, and replace dynamic RegExp pattern matching with string-segment glob matching to eliminate super-linear backtracking risk. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 06cc4d2 commit 53c3810

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

build/scripts/cqa/checks/cqa-00a-orphaned.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,12 @@ function collectIncludes(root) {
8989
for (const file of walkAdoc(root)) {
9090
for (const line of readLines(file)) {
9191
if (!line.startsWith('include::')) continue;
92-
const path = line.slice('include::'.length).replace(/\[[\s\S]*$/, '').trim();
92+
const raw = line.slice('include::'.length);
93+
const bracketIdx = raw.indexOf('[');
94+
const path = (bracketIdx >= 0 ? raw.slice(0, bracketIdx) : raw).trim();
9395
const bn = basename(path);
9496
if (bn.includes('{')) {
95-
includedPatterns.push(patternToRegex(bn));
97+
includedPatterns.push(patternToGlob(bn));
9698
} else {
9799
includedBasenames.add(bn);
98100
}
@@ -127,13 +129,26 @@ function collectImageRefsFromFile(file, referenced) {
127129

128130
// ── Pure utilities ────────────────────────────────────────────────────────────
129131

130-
function patternToRegex(bn) {
131-
const escaped = bn.replaceAll('.', String.raw`\.`).replaceAll(/\{[^}]*\}/g, '[^.]+');
132-
return new RegExp(`^${escaped}$`);
132+
function patternToGlob(bn) {
133+
// Split on {attr} placeholders, returning fixed segments
134+
return bn.split(/\{[^}]*\}/);
133135
}
134136

135137
function isIncluded(bn, basenames, patterns) {
136-
return basenames.has(bn) || patterns.some(re => re.test(bn));
138+
if (basenames.has(bn)) return true;
139+
return patterns.some(segments => {
140+
if (segments.length <= 1) return bn === (segments[0] || '');
141+
// Check that bn starts with first segment, ends with last, and contains middle segments in order
142+
if (!bn.startsWith(segments[0])) return false;
143+
if (!bn.endsWith(segments[segments.length - 1])) return false;
144+
let pos = segments[0].length;
145+
for (let i = 1; i < segments.length - 1; i++) {
146+
const idx = bn.indexOf(segments[i], pos);
147+
if (idx < 0) return false;
148+
pos = idx + segments[i].length;
149+
}
150+
return true;
151+
});
137152
}
138153

139154
function* walkAdoc(dir) {

0 commit comments

Comments
 (0)