From aa66fb2fd3022d7bfe6af834fa383ef22a6f156b Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Wed, 23 Jun 2021 01:02:07 +0700 Subject: [PATCH] fix cloning of regex through `RegExp` constructor, close #948 --- CHANGELOG.md | 2 +- .../core-js/modules/es.regexp.constructor.js | 17 ++++++----------- tests/tests/es.regexp.constructor.js | 13 +++++++++++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c19444fa6b5c..f0b2abc41472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Changelog ##### Unreleased -- Nothing +- Fixed cloning of regex through `RegExp` constructor, [#948](https://github.com/zloirock/core-js/issues/948) ##### 3.15.0 - 2021.06.21 - Added `RegExp` named capture groups polyfill, [#521](https://github.com/zloirock/core-js/issues/521), [#944](https://github.com/zloirock/core-js/issues/944) diff --git a/packages/core-js/modules/es.regexp.constructor.js b/packages/core-js/modules/es.regexp.constructor.js index 8619347bed89..6c95d1319a59 100644 --- a/packages/core-js/modules/es.regexp.constructor.js +++ b/packages/core-js/modules/es.regexp.constructor.js @@ -113,17 +113,16 @@ if (isForced('RegExp', BASE_FORCED)) { var patternIsRegExp = isRegExp(pattern); var flagsAreUndefined = flags === undefined; var groups = []; - var rawPattern, rawFlags, dotAll, sticky, handled, result, state; + var rawPattern = pattern; + var rawFlags, dotAll, sticky, handled, result, state; - if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) { + if (!thisIsRegExp && patternIsRegExp && flagsAreUndefined && pattern.constructor === RegExpWrapper) { return pattern; } - if (CORRECT_NEW) { - if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source; - } else if (pattern instanceof RegExpWrapper) { - if (flagsAreUndefined) flags = getFlags.call(pattern); + if (patternIsRegExp || pattern instanceof RegExpWrapper) { pattern = pattern.source; + if (flagsAreUndefined) flags = 'flags' in rawPattern ? rawPattern.flags : getFlags.call(rawPattern); } pattern = pattern === undefined ? '' : String(pattern); @@ -148,11 +147,7 @@ if (isForced('RegExp', BASE_FORCED)) { groups = handled[1]; } - result = inheritIfRequired( - CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags), - thisIsRegExp ? this : RegExpPrototype, - RegExpWrapper - ); + result = inheritIfRequired(NativeRegExp(pattern, flags), thisIsRegExp ? this : RegExpPrototype, RegExpWrapper); if (dotAll || sticky || groups.length) { state = enforceInternalState(result); diff --git a/tests/tests/es.regexp.constructor.js b/tests/tests/es.regexp.constructor.js index 7128d4a7a718..881a2cd4e7a7 100644 --- a/tests/tests/es.regexp.constructor.js +++ b/tests/tests/es.regexp.constructor.js @@ -12,7 +12,7 @@ if (DESCRIPTORS) { assert.looksNative(RegExp); assert.ok({}.toString.call(RegExp()).slice(8, -1), 'RegExp'); assert.ok({}.toString.call(new RegExp()).slice(8, -1), 'RegExp'); - const regexp = /a/g; + let regexp = /a/g; assert.notStrictEqual(regexp, new RegExp(regexp), 'new RegExp(regexp) isnt regexp'); assert.strictEqual(regexp, RegExp(regexp), 'RegExp(regexp) is regexp'); regexp[Symbol.match] = false; @@ -26,8 +26,17 @@ if (DESCRIPTORS) { assert.strictEqual(String(new RegExp(/a/g, 'mi')), '/a/im', 'Allows a regex with flags'); assert.ok(new RegExp(/a/g, 'im') instanceof RegExp, 'Works with instanceof'); assert.strictEqual(new RegExp(/a/g, 'im').constructor, RegExp, 'Has the right constructor'); + + const orig = /^https?:\/\//i; + // eslint-disable-next-line regexp/no-useless-assertions -- false positive + regexp = new RegExp(orig); + assert.ok(regexp !== orig, 'new + re + no flags #1'); + assert.same(String(regexp), '/^https?:\\/\\//i', 'new + re + no flags #2'); + let result = regexp.exec('http://github.com'); + assert.deepEqual(result, ['http://'], 'new + re + no flags #3'); + /(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)/.exec('abcdefghijklmnopq'); - let result = true; + result = true; const characters = 'bcdefghij'; for (let i = 0, { length } = characters; i < length; ++i) { const chr = characters[i];