From 8a4e5ccb12513f9da6b917913da2f62f1c876653 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Mon, 9 Sep 2019 12:21:01 +0200
Subject: [PATCH] fix: add try/throw within util/regex (#4453)

---
 lib/util/regex.ts             | 34 +++++++++++++++++++---------------
 lib/versioning/regex/index.ts | 14 ++------------
 test/util/regex.spec.ts       |  9 ++++++---
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/lib/util/regex.ts b/lib/util/regex.ts
index b109ffde07..3094b008a1 100644
--- a/lib/util/regex.ts
+++ b/lib/util/regex.ts
@@ -1,22 +1,26 @@
 import { logger } from '../logger';
 
-export interface RegExConstructor {
-  new (pattern: RegExp | string): RegExp;
-  new (pattern: string, flags?: string): RegExp;
+let RegEx;
+
+try {
+  // eslint-disable-next-line
+  const RE2 = require('re2');
+  // Test if native is working
+  new RE2('.*').exec('test');
+  logger.debug('Using RE2 as regex engine');
+  RegEx = RE2;
+} catch (err) {
+  logger.warn({ err }, 'RE2 not usable, falling back to RegExp');
+  RegEx = RegExp;
 }
 
-const RegEx: RegExConstructor = (() => {
+export function regEx(pattern: string, flags?: string) {
   try {
-    // eslint-disable-next-line
-    const RE2 = require('re2');
-    // Test if native is working
-    new RE2('.*').exec('test');
-    logger.debug('Using RE2 as regex engine');
-    return RE2;
+    return new RegEx(pattern, flags);
   } catch (err) {
-    logger.warn({ err }, 'RE2 not usable, falling back to RegExp');
-    return RegExp;
+    const error = new Error('config-validation');
+    error.configFile = pattern;
+    error.validationError = 'Invalid regular expression: ' + err.toString();
+    throw error;
   }
-})();
-
-export { RegEx };
+}
diff --git a/lib/versioning/regex/index.ts b/lib/versioning/regex/index.ts
index 94e2c1c672..7ae233e300 100644
--- a/lib/versioning/regex/index.ts
+++ b/lib/versioning/regex/index.ts
@@ -1,8 +1,7 @@
 import { compare, satisfies, ltr, minSatisfying, maxSatisfying } from 'semver';
 import { VersioningApiConstructor } from '../common';
 import { GenericVersion, GenericVersioningApi } from '../loose/generic';
-import { logger } from '../../logger';
-import { RegEx } from '../../util/regex';
+import { regEx } from '../../util/regex';
 
 export interface RegExpVersion extends GenericVersion {
   /** prereleases are treated in the standard semver manner, if present */
@@ -48,16 +47,7 @@ export class RegExpVersioningApi extends GenericVersioningApi<RegExpVersion> {
 
     // TODO: should we validate the user has not added extra unsupported
     // capture groups?
-
-    try {
-      this._config = new RegEx(new_config);
-    } catch (e) {
-      logger.debug({ err: e }, 'regex error');
-      const error = new Error('config-validation');
-      error.configFile = new_config;
-      error.validationError = 'Invalid regex versionSheme found';
-      throw error;
-    }
+    this._config = regEx(new_config);
   }
 
   protected _compare(version: string, other: string): number {
diff --git a/test/util/regex.spec.ts b/test/util/regex.spec.ts
index f99dd32510..64ea780e9c 100644
--- a/test/util/regex.spec.ts
+++ b/test/util/regex.spec.ts
@@ -1,5 +1,5 @@
 import RE2 from 're2';
-import { RegEx } from '../../lib/util/regex';
+import { regEx } from '../../lib/util/regex';
 
 describe('util/regex', () => {
   beforeEach(() => {
@@ -7,7 +7,10 @@ describe('util/regex', () => {
   });
 
   it('uses RE2', () => {
-    expect(RegEx).toEqual(RE2);
+    expect(regEx('foo')).toBeInstanceOf(RE2);
+  });
+  it('throws unsafe 2', () => {
+    expect(() => regEx(`x++`)).toThrow('config-validation');
   });
 
   it('Falls back to RegExp', () => {
@@ -16,6 +19,6 @@ describe('util/regex', () => {
     });
 
     const regex = require('../../lib/util/regex');
-    expect(regex.RegEx).toEqual(RegExp);
+    expect(regex.regEx('foo')).toBeInstanceOf(RegExp);
   });
 });
-- 
GitLab