1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:57:45 +00:00

LibJS: Implement String.prototype.substr with UTF-16 code units

This commit is contained in:
Timothy Flynn 2021-07-19 13:34:41 -04:00 committed by Andreas Kling
parent 60d8852fc2
commit 892bfdbbcf
2 changed files with 18 additions and 10 deletions

View file

@ -527,14 +527,12 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
// B.2.3.1 String.prototype.substr ( start, length ), https://tc39.es/ecma262/#sec-string.prototype.substr // B.2.3.1 String.prototype.substr ( start, length ), https://tc39.es/ecma262/#sec-string.prototype.substr
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
{ {
auto string = ak_string_from(vm, global_object); auto string = utf16_string_from(vm, global_object);
if (!string.has_value()) if (vm.exception())
return {}; return {};
if (vm.argument_count() == 0)
return js_string(vm, *string);
// FIXME: this should index a UTF-16 code_point view of the string. Utf16View utf16_string_view { string };
auto size = (i32)string->length(); auto size = utf16_string_view.length_in_code_units();
auto int_start = vm.argument(0).to_integer_or_infinity(global_object); auto int_start = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception()) if (vm.exception())
@ -551,15 +549,14 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
return {}; return {};
if (Value(int_start).is_positive_infinity() || (int_length <= 0) || Value(int_length).is_positive_infinity()) if (Value(int_start).is_positive_infinity() || (int_length <= 0) || Value(int_length).is_positive_infinity())
return js_string(vm, String("")); return js_string(vm, String::empty());
auto int_end = min((i32)(int_start + int_length), size); auto int_end = min((i32)(int_start + int_length), size);
if (int_start >= int_end) if (int_start >= int_end)
return js_string(vm, String("")); return js_string(vm, String::empty());
auto string_part = string->substring(int_start, int_end - int_start); return js_string(vm, utf16_string_view.substring_view(int_start, int_end - int_start));
return js_string(vm, string_part);
} }
// 22.1.3.7 String.prototype.includes ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.includes // 22.1.3.7 String.prototype.includes ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.includes

View file

@ -17,3 +17,14 @@ test("basic functionality", () => {
expect("hello friends".substr(-7)).toBe("friends"); expect("hello friends".substr(-7)).toBe("friends");
expect("hello friends".substr(-3, -5)).toBe(""); expect("hello friends".substr(-3, -5)).toBe("");
}); });
test("UTF-16", () => {
var s = "😀";
expect(s).toHaveLength(2);
expect(s.substr()).toBe("😀");
expect(s.substr(0)).toBe("😀");
expect(s.substr(0, 2)).toBe("😀");
expect(s.substr(0, 1)).toBe("\ud83d");
expect(s.substr(1, 1)).toBe("\ude00");
expect(s.substr(2, 1)).toBe("");
});