summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/Queue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/webgpu/Queue.cpp')
-rw-r--r--dom/webgpu/Queue.cpp34
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;
}