Skip to content

Commit 766ff3b

Browse files
committed
fix order of arguments validation in String.prototype.{ startsWith, endsWith } polyfills
1 parent 1b8ac69 commit 766ff3b

File tree

7 files changed

+33
-2
lines changed

7 files changed

+33
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- Fixed iterator closing in `Set.prototype.{ isDisjointFrom, isSupersetOf }` polyfill
1414
- Fixed (updated following the final spec) one more case `Set.prototype.difference` polyfill with updating `this`
1515
- Fixed `DataView.prototype.setFloat16` polyfill in (0, 1) range
16+
- Fixed order of arguments validation in `String.prototype.{ startsWith, endsWith }` polyfills
1617
- Fixed named backreferences in `RegExp` NCG polyfill
1718
- Fixed some cases of `RegExp` NCG polyfill in combination with other types of groups
1819
- Fixed some cases of `RegExp` NCG polyfill in combination with `dotAll`

packages/core-js/modules/es.string.ends-with.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ $({ target: 'String', proto: true, forced: !MDN_POLYFILL_BUG && !CORRECT_IS_REGE
2525
endsWith: function endsWith(searchString /* , endPosition = @length */) {
2626
var that = toString(requireObjectCoercible(this));
2727
notARegExp(searchString);
28+
var search = toString(searchString);
2829
var endPosition = arguments.length > 1 ? arguments[1] : undefined;
2930
var len = that.length;
3031
var end = endPosition === undefined ? len : min(toLength(endPosition), len);
31-
var search = toString(searchString);
3232
return slice(that, end - search.length, end) === search;
3333
}
3434
});

packages/core-js/modules/es.string.starts-with.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ $({ target: 'String', proto: true, forced: !MDN_POLYFILL_BUG && !CORRECT_IS_REGE
2525
startsWith: function startsWith(searchString /* , position = 0 */) {
2626
var that = toString(requireObjectCoercible(this));
2727
notARegExp(searchString);
28-
var index = toLength(min(arguments.length > 1 ? arguments[1] : undefined, that.length));
2928
var search = toString(searchString);
29+
var index = toLength(min(arguments.length > 1 ? arguments[1] : undefined, that.length));
3030
return stringSlice(that, index, index + search.length) === search;
3131
}
3232
});

tests/unit-global/es.string.ends-with.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,11 @@ QUnit.test('String#endsWith', assert => {
4242
assert.notThrows(() => '[object Object]'.endsWith(object));
4343
object[Symbol.match] = true;
4444
assert.throws(() => '[object Object]'.endsWith(object), TypeError);
45+
// side-effect ordering: ToString(searchString) should happen before ToIntegerOrInfinity(endPosition)
46+
const order = [];
47+
'abc'.endsWith(
48+
{ toString() { order.push('search'); return 'c'; } },
49+
{ valueOf() { order.push('pos'); return 3; } },
50+
);
51+
assert.deepEqual(order, ['search', 'pos'], 'ToString(searchString) before ToIntegerOrInfinity(endPosition)');
4552
});

tests/unit-global/es.string.starts-with.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,11 @@ QUnit.test('String#startsWith', assert => {
4141
assert.notThrows(() => '[object Object]'.startsWith(object));
4242
object[Symbol.match] = true;
4343
assert.throws(() => '[object Object]'.startsWith(object), TypeError);
44+
// side-effect ordering: ToString(searchString) should happen before ToIntegerOrInfinity(position)
45+
const order = [];
46+
'abc'.startsWith(
47+
{ toString() { order.push('search'); return 'a'; } },
48+
{ valueOf() { order.push('pos'); return 0; } },
49+
);
50+
assert.deepEqual(order, ['search', 'pos'], 'ToString(searchString) before ToIntegerOrInfinity(position)');
4451
});

tests/unit-pure/es.string.ends-with.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,12 @@ QUnit.test('String#endsWith', assert => {
3737
assert.notThrows(() => endsWith('[object Object]', object));
3838
object[Symbol.match] = true;
3939
assert.throws(() => endsWith('[object Object]', object), TypeError);
40+
// side-effect ordering: ToString(searchString) should happen before ToIntegerOrInfinity(endPosition)
41+
const order = [];
42+
endsWith(
43+
'abc',
44+
{ toString() { order.push('search'); return 'c'; } },
45+
{ valueOf() { order.push('pos'); return 3; } },
46+
);
47+
assert.deepEqual(order, ['search', 'pos'], 'ToString(searchString) before ToIntegerOrInfinity(endPosition)');
4048
});

tests/unit-pure/es.string.starts-with.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,12 @@ QUnit.test('String#startsWith', assert => {
3737
assert.notThrows(() => startsWith('[object Object]', object));
3838
object[Symbol.match] = true;
3939
assert.throws(() => startsWith('[object Object]', object), TypeError);
40+
// side-effect ordering: ToString(searchString) should happen before ToIntegerOrInfinity(position)
41+
const order = [];
42+
startsWith(
43+
'abc',
44+
{ toString() { order.push('search'); return 'a'; } },
45+
{ valueOf() { order.push('pos'); return 0; } },
46+
);
47+
assert.deepEqual(order, ['search', 'pos'], 'ToString(searchString) before ToIntegerOrInfinity(position)');
4048
});

0 commit comments

Comments
 (0)