mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
ffi: reject non-boolean copy arguments
ffi.toBuffer() and ffi.toArrayBuffer() document copy as a boolean, but read it with BooleanValue(), which applies JavaScript truthiness. A falsy non-boolean such as null, 0 or '' therefore selects the zero-copy mode, which returns a writable view over foreign memory instead of a copy, while values such as 'false' or 1 select a copy. Throw ERR_INVALID_ARG_TYPE when copy is neither undefined nor a boolean. Omitting copy or passing undefined still makes a copy, and true and false keep their current behavior. Signed-off-by: Christian Aurich Zanettini Martins <christian.aurichzm@gmail.com> PR-URL: https://github.com/nodejs/node/pull/66219 Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
This commit is contained in:
1 parent
118f2a1d78
commit
63a6ea26bb
2 files changed
+24
-5
No files matched your search
+12
-5
@@ -546,7 +546,6 @@ static bool ZeroCopyUnavailable(Environment* env) {
|
||||
|
||||
void ToBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
Isolate* isolate = env->isolate();
|
||||
|
||||
THROW_IF_INSUFFICIENT_PERMISSIONS(env, permission::PermissionScope::kFFI, "");
|
||||
|
||||
@@ -589,8 +588,12 @@ void ToBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool copy = args.Length() < 3 || args[2]->IsUndefined() ||
|
||||
args[2]->BooleanValue(isolate);
|
||||
if (!args[2]->IsUndefined() && !args[2]->IsBoolean()) {
|
||||
THROW_ERR_INVALID_ARG_TYPE(env, "The copy argument must be a boolean");
|
||||
return;
|
||||
}
|
||||
|
||||
bool copy = !args[2]->IsFalse();
|
||||
if (!copy && ZeroCopyUnavailable(env)) return;
|
||||
|
||||
Local<Object> buf;
|
||||
@@ -654,8 +657,12 @@ void ToArrayBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool copy = args.Length() < 3 || args[2]->IsUndefined() ||
|
||||
args[2]->BooleanValue(isolate);
|
||||
if (!args[2]->IsUndefined() && !args[2]->IsBoolean()) {
|
||||
THROW_ERR_INVALID_ARG_TYPE(env, "The copy argument must be a boolean");
|
||||
return;
|
||||
}
|
||||
|
||||
bool copy = !args[2]->IsFalse();
|
||||
if (!copy && ZeroCopyUnavailable(env)) return;
|
||||
|
||||
Local<ArrayBuffer> ab;
|
||||
|
||||
@@ -132,6 +132,18 @@ test('ffi zero-copy views throw with the V8 sandbox', { skip: !common.hasV8Sandb
|
||||
}));
|
||||
});
|
||||
|
||||
test('ffi toBuffer and toArrayBuffer require a boolean copy argument', () => {
|
||||
withAllocations(common.mustCall((alloc) => {
|
||||
const ptr = alloc(4);
|
||||
const type = { code: 'ERR_INVALID_ARG_TYPE' };
|
||||
|
||||
for (const copy of [null, 0, '', 'false', 1, {}]) {
|
||||
assert.throws(() => ffi.toBuffer(ptr, 4, copy), type);
|
||||
assert.throws(() => ffi.toArrayBuffer(ptr, 4, copy), type);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
test('ffi getRawPointer returns raw addresses for byte sources', () => {
|
||||
const buffer = Buffer.from([1, 2, 3]);
|
||||
const arrayBuffer = new Uint8Array([4, 5, 6, 7]).buffer;
|
||||
|
||||
Reference in new issue
Block a user