LibWeb: Respect subarrays in TextEncoder::encode_into

This is the method that Figma uses to write strings into Wasm memory,
using subarrays to select a particular Wasm memory address to write to.
This commit is contained in:
Luke Wilde 2025-01-09 16:30:30 +00:00 committed by Andreas Kling
parent 513231216a
commit 3ab93667f5
Notes: github-actions[bot] 2025-01-21 20:38:39 +00:00
3 changed files with 10 additions and 10 deletions

View file

@ -53,7 +53,7 @@ GC::Ref<JS::Uint8Array> TextEncoder::encode(String const& input) const
// https://encoding.spec.whatwg.org/#dom-textencoder-encodeinto
TextEncoderEncodeIntoResult TextEncoder::encode_into(String const& source, GC::Root<WebIDL::BufferSource> const& destination) const
{
auto& data = destination->viewed_array_buffer()->buffer();
auto data = destination->viewed_array_buffer()->buffer().bytes().slice(destination->byte_offset(), destination->byte_length());
// 1. Let read be 0.
WebIDL::UnsignedLongLong read = 0;
@ -79,7 +79,7 @@ TextEncoderEncodeIntoResult TextEncoder::encode_into(String const& source, GC::R
// 6.4. Otherwise:
// 6.4.1. If destinations byte length written is greater than or equal to the number of bytes in result, then:
if (data.size() - written >= result.size()) {
if (destination->byte_length() - written >= result.size()) {
// 6.4.1.1. If item is greater than U+FFFF, then increment read by 2.
if (item > 0xffff) {
read += 2;

View file

@ -29,6 +29,13 @@ u32 BufferableObjectBase::byte_length() const
[](GC::Ref<JS::ArrayBuffer> array_buffer) { return static_cast<u32>(array_buffer->byte_length()); });
}
u32 BufferableObjectBase::byte_offset() const
{
return m_bufferable_object.visit(
[](GC::Ref<JS::ArrayBuffer>) -> u32 { return 0; },
[](auto& view) -> u32 { return static_cast<u32>(view->byte_offset()); });
}
u32 BufferableObjectBase::element_size() const
{
return m_bufferable_object.visit(
@ -98,13 +105,6 @@ void BufferableObjectBase::visit_edges(Visitor& visitor)
ArrayBufferView::~ArrayBufferView() = default;
u32 ArrayBufferView::byte_offset() const
{
return m_bufferable_object.visit(
[](GC::Ref<JS::ArrayBuffer>) -> u32 { VERIFY_NOT_REACHED(); },
[](auto& view) -> u32 { return static_cast<u32>(view->byte_offset()); });
}
// https://webidl.spec.whatwg.org/#arraybufferview-write
void ArrayBufferView::write(ReadonlyBytes bytes, u32 starting_offset)
{

View file

@ -27,6 +27,7 @@ public:
virtual ~BufferableObjectBase() override = default;
u32 byte_length() const;
u32 byte_offset() const;
u32 element_size() const;
GC::Ref<JS::Object> raw_object();
@ -69,7 +70,6 @@ public:
using BufferableObjectBase::is_data_view;
using BufferableObjectBase::is_typed_array_base;
u32 byte_offset() const;
void write(ReadonlyBytes, u32 starting_offset = 0);
};