Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle failure in ffi_closure_alloc #1378

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -11,6 +11,7 @@ Features

Bug Fixes
---------
* [#1378](https://github.com/java-native-access/jna/pull/1378): Handle failure in `ffi_closure_alloc` - [@davecturner](https://github.com/davecturner).


Release 5.9.0
Expand Down
20 changes: 20 additions & 0 deletions native/dispatch.c
Expand Up @@ -3466,6 +3466,11 @@ Java_com_sun_jna_Native_registerMethod(JNIEnv *env, jclass UNUSED(ncls),
}

closure = ffi_closure_alloc(sizeof(ffi_closure), &code);
if (closure == NULL) {
throwByName(env, EUnsupportedOperation, "Failed to allocate closure");
status = FFI_BAD_ABI;
goto cleanup;
}
status = ffi_prep_closure_loc(closure, closure_cif, dispatch_direct, data, code);
if (status != FFI_OK) {
throwByName(env, EError, "Native method linkage failed");
Expand Down Expand Up @@ -3514,16 +3519,31 @@ Java_com_sun_jna_Native_ffi_1prep_1closure(JNIEnv *env, jclass UNUSED(cls), jlon
ffi_status s;

if ((*env)->GetJavaVM(env, &cb->vm) != JNI_OK) {
free(cb);
throwByName(env, EUnsatisfiedLink, "Can't get Java VM");
return 0;
}

cb->object = (*env)->NewWeakGlobalRef(env, obj);
if (cb->object == NULL) {
// either obj was null or an OutOfMemoryError has been thrown
free(cb);
return 0;
}
cb->closure = ffi_closure_alloc(sizeof(ffi_closure), L2A(&cb->x_closure));
if (cb->closure == NULL) {
(*env)->DeleteWeakGlobalRef(env, cb->object);
free(cb);
dbwiddis marked this conversation as resolved.
Show resolved Hide resolved
throwByName(env, EUnsupportedOperation, "Failed to allocate closure");
return 0;
}

s = ffi_prep_closure_loc(cb->closure, L2A(cif), &closure_handler,
cb, cb->x_closure);
if (ffi_error(env, "ffi_prep_cif", s)) {
ffi_closure_free(cb->closure);
(*env)->DeleteWeakGlobalRef(env, cb->object);
free(cb);
return 0;
}
return A2L(cb);
Expand Down