commit 77f736a623f12eb22e6c92e595deff767ec626b1
parent dfebe2194e084339e278009e2a7ae76e4d2b8c77
Author: pommicket <pommicket@gmail.com>
Date: Thu, 23 Oct 2025 12:00:11 +0000
Bug 1995659 - Fix handling of duplicate transfer ArrayBuffers in ImageDecoder r=aosmond
Differential Revision: https://phabricator.services.mozilla.com/D269505
Diffstat:
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/dom/media/webcodecs/ImageDecoder.cpp b/dom/media/webcodecs/ImageDecoder.cpp
@@ -497,11 +497,11 @@ void ImageDecoder::CheckOutstandingDecodes() {
return nullptr;
}
- nsTHashSet<const ArrayBuffer*> transferSet;
+ nsTHashSet<const JSObject*> transferSet;
for (const auto& buffer : aInit.mTransfer) {
// 10.2.2.2. If init.transfer contains more than one reference to the same
// ArrayBuffer, then throw a DataCloneError DOMException.
- if (transferSet.Contains(&buffer)) {
+ if (transferSet.Contains(buffer.Obj())) {
MOZ_LOG(
gWebCodecsLog, LogLevel::Error,
("ImageDecoder Constructor -- duplicate transferred ArrayBuffer"));
@@ -509,7 +509,7 @@ void ImageDecoder::CheckOutstandingDecodes() {
"Transfer contains duplicate ArrayBuffer objects");
return nullptr;
}
- transferSet.Insert(&buffer);
+ transferSet.Insert(buffer.Obj());
// 10.2.2.3.1. If [[Detached]] internal slot is true, then throw a
// DataCloneError DOMException.
bool empty = buffer.ProcessData(
diff --git a/testing/web-platform/tests/webcodecs/transfering.https.any.js b/testing/web-platform/tests/webcodecs/transfering.https.any.js
@@ -168,7 +168,7 @@ promise_test(async t => {
}
// `data.buffer` didn't get detached
assert_equals(data.length, 16, 'data.length');
-}, 'Test transfering same array buffer twice');
+}, 'Test transfering same array buffer twice to VideoFrame');
promise_test(async t => {
const bytes = [ 0xBA, 0xDF, 0x00, 0xD0, 0xBA, 0xDF, 0x01, 0xD0, 0xBA, 0xDF ];
@@ -317,3 +317,18 @@ promise_test(async t => {
assert_equals(result.image.displayWidth, 320);
assert_equals(result.image.displayHeight, 240);
}, 'Test transfering ArrayBuffer to ImageDecoder.');
+
+promise_test(async t => {
+ // Not a valid PNG but that shouldn't matter.
+ let arraybuffer = new ArrayBuffer(16);
+ let data = new Uint8Array(arraybuffer);
+ let init = {
+ type: 'image/png',
+ data: data,
+ transfer: [arraybuffer, arraybuffer]
+ };
+
+ assert_throws_dom('DataCloneError', () => new ImageDecoder(init));
+ // `data.buffer` didn't get detached
+ assert_equals(data.length, 16, 'data.length');
+}, 'Test transfering same array buffer twice to ImageDecoder');