Skip to content

Commit

Permalink
JBR-5536: Crash on macOS bad JNI lookup in Java_sun_swing_AccessibleA…
Browse files Browse the repository at this point in the history
…nnouncer_nativeAnnounce

Stop using the JNIEnv instance bound to EDT in the AppKit thread.
  • Loading branch information
NikitkoCent committed Apr 14, 2023
1 parent 01bff53 commit 0f49341
Showing 1 changed file with 43 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,9 @@ - (BOOL)accessibilityPerformIncrement {
JNI_COCOA_EXIT(env);
}


static void nativeAnnounceAppKit(jobject jAccessible, NSString *text, NSNumber *javaPriority);

/*
* Class: sun_swing_AccessibleAnnouncer
* Method: nativeAnnounce
Expand All @@ -1360,31 +1363,50 @@ - (BOOL)accessibilityPerformIncrement {
{
JNI_COCOA_ENTER(env);

NSString *text = JavaStringToNSString(env, str);
NSNumber *javaPriority = [NSNumber numberWithInt:priority];
NSString *text = JavaStringToNSString(env, str);
NSNumber *javaPriority = [NSNumber numberWithInt:priority];

[ThreadUtilities performOnMainThreadWaiting:YES block:^{
[ThreadUtilities performOnMainThreadWaiting:YES block:^{
nativeAnnounceAppKit(jAccessible, text, javaPriority);
}];

id caller = nil;
JNI_COCOA_EXIT(env);
}

DECLARE_CLASS(jc_Accessible, "javax/accessibility/Accessible");
void nativeAnnounceAppKit(
const jobject jAccessible,
NSString * const text,
NSNumber * const javaPriority
) {
AWT_ASSERT_APPKIT_THREAD;
assert((text != NULL));
assert((javaPriority != NULL));

if ((jAccessible != NULL) && (*env)->IsInstanceOf(env, jAccessible, jc_Accessible)) {
GET_CACCESSIBLE_CLASS();
DECLARE_FIELD(jf_ptr, sjc_CAccessible, "ptr", "J");
// try to fetch the jCAX from Java, and return autoreleased
jobject jCAX = [CommonComponentAccessibility getCAccessible:jAccessible withEnv:env];
if (jCAX != NULL) {
caller = (CommonComponentAccessibility *) jlong_to_ptr((*env)->GetLongField(env, jCAX, jf_ptr));
(*env)->DeleteLocalRef(env, jCAX);
}
}
JNIEnv *env = [ThreadUtilities getJNIEnv];
if (env == NULL) { // unlikely
NSLog(@"%s: failed to get JNIEnv instance\n%@\n", __func__, [NSThread callStackSymbols]);
return;
}

if (caller == nil) {
caller = [NSApp accessibilityFocusedUIElement];
}
id caller = nil;

[CommonComponentAccessibility postAnnounceWithCaller:caller andText:text andPriority:javaPriority];
}];
JNI_COCOA_EXIT(env);
DECLARE_CLASS(jc_Accessible, "javax/accessibility/Accessible");

if ( (jAccessible != NULL) && ((*env)->IsInstanceOf(env, jAccessible, jc_Accessible) == JNI_TRUE) ) {
GET_CACCESSIBLE_CLASS();
DECLARE_FIELD(jf_ptr, sjc_CAccessible, "ptr", "J");

// try to fetch the jCAX from Java, and return autoreleased
const jobject jCAX = [CommonComponentAccessibility getCAccessible:jAccessible withEnv:env];
if (jCAX != NULL) {
caller = (CommonComponentAccessibility*)jlong_to_ptr((*env)->GetLongField(env, jCAX, jf_ptr));
(*env)->DeleteLocalRef(env, jCAX);
}
}

if (caller == nil) {
caller = [NSApp accessibilityFocusedUIElement];
}

[CommonComponentAccessibility postAnnounceWithCaller:caller andText:text andPriority:javaPriority];
}

0 comments on commit 0f49341

Please sign in to comment.