From 66c31a0c07b6ad73c096c6d4553c0dbd3385baf7 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 22 Jul 2021 10:22:07 -0400 Subject: [PATCH] LibJS: Implement RegExp.prototype [ @@search ] with UTF-16 code units --- .../LibJS/Runtime/RegExpPrototype.cpp | 8 ++++---- .../LibJS/Runtime/StringPrototype.cpp | 7 +++++-- .../String/String.prototype.search.js | 19 ++++++++++++------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 5373735c0d..a80d94efa5 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -787,14 +787,14 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) // 22.2.5.11 RegExp.prototype [ @@search ] ( string ), https://tc39.es/ecma262/#sec-regexp.prototype-@@search JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) { - auto string_value = vm.argument(0); - auto* regexp_object = this_object_from(vm, global_object); if (!regexp_object) return {}; - auto string = string_value.to_string(global_object); + + auto string = vm.argument(0).to_utf16_string(global_object); if (vm.exception()) return {}; + Utf16View string_view { string }; auto previous_last_index = regexp_object->get(vm.names.lastIndex); if (vm.exception()) @@ -805,7 +805,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) return {}; } - auto result = regexp_exec(global_object, *regexp_object, string); + auto result = regexp_exec(global_object, *regexp_object, string_view); if (vm.exception()) return {}; diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index 549d82e508..dda7cd91ed 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -1085,13 +1085,16 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search) if (vm.exception()) return {}; } - auto s = this_object.to_string(global_object); + + auto string = this_object.to_utf16_string(global_object); if (vm.exception()) return {}; + Utf16View utf16_string_view { string }; + auto rx = regexp_create(global_object, regexp, js_undefined()); if (!rx) return {}; - return rx->invoke(*vm.well_known_symbol_search(), js_string(vm, s)); + return rx->invoke(*vm.well_known_symbol_search(), js_string(vm, utf16_string_view)); } // B.2.3.2.1 CreateHTML ( string, tag, attribute, value ), https://tc39.es/ecma262/#sec-createhtml diff --git a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.search.js b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.search.js index 07480adb9c..e104a521e5 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.search.js +++ b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.search.js @@ -46,10 +46,15 @@ test("override exec with non-function", () => { expect("test".search(re)).toBe(0); }); -// FIXME: RegExp.prototype [ @@search ] needs to support UTF-16. -// test("UTF-16", () => { -// var s = "😀"; -// expect(s.search("😀")).toBe(0); -// expect(s.search("\ud83d")).toBe(0); -// expect(s.search("\ude00")).toBe(1); -// }); +test("UTF-16", () => { + var s = "😀"; + expect(s.search("😀")).toBe(0); + expect(s.search("\ud83d")).toBe(0); + expect(s.search("\ude00")).toBe(1); + expect(s.search("foo")).toBe(-1); + + s = "\u{80}\u{160}"; + expect(s.search("\u{80}")).toBe(0); + expect(s.search("\u{160}")).toBe(1); + expect(s.search("foo")).toBe(-1); +});