mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 14:52:09 +03:00
perf(obfuscation): cache per-word regexes instead of recompiling every request (#4109)
Integrated into release/v3.8.28 (r8)
This commit is contained in:
@@ -38,12 +38,26 @@ function escapeRegex(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
// Per-word regex cache — avoids recompiling one RegExp per word on every request body.
|
||||
// Bounded by distinct configured words; global regexes are safe to reuse (String.replace
|
||||
// resets lastIndex).
|
||||
const _obfuscationRegexCache = new Map<string, RegExp>();
|
||||
function getObfuscationRegex(word: string): RegExp {
|
||||
let regex = _obfuscationRegexCache.get(word);
|
||||
if (!regex) {
|
||||
if (_obfuscationRegexCache.size > 2000) _obfuscationRegexCache.clear();
|
||||
regex = new RegExp(escapeRegex(word), "gi");
|
||||
_obfuscationRegexCache.set(word, regex);
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
export function obfuscateSensitiveWords(text: string): string {
|
||||
if (!text || words.length === 0) return text;
|
||||
let result = text;
|
||||
for (const word of words) {
|
||||
if (!word) continue;
|
||||
const regex = new RegExp(escapeRegex(word), "gi");
|
||||
const regex = getObfuscationRegex(word);
|
||||
result = result.replace(regex, (m) => (m.length <= 1 ? m : m[0] + ZWJ + m.slice(1)));
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -40,14 +40,28 @@ function obfuscateWord(word: string): string {
|
||||
return word[0] + ZWJ + word.slice(1);
|
||||
}
|
||||
|
||||
// Per-word regex cache — obfuscateSensitiveWords recompiles one RegExp per word on every
|
||||
// request body otherwise. Bounded by distinct configured words; global regexes are safe to
|
||||
// reuse because String.replace resets lastIndex.
|
||||
const _obfuscationRegexCache = new Map<string, RegExp>();
|
||||
function getObfuscationRegex(word: string): RegExp {
|
||||
let regex = _obfuscationRegexCache.get(word);
|
||||
if (!regex) {
|
||||
if (_obfuscationRegexCache.size > 2000) _obfuscationRegexCache.clear();
|
||||
regex = new RegExp(escapeRegex(word), "gi");
|
||||
_obfuscationRegexCache.set(word, regex);
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
export function obfuscateSensitiveWords(text: string): string {
|
||||
if (!text || sensitiveWords.length === 0) return text;
|
||||
|
||||
let result = text;
|
||||
for (const word of sensitiveWords) {
|
||||
if (!word) continue;
|
||||
// Case-insensitive replacement
|
||||
const regex = new RegExp(escapeRegex(word), "gi");
|
||||
// Case-insensitive replacement (cached: see getObfuscationRegex)
|
||||
const regex = getObfuscationRegex(word);
|
||||
result = result.replace(regex, (match) => obfuscateWord(match));
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -269,12 +269,27 @@ function obfuscateWord(word: string): string {
|
||||
* list instead of the module-level singleton, so concurrent requests with
|
||||
* different op configs do not race.
|
||||
*/
|
||||
// Per-word regex cache: obfuscateWithList runs over the whole request body on every
|
||||
// request when obfuscation is enabled, recompiling one RegExp per word each time. The
|
||||
// word list is stable per op config, so memoize. Bounded by distinct configured words
|
||||
// (with a defensive cap). Global regexes are safe to reuse: String.replace resets lastIndex.
|
||||
const _obfuscationRegexCache = new Map<string, RegExp>();
|
||||
function getObfuscationRegex(word: string): RegExp {
|
||||
let regex = _obfuscationRegexCache.get(word);
|
||||
if (!regex) {
|
||||
if (_obfuscationRegexCache.size > 2000) _obfuscationRegexCache.clear();
|
||||
regex = new RegExp(escapeRegex(word), "gi");
|
||||
_obfuscationRegexCache.set(word, regex);
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
function obfuscateWithList(text: string, words: string[]): string {
|
||||
if (!text || words.length === 0) return text;
|
||||
let result = text;
|
||||
for (const word of words) {
|
||||
if (!word) continue;
|
||||
const regex = new RegExp(escapeRegex(word), "gi");
|
||||
const regex = getObfuscationRegex(word);
|
||||
result = result.replace(regex, (match) => obfuscateWord(match));
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user