diff --git a/AK/String.cpp b/AK/String.cpp index 3fe5e088679..2f4aaac8b73 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -636,4 +636,21 @@ bool String::equals_ignoring_ascii_case(StringView other) const return StringUtils::equals_ignoring_ascii_case(bytes_as_string_view(), other); } +String String::repeated(String const& input, size_t count) +{ + VERIFY(!Checked::multiplication_would_overflow(count, input.bytes().size())); + u8* buffer = nullptr; + auto data = MUST(Detail::StringData::create_uninitialized(count * input.bytes().size(), buffer)); + + if (input.bytes().size() == 1) { + memset(buffer, input.bytes().first(), count); + return String { move(data) }; + } + + for (size_t i = 0; i < count; ++i) { + memcpy(buffer + (i * input.bytes().size()), input.bytes().data(), input.bytes().size()); + } + return String { data }; +} + } diff --git a/AK/String.h b/AK/String.h index b37ec0b9bfa..a608f772bbc 100644 --- a/AK/String.h +++ b/AK/String.h @@ -92,6 +92,9 @@ public: // Creates a new String with a single code point repeated N times. static ErrorOr repeated(u32 code_point, size_t count); + // Creates a new String from another string, repeated N times. + static String repeated(String const&, size_t count); + // Creates a new String by case-transforming this String. Using these methods require linking LibUnicode into your application. ErrorOr to_lowercase(Optional const& locale = {}) const; ErrorOr to_uppercase(Optional const& locale = {}) const; diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index da3bb9c8dbd..9e842002e23 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -777,10 +777,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat) return PrimitiveString::create(vm, String {}); // 6. Return the String value that is made from n copies of S appended together. - StringBuilder builder; - for (size_t i = 0; i < n; ++i) - builder.append(string); - return PrimitiveString::create(vm, MUST(builder.to_string())); + return PrimitiveString::create(vm, String::repeated(string, n)); } // 22.1.3.19 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace