diff options
Diffstat (limited to 'dom/webgpu/Queue.cpp')
-rw-r--r-- | dom/webgpu/Queue.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/dom/webgpu/Queue.cpp b/dom/webgpu/Queue.cpp index 26952ee173..ca25b2f290 100644 --- a/dom/webgpu/Queue.cpp +++ b/dom/webgpu/Queue.cpp @@ -69,18 +69,36 @@ void Queue::WriteBuffer(const Buffer& aBuffer, uint64_t aBufferOffset, return; } - dom::ProcessTypedArraysFixed(aData, [&](const Span<const uint8_t>& aData) { - uint64_t length = aData.Length(); - const auto checkedSize = aSize.WasPassed() - ? CheckedInt<size_t>(aSize.Value()) - : CheckedInt<size_t>(length) - aDataOffset; - if (!checkedSize.isValid()) { + size_t elementByteSize = 1; + if (aData.IsArrayBufferView()) { + auto type = aData.GetAsArrayBufferView().Type(); + if (type != JS::Scalar::MaxTypedArrayViewType) { + elementByteSize = byteSize(type); + } + } + dom::ProcessTypedArraysFixed(aData, [&, elementByteSize]( + const Span<const uint8_t>& aData) { + uint64_t byteLength = aData.Length(); + + auto checkedByteOffset = + CheckedInt<uint64_t>(aDataOffset) * elementByteSize; + if (!checkedByteOffset.isValid()) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return; + } + auto offset = checkedByteOffset.value(); + + const auto checkedByteSize = + aSize.WasPassed() ? CheckedInt<size_t>(aSize.Value()) * elementByteSize + : CheckedInt<size_t>(byteLength) - offset; + if (!checkedByteSize.isValid()) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } + auto size = checkedByteSize.value(); - const auto& size = checkedSize.value(); - if (aDataOffset + size > length) { + auto checkedByteEnd = CheckedInt<uint64_t>(offset) + size; + if (!checkedByteEnd.isValid() || checkedByteEnd.value() > byteLength) { aRv.ThrowAbortError(nsPrintfCString("Wrong data size %" PRIuPTR, size)); return; } |