From 42b31820a65d2625e025647c75d185fb0e5e7b5b Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Wed, 6 Nov 2024 04:26:56 +0100 Subject: [PATCH] LibWeb: Use UTF-16 code units length in CharacterData::replace_data() Range API uses UTF-16 code units to represent offsets, so replace_data() needs to use it instead of bytes count while calculating new offsets. Fixes incorrectly thrown exception when non-latin string is passed into replace_data(). --- Tests/LibWeb/Text/expected/text-insertData.txt | 1 + Tests/LibWeb/Text/input/text-insertData.html | 13 +++++++++++++ Userland/Libraries/LibWeb/DOM/CharacterData.cpp | 6 ++++-- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/text-insertData.txt create mode 100644 Tests/LibWeb/Text/input/text-insertData.html diff --git a/Tests/LibWeb/Text/expected/text-insertData.txt b/Tests/LibWeb/Text/expected/text-insertData.txt new file mode 100644 index 00000000000..241c76b933b --- /dev/null +++ b/Tests/LibWeb/Text/expected/text-insertData.txt @@ -0,0 +1 @@ +=Привет= diff --git a/Tests/LibWeb/Text/input/text-insertData.html b/Tests/LibWeb/Text/input/text-insertData.html new file mode 100644 index 00000000000..ed65954c480 --- /dev/null +++ b/Tests/LibWeb/Text/input/text-insertData.html @@ -0,0 +1,13 @@ + + +
==
+ diff --git a/Userland/Libraries/LibWeb/DOM/CharacterData.cpp b/Userland/Libraries/LibWeb/DOM/CharacterData.cpp index 42d9cb64b75..7dd4c71e02a 100644 --- a/Userland/Libraries/LibWeb/DOM/CharacterData.cpp +++ b/Userland/Libraries/LibWeb/DOM/CharacterData.cpp @@ -72,6 +72,8 @@ WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t coun Utf16View utf16_view { utf16_data }; auto length = utf16_view.length_in_code_units(); + auto inserted_data_length_in_utf16_code_units = AK::utf16_code_unit_length_from_utf8(data); + // 2. If offset is greater than length, then throw an "IndexSizeError" DOMException. if (offset > length) return WebIDL::IndexSizeError::create(realm(), "Replacement offset out of range."_string); @@ -107,14 +109,14 @@ WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t coun // 10. For each live range whose start node is node and start offset is greater than offset plus count, increase its start offset by data’s length and decrease it by count. for (auto& range : Range::live_ranges()) { if (range->start_container() == this && range->start_offset() > (offset + count)) - TRY(range->set_start(*range->start_container(), range->start_offset() + data.bytes().size() - count)); + TRY(range->set_start(*range->start_container(), range->start_offset() + inserted_data_length_in_utf16_code_units - count)); } // 11. For each live range whose end node is node and end offset is greater than offset plus count, increase its end offset by data’s length and decrease it by count. for (auto& range : Range::live_ranges()) { if (range->end_container() == this && range->end_offset() > (offset + count)) { // AD-HOC: Clamp offset to the end of the data if it's too large. - auto new_offset = min(range->end_offset() + data.bytes().size() - count, m_data.bytes().size()); + auto new_offset = min(range->end_offset() + inserted_data_length_in_utf16_code_units - count, length_in_utf16_code_units()); TRY(range->set_end(*range->end_container(), new_offset)); } }