ffi: validate DynamicLibrary getter receivers

Bind the path, symbols, and functions getter templates to the
DynamicLibrary constructor signature. This causes V8 to reject
incompatible receivers before invoking the native callbacks,
preventing them from crashing the process.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: codex:gpt-5.6-sol
PR-URL: https://github.com/nodejs/node/pull/65415
Fixes: https://github.com/nodejs/node/issues/65287
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
This commit is contained in:
Trivikram Kamat authored and GitHub committed 2026-08-27 07:00:51 +00:00
1 parent a2bbe4e39f
commit abb365abea
2 files changed
+26 -3

No files matched your search

+8 -3
View File
@@ -35,6 +35,7 @@ using v8::MaybeLocal;
using v8::Object;
using v8::PropertyAttribute;
using v8::ReadOnly;
using v8::Signature;
using v8::String;
using v8::TryCatch;
using v8::Value;
@@ -1238,16 +1239,19 @@ Local<FunctionTemplate> DynamicLibrary::GetConstructorTemplate(
tmpl = NewFunctionTemplate(isolate, DynamicLibrary::New);
tmpl->InstanceTemplate()->SetInternalFieldCount(
DynamicLibrary::kInternalFieldCount);
Local<Signature> signature = Signature::New(isolate, tmpl);
tmpl->InstanceTemplate()->SetAccessorProperty(
env->path_string(),
FunctionTemplate::New(env->isolate(), DynamicLibrary::GetPath),
FunctionTemplate::New(
isolate, DynamicLibrary::GetPath, Local<Value>(), signature),
Local<FunctionTemplate>(),
attributes);
tmpl->InstanceTemplate()->SetAccessorProperty(
FIXED_ONE_BYTE_STRING(isolate, "symbols"),
FunctionTemplate::New(env->isolate(), DynamicLibrary::GetSymbols),
FunctionTemplate::New(
isolate, DynamicLibrary::GetSymbols, Local<Value>(), signature),
Local<FunctionTemplate>(),
attributes);
@@ -1257,7 +1261,8 @@ Local<FunctionTemplate> DynamicLibrary::GetConstructorTemplate(
// reason.
tmpl->PrototypeTemplate()->SetAccessorProperty(
FIXED_ONE_BYTE_STRING(isolate, "functions"),
FunctionTemplate::New(env->isolate(), DynamicLibrary::GetFunctions),
FunctionTemplate::New(
isolate, DynamicLibrary::GetFunctions, Local<Value>(), signature),
Local<FunctionTemplate>(),
static_cast<PropertyAttribute>(ReadOnly));
+18
View File
@@ -124,6 +124,24 @@ test('DynamicLibrary exposes functions and symbols', () => {
}
});
test('DynamicLibrary getters reject incompatible receivers', () => {
const lib = new ffi.DynamicLibrary(libraryPath);
try {
const invalidGets = [
() => Reflect.get(lib, 'path', {}),
() => Reflect.get(lib, 'symbols', {}),
() => Reflect.get(ffi.DynamicLibrary.prototype, 'functions', {}),
];
for (const invalidGet of invalidGets) {
assert.throws(invalidGet, TypeError);
}
} finally {
lib.close();
}
});
test('DynamicLibrary evaluates function signatures once', () => {
function makeChangingSignature() {
const reads = { arguments: 0, return: 0 };