Skip to content

Commit f315d5e

Browse files
committed
LibJS: Reject repeat counts above 2^53 - 1 in String.prototype.repeat
Converting the maximum size_t value to a double rounds up to 2^64, so a count of exactly 2^64 passed the range check and was subsequently converted to an unsigned type, which is undefined behavior. Compare against the maximum array-like index instead, which is exactly representable as a double. Any count above that limit necessarily exceeds the maximum string length, so it is rejected in any case.
1 parent 6cca2b9 commit f315d5e

2 files changed

Lines changed: 5 additions & 1 deletion

File tree

Libraries/LibJS/Runtime/StringPrototype.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
824824
if (string->is_empty())
825825
return PrimitiveString::create(vm, Utf16String {});
826826

827-
if (n > static_cast<double>(NumericLimits<size_t>::max()))
827+
if (n > MAX_ARRAY_LIKE_INDEX)
828828
return vm.throw_completion<RangeError>(ErrorType::StringRepeatCountMustNotOverflow);
829829

830830
auto count = static_cast<size_t>(n);

Tests/LibJS/Runtime/builtins/String/String.prototype.repeat.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ test("throws correct range errors", () => {
3030
expect(() => {
3131
"aa".repeat(0x80000000);
3232
}).toThrowWithMessage(RangeError, "repeat count must not overflow");
33+
34+
expect(() => {
35+
"foo".repeat(2 ** 64);
36+
}).toThrowWithMessage(RangeError, "repeat count must not overflow");
3337
});
3438

3539
test("UTF-16", () => {

0 commit comments

Comments
 (0)