Skip to content

Commit 0e2cbe6

Browse files
addaleaxtargos
authored andcommitted
worker: fix passing multiple SharedArrayBuffers at once
V8 has a handle scope below each `GetSharedArrayBufferId()` call, so using a `v8::Local` that outlives that handle scope to store references to `SharedArrayBuffer`s is invalid and may cause accidental de-duplication of passed `SharedArrayBuffer`s. Use a persistent handle instead to address this issue. Fixes: #28559 PR-URL: #28582 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent 70c3116 commit 0e2cbe6

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/node_messaging.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ using v8::Exception;
1919
using v8::Function;
2020
using v8::FunctionCallbackInfo;
2121
using v8::FunctionTemplate;
22+
using v8::Global;
2223
using v8::HandleScope;
2324
using v8::Isolate;
2425
using v8::Just;
@@ -241,8 +242,10 @@ class SerializerDelegate : public ValueSerializer::Delegate {
241242
Local<SharedArrayBuffer> shared_array_buffer) override {
242243
uint32_t i;
243244
for (i = 0; i < seen_shared_array_buffers_.size(); ++i) {
244-
if (seen_shared_array_buffers_[i] == shared_array_buffer)
245+
if (PersistentToLocal::Strong(seen_shared_array_buffers_[i]) ==
246+
shared_array_buffer) {
245247
return Just(i);
248+
}
246249
}
247250

248251
auto reference = SharedArrayBufferMetadata::ForSharedArrayBuffer(
@@ -252,7 +255,8 @@ class SerializerDelegate : public ValueSerializer::Delegate {
252255
if (!reference) {
253256
return Nothing<uint32_t>();
254257
}
255-
seen_shared_array_buffers_.push_back(shared_array_buffer);
258+
seen_shared_array_buffers_.emplace_back(
259+
Global<SharedArrayBuffer> { isolate, shared_array_buffer });
256260
msg_->AddSharedArrayBuffer(reference);
257261
return Just(i);
258262
}
@@ -289,7 +293,7 @@ class SerializerDelegate : public ValueSerializer::Delegate {
289293
Environment* env_;
290294
Local<Context> context_;
291295
Message* msg_;
292-
std::vector<Local<SharedArrayBuffer>> seen_shared_array_buffers_;
296+
std::vector<Global<SharedArrayBuffer>> seen_shared_array_buffers_;
293297
std::vector<MessagePort*> ports_;
294298

295299
friend class worker::Message;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { MessageChannel } = require('worker_threads');
5+
6+
// Regression test for https://github.com/nodejs/node/issues/28559
7+
8+
const obj = [
9+
[ new SharedArrayBuffer(0), new SharedArrayBuffer(1) ],
10+
[ new SharedArrayBuffer(2), new SharedArrayBuffer(3) ]
11+
];
12+
13+
const { port1, port2 } = new MessageChannel();
14+
port1.once('message', common.mustCall((message) => {
15+
assert.deepStrictEqual(message, obj);
16+
}));
17+
port2.postMessage(obj);

0 commit comments

Comments
 (0)