fix(ext/node): mark pool ArrayBuffer as untransferable (#29612)

Enables `parallel/test-buffer-pool-untransferable.js`

Towards https://github.com/denoland/deno/issues/29589
This commit is contained in:
Divy Srivastava 2025-06-04 23:14:48 -07:00 committed by GitHub
parent 97a38fa584
commit 104084876c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 56 additions and 2 deletions

View file

@ -99,6 +99,7 @@ import {
} from "ext:deno_web/00_infra.js";
import { atob, btoa } from "ext:deno_web/05_base64.js";
import { Blob } from "ext:deno_web/09_file.js";
import { untransferableSymbol } from "ext:deno_node/internal_binding/util.ts";
export { atob, Blob, btoa };
@ -244,6 +245,7 @@ function createPool() {
poolSize = Buffer.poolSize;
allocBuffer = new Uint8Array(poolSize);
allocPool = TypedArrayPrototypeGetBuffer(allocBuffer);
allocPool[untransferableSymbol] = true;
poolOffset = 0;
}
createPool();

View file

@ -137,3 +137,7 @@ export function arrayBufferViewHasBuffer(
): boolean {
return op_node_view_has_buffer(view);
}
export const untransferableSymbol = Symbol.for(
"nodejs.worker_threads.untransferable",
);

View file

@ -27,6 +27,7 @@ import * as webidl from "ext:deno_webidl/00_webidl.js";
import { notImplemented } from "ext:deno_node/_utils.ts";
import { EventEmitter } from "node:events";
import { BroadcastChannel } from "ext:deno_broadcast_channel/01_broadcast_channel.js";
import { untransferableSymbol } from "ext:deno_node/internal_binding/util.ts";
import process from "node:process";
const { JSONParse, JSONStringify, ObjectPrototypeIsPrototypeOf } = primordials;
@ -34,6 +35,7 @@ const {
Error,
ObjectHasOwn,
PromiseResolve,
FunctionPrototypeCall,
SafeSet,
Symbol,
SymbolFor,
@ -579,6 +581,22 @@ function webMessagePortToNodeMessagePort(port: MessagePort) {
port.ref = () => {
port[refMessagePort](true);
};
const webPostMessage = port.postMessage;
port.postMessage = (message, transferList) => {
for (let i = 0; i < transferList?.length; i++) {
const item = transferList[i];
if (item[untransferableSymbol] === true) {
throw new DOMException("Value not transferable", "DataCloneError");
}
}
return FunctionPrototypeCall(
webPostMessage,
port,
message,
transferList,
);
};
port.once = (name: string | symbol, listener) => {
const fn = (event) => {
port.off(name, fn);

View file

@ -303,6 +303,7 @@
"test-buffer-over-max-length.js",
"test-buffer-parent-property.js",
"test-buffer-pending-deprecation.js",
"test-buffer-pool-untransferable.js",
"test-buffer-read.js",
"test-buffer-readdouble.js",
"test-buffer-readfloat.js",

View file

@ -1,7 +1,7 @@
<!-- deno-fmt-ignore-file -->
# Remaining Node Tests
1191 tests out of 3993 have been ported from Node 23.9.0 (29.83% ported, 70.77% remaining).
1192 tests out of 3993 have been ported from Node 23.9.0 (29.85% ported, 70.75% remaining).
NOTE: This file should not be manually edited. Please edit `tests/node_compat/config.json` and run `deno task setup` in `tests/node_compat/runner` dir instead.
@ -285,7 +285,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co
- [parallel/test-buffer-constructor-node-modules-paths.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-buffer-constructor-node-modules-paths.js)
- [parallel/test-buffer-fill.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-buffer-fill.js)
- [parallel/test-buffer-inspect.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-buffer-inspect.js)
- [parallel/test-buffer-pool-untransferable.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-buffer-pool-untransferable.js)
- [parallel/test-buffer-prototype-inspect.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-buffer-prototype-inspect.js)
- [parallel/test-c-ares.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-c-ares.js)
- [parallel/test-child-process-advanced-serialization-largebuffer.js](https://github.com/nodejs/node/tree/v23.9.0/test/parallel/test-child-process-advanced-serialization-largebuffer.js)

View file

@ -0,0 +1,30 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 23.9.0
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
require('../common');
const assert = require('assert');
const { MessageChannel } = require('worker_threads');
// Make sure that the pools used by the Buffer implementation are not
// transferable.
// Refs: https://github.com/nodejs/node/issues/32752
const a = Buffer.from('hello world');
const b = Buffer.from('hello world');
assert.strictEqual(a.buffer, b.buffer);
const length = a.length;
const { port1 } = new MessageChannel();
assert.throws(() => port1.postMessage(a, [ a.buffer ]), {
code: 25,
name: 'DataCloneError',
});
// Verify that the pool ArrayBuffer has not actually been transferred:
assert.strictEqual(a.buffer, b.buffer);
assert.strictEqual(a.length, length);