From fd64fa4ccc6aedb76cc856834d4fd89ab347a19f Mon Sep 17 00:00:00 2001 From: Daeyeon Jeong Date: Sun, 19 Apr 2026 18:36:27 +0900 Subject: [PATCH] stream: reject duplicate nested transferables Signed-off-by: Daeyeon Jeong --- src/node_messaging.cc | 9 +++++++-- ...twg-webstreams-transform-stream-members.js | 19 +++++++++++++++++++ test/wpt/status/streams.json | 8 -------- 3 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 test/parallel/test-whatwg-webstreams-transform-stream-members.js diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 72e807a1c04de5..f00ab803fef089 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -415,10 +415,15 @@ class SerializerDelegate : public ValueSerializer::Delegate { if (!host_objects_[i]->NestedTransferables().To(&nested_transferables)) return Nothing(); for (auto& nested_transferable : nested_transferables) { - if (std::ranges::find(host_objects_, nested_transferable) == + if (std::ranges::find(host_objects_, nested_transferable) != host_objects_.end()) { - AddHostObject(nested_transferable); + ThrowDataCloneException( + context_, + FIXED_ONE_BYTE_STRING(env_->isolate(), + "The transfer list is invalid.")); + return Nothing(); } + AddHostObject(nested_transferable); } } return Just(true); diff --git a/test/parallel/test-whatwg-webstreams-transform-stream-members.js b/test/parallel/test-whatwg-webstreams-transform-stream-members.js new file mode 100644 index 00000000000000..90a935683053d4 --- /dev/null +++ b/test/parallel/test-whatwg-webstreams-transform-stream-members.js @@ -0,0 +1,19 @@ +'use strict'; + +require('../common'); +const assert = require('node:assert'); + +const combinations = [ + ((t) => [t, t.readable])(new TransformStream()), + ((t) => [t.readable, t])(new TransformStream()), + ((t) => [t, t.writable])(new TransformStream()), + ((t) => [t.writable, t])(new TransformStream()), +]; + +for (const combination of combinations) { + assert.throws(() => structuredClone(combination, { transfer: combination }), { + constructor: DOMException, + name: 'DataCloneError', + code: 25, + }); +} diff --git a/test/wpt/status/streams.json b/test/wpt/status/streams.json index 222a68014f4af6..968b3359765189 100644 --- a/test/wpt/status/streams.json +++ b/test/wpt/status/streams.json @@ -41,14 +41,6 @@ "transferable/transfer-with-messageport.window.js": { "skip": "Browser-specific test" }, - "transferable/transform-stream-members.any.js": { - "fail": { - "expected": [ - "Transferring [object TransformStream],[object ReadableStream] should fail", - "Transferring [object TransformStream],[object WritableStream] should fail" - ] - } - }, "transform-streams/invalid-realm.tentative.window.js": { "skip": "Browser-specific test" }