Skip to content

Commit c5ff7c4

Browse files
legendecasV8 LUCI CQ
authored andcommitted
[builtins] disallow ArrayBuffer transfer with a detach key
This allows embedder to disallow `ArrayBuffer.prototype.transfer()` on an arraybuffer that is not detachable. This also fix the check on `ArrayBufferCopyAndDetach` step 8 of `ArrayBuffer.prototype.transfer`. Refs: nodejs/node#61362 Refs: https://tc39.es/ecma262/#sec-arraybuffercopyanddetach Change-Id: I3c6e156a8fad007fd100218d8b16aed5c4e1db68 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7454288 Commit-Queue: Chengzhong Wu <[email protected]> Reviewed-by: Olivier Flückiger <[email protected]> Cr-Commit-Position: refs/heads/main@{#104697}
1 parent 11a8ddd commit c5ff7c4

4 files changed

Lines changed: 65 additions & 1 deletion

File tree

src/builtins/builtins-arraybuffer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,8 @@ Tagged<Object> ArrayBufferTransfer(Isolate* isolate,
715715
// 8. If arrayBuffer.[[ArrayBufferDetachKey]] is not undefined, throw a
716716
// TypeError exception.
717717

718-
if (!array_buffer->is_detachable()) {
718+
if (!IsUndefined(array_buffer->detach_key()) ||
719+
!array_buffer->is_detachable()) {
719720
THROW_NEW_ERROR_RETURN_FAILURE(
720721
isolate,
721722
NewTypeError(MessageTemplate::kDataCloneErrorNonDetachableArrayBuffer));
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2026 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
//
5+
// Flags: --allow-natives-syntax
6+
7+
function TestTransferSucceeds() {
8+
const ab = new ArrayBuffer(100);
9+
%ArrayBufferSetDetachKey(ab, undefined);
10+
ab.transfer();
11+
assertEquals(0, ab.byteLength); // Detached.
12+
}
13+
14+
function TestTransferFails() {
15+
const ab = new ArrayBuffer(100);
16+
%ArrayBufferSetDetachKey(ab, Symbol());
17+
assertThrows(() => { ab.transfer(); }, TypeError);
18+
assertEquals(100, ab.byteLength); // Not detached.
19+
}
20+
21+
TestTransferSucceeds();
22+
TestTransferFails();

test/unittests/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ v8_source_set("v8_unittests_sources") {
263263
"api/remote-object-unittest.cc",
264264
"api/resource-constraints-unittest.cc",
265265
"api/smi-tagging-unittest.cc",
266+
"api/v8-array-buffer-unittest.cc",
266267
"api/v8-array-unittest.cc",
267268
"api/v8-maybe-unittest.cc",
268269
"api/v8-memory-span-unittest.cc",
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2026 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "include/v8-array-buffer.h"
6+
7+
#include "test/unittests/test-utils.h"
8+
#include "testing/gtest/include/gtest/gtest.h"
9+
10+
namespace v8 {
11+
namespace {
12+
13+
using ArrayBufferTest = TestWithContext;
14+
15+
TEST_F(ArrayBufferTest, TransferWithDetachKey) {
16+
Local<ArrayBuffer> ab = ArrayBuffer::New(isolate(), 1);
17+
Local<Value> key = Symbol::New(isolate());
18+
ab->SetDetachKey(key);
19+
Local<Object> global = context()->Global();
20+
Local<String> property_name =
21+
String::NewFromUtf8Literal(isolate(), "test_ab");
22+
global->Set(context(), property_name, ab).ToChecked();
23+
24+
{
25+
TryCatch try_catch(isolate());
26+
CHECK(TryRunJS("globalThis.test_ab.transfer()").IsEmpty());
27+
}
28+
29+
// Didnot transfer.
30+
EXPECT_EQ(ab->ByteLength(), 1u);
31+
32+
ab->SetDetachKey(Undefined(isolate()));
33+
RunJS("globalThis.test_ab.transfer()");
34+
35+
// Transferred.
36+
EXPECT_EQ(ab->ByteLength(), 0u);
37+
}
38+
39+
} // namespace
40+
} // namespace v8

0 commit comments

Comments
 (0)