From b7317a23139b17c31ebef04640842257adb593b1 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Tue, 1 Nov 2022 12:20:11 +0300
Subject: [PATCH] fix(regex): Don't cache stateful regex instances (#18645)

---
 lib/util/regex.spec.ts | 14 ++++++++++++++
 lib/util/regex.ts      | 13 +++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/lib/util/regex.spec.ts b/lib/util/regex.spec.ts
index 89139ddbc0..f8d24b1f05 100644
--- a/lib/util/regex.spec.ts
+++ b/lib/util/regex.spec.ts
@@ -15,6 +15,20 @@ describe('util/regex', () => {
     expect(() => regEx(`x++`)).toThrow(CONFIG_VALIDATION);
   });
 
+  it('reuses flags from regex', () => {
+    expect(regEx(/foo/i).flags).toBe('iu');
+  });
+
+  it('caches non-stateful regex', () => {
+    expect(regEx('foo')).toBe(regEx('foo'));
+    expect(regEx('foo', 'm')).toBe(regEx('foo', 'm'));
+  });
+
+  it('does not cache stateful regex', () => {
+    expect(regEx('foo', 'g')).not.toBe(regEx('foo', 'g'));
+    expect(regEx(/bar/g)).not.toBe(/bar/g);
+  });
+
   it('Falls back to RegExp', () => {
     jest.doMock('re2', () => {
       throw new Error();
diff --git a/lib/util/regex.ts b/lib/util/regex.ts
index 4b0e112384..6e6bdf2952 100644
--- a/lib/util/regex.ts
+++ b/lib/util/regex.ts
@@ -24,16 +24,25 @@ export function regEx(
   flags?: string | undefined,
   useCache = true
 ): RegExp {
+  let canBeCached = useCache;
+  if (canBeCached && flags?.includes('g')) {
+    canBeCached = false;
+  }
+  if (canBeCached && is.regExp(pattern) && pattern.flags.includes('g')) {
+    canBeCached = false;
+  }
+
   const key = flags ? `${pattern.toString()}:${flags}` : pattern.toString();
-  if (useCache) {
+  if (canBeCached) {
     const cachedResult = cache.get(key);
     if (cachedResult) {
       return cachedResult;
     }
   }
+
   try {
     const instance = new RegEx(pattern, flags);
-    if (useCache) {
+    if (canBeCached) {
       cache.set(key, instance);
     }
     return instance;
-- 
GitLab