Skip to content

Commit abb365a

Browse files
authored
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: #65415 Fixes: #65287 Reviewed-By: Paolo Insogna <paolo@cowtech.it>
1 parent a2bbe4e commit abb365a

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

src/node_ffi.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ using v8::MaybeLocal;
3535
using v8::Object;
3636
using v8::PropertyAttribute;
3737
using v8::ReadOnly;
38+
using v8::Signature;
3839
using v8::String;
3940
using v8::TryCatch;
4041
using v8::Value;
@@ -1238,16 +1239,19 @@ Local<FunctionTemplate> DynamicLibrary::GetConstructorTemplate(
12381239
tmpl = NewFunctionTemplate(isolate, DynamicLibrary::New);
12391240
tmpl->InstanceTemplate()->SetInternalFieldCount(
12401241
DynamicLibrary::kInternalFieldCount);
1242+
Local<Signature> signature = Signature::New(isolate, tmpl);
12411243

12421244
tmpl->InstanceTemplate()->SetAccessorProperty(
12431245
env->path_string(),
1244-
FunctionTemplate::New(env->isolate(), DynamicLibrary::GetPath),
1246+
FunctionTemplate::New(
1247+
isolate, DynamicLibrary::GetPath, Local<Value>(), signature),
12451248
Local<FunctionTemplate>(),
12461249
attributes);
12471250

12481251
tmpl->InstanceTemplate()->SetAccessorProperty(
12491252
FIXED_ONE_BYTE_STRING(isolate, "symbols"),
1250-
FunctionTemplate::New(env->isolate(), DynamicLibrary::GetSymbols),
1253+
FunctionTemplate::New(
1254+
isolate, DynamicLibrary::GetSymbols, Local<Value>(), signature),
12511255
Local<FunctionTemplate>(),
12521256
attributes);
12531257

@@ -1257,7 +1261,8 @@ Local<FunctionTemplate> DynamicLibrary::GetConstructorTemplate(
12571261
// reason.
12581262
tmpl->PrototypeTemplate()->SetAccessorProperty(
12591263
FIXED_ONE_BYTE_STRING(isolate, "functions"),
1260-
FunctionTemplate::New(env->isolate(), DynamicLibrary::GetFunctions),
1264+
FunctionTemplate::New(
1265+
isolate, DynamicLibrary::GetFunctions, Local<Value>(), signature),
12611266
Local<FunctionTemplate>(),
12621267
static_cast<PropertyAttribute>(ReadOnly));
12631268

test/ffi/test-ffi-dynamic-library.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,24 @@ test('DynamicLibrary exposes functions and symbols', () => {
124124
}
125125
});
126126

127+
test('DynamicLibrary getters reject incompatible receivers', () => {
128+
const lib = new ffi.DynamicLibrary(libraryPath);
129+
130+
try {
131+
const invalidGets = [
132+
() => Reflect.get(lib, 'path', {}),
133+
() => Reflect.get(lib, 'symbols', {}),
134+
() => Reflect.get(ffi.DynamicLibrary.prototype, 'functions', {}),
135+
];
136+
137+
for (const invalidGet of invalidGets) {
138+
assert.throws(invalidGet, TypeError);
139+
}
140+
} finally {
141+
lib.close();
142+
}
143+
});
144+
127145
test('DynamicLibrary evaluates function signatures once', () => {
128146
function makeChangingSignature() {
129147
const reads = { arguments: 0, return: 0 };

0 commit comments

Comments
 (0)