From 20287c13399cd425c4874ab4a474b34401d21f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Tue, 13 Nov 2018 23:37:35 +0100 Subject: [PATCH] Fix String#split and another RegExp#lastIndex case in IE8 --- packages/core-js/internals/regexp-exec.js | 25 ++++++++++++++--------- tests/tests/es.regexp.exec.js | 8 ++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/core-js/internals/regexp-exec.js b/packages/core-js/internals/regexp-exec.js index a9a0c57ff851..55a0e16411d3 100644 --- a/packages/core-js/internals/regexp-exec.js +++ b/packages/core-js/internals/regexp-exec.js @@ -11,17 +11,20 @@ var nativeReplace = String.prototype.replace; var patchedExec = nativeExec; var LAST_INDEX = 'lastIndex'; - -var UPDATES_LAST_INDEX_NON_GLOBAL = (function () { - var re = /a/; - nativeExec.call(re, 'a'); - return re[LAST_INDEX] !== 0; +var LENGTH = 'length'; + +var UPDATES_LAST_INDEX_WRONG = (function () { + var re1 = /a/, + re2 = /b*/g; + nativeExec.call(re1, 'a'); + nativeExec.call(re2, 'a'); + return re1[LAST_INDEX] !== 0// || re2[LAST_INDEX] !== 0; })(); // nonparticipating capturing group, copied from es5-shim's String#split patch. var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined; -var patch = UPDATES_LAST_INDEX_NON_GLOBAL || NPCG_INCLUDED; +var patch = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED; if (patch) { patchedExec = function exec(str) { @@ -31,17 +34,19 @@ if (patch) { if (NPCG_INCLUDED) { reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re)); } - if (UPDATES_LAST_INDEX_NON_GLOBAL) lastIndex = this[LAST_INDEX]; + if (UPDATES_LAST_INDEX_WRONG) lastIndex = this[LAST_INDEX]; match = nativeExec.call(this, str); - if (UPDATES_LAST_INDEX_NON_GLOBAL && !this.global) this[LAST_INDEX] = lastIndex; - if (NPCG_INCLUDED && match && match.length > 1) { + if (UPDATES_LAST_INDEX_WRONG && match) { + this[LAST_INDEX] = this.global ? match.index + match[0][LENGTH] : lastIndex; + } + if (NPCG_INCLUDED && match && match[LENGTH] > 1) { // Fix browsers whose `exec` methods don't consistently return `undefined` // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/ // eslint-disable-next-line no-loop-func nativeReplace.call(match[0], reCopy, function () { - for (i = 1; i < arguments.length - 2; i++) { + for (i = 1; i < arguments[LENGTH] - 2; i++) { if (arguments[i] === undefined) match[i] = undefined; } }); diff --git a/tests/tests/es.regexp.exec.js b/tests/tests/es.regexp.exec.js index fc3a9e8f17df..fd9222a01373 100644 --- a/tests/tests/es.regexp.exec.js +++ b/tests/tests/es.regexp.exec.js @@ -8,6 +8,14 @@ QUnit.test('RegExp#exec lastIndex updating', assert => { assert.strictEqual(re.lastIndex, 0, '.lastIndex starts at 0 for global regexps'); re.exec('abc'); assert.strictEqual(re.lastIndex, 2, '.lastIndex is updated for global regexps'); + + re = /b*/; + re.exec('a'); + assert.strictEqual(re.lastIndex, 0, '.lastIndex isn\'t updated for non-global regexps if the match is empty'); + + re = /b*/g; + re.exec('a'); + assert.strictEqual(re.lastIndex, 0, '.lastIndex isn\'t updated for global regexps if the match is empty'); }); QUnit.test('RegExp#exec capturing groups', assert => {