From 4c337ff06d5cbb817b657eea98502952b67679b1 Mon Sep 17 00:00:00 2001 From: Greg Pomerantz Date: Fri, 21 Aug 2026 15:29:24 -0400 Subject: [PATCH] Guard the JNI fragment registration against the null detach view. Gio's GioView.onDestroyView signals detach with ViewEvent{View: 0}; handleEvent already filters these, but add defense in depth so any caller forwarding the event unfiltered cannot drive the JNI path (GetObjectClass on a null ref aborts the process, the recents-wipe SIGABRT). Completes the intent of PR #1, whose handleEvent guard is already in master from the migration commit. Fixes: recents-wipe crash defense (PR #1 superseded). --- impl_android.go | 6 ++++++ jni_android.c | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/impl_android.go b/impl_android.go index dc5b806..e4bf256 100644 --- a/impl_android.go +++ b/impl_android.go @@ -51,6 +51,9 @@ func Java_st_wow_git_passgo_PgpConnect_installComplete(env *C.JNIEnv, class C.jc func InitPgp(view uintptr) { log.Printf("InitPgp()") + if view == 0 { + return // detach signal; nothing to register + } jvm = app.JavaVM() SetJVM(jvm) // why? RunInJVM(func(env *JNIEnv) { @@ -63,6 +66,9 @@ func InitPgp(view uintptr) { // screen on Android 11+) so the app can read the store in shared storage. func InitPermissions(view uintptr) { log.Printf("InitPermissions()") + if view == 0 { + return // detach signal; nothing to register + } RunInJVM(func(env *JNIEnv) { C.registerPermissionsFragment(env, (C.jobject)(unsafe.Pointer(view))) }) diff --git a/jni_android.c b/jni_android.c index 3a37a05..ce807b2 100644 --- a/jni_android.c +++ b/jni_android.c @@ -7,6 +7,12 @@ void registerFragment(JNIEnv *env, jobject view) { + if (view == NULL) { + // Detach signal (Gio sends ViewEvent{View: 0} when the view is + // destroyed, e.g. on a recents-wipe); the Go side already + // filters these, but GetObjectClass(null) aborts the process. + return; + } jclass cls = (*env)->GetObjectClass(env, view); jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;"); jobject ctx = (*env)->CallObjectMethod(env, view, mid); @@ -23,6 +29,9 @@ registerFragment(JNIEnv *env, jobject view) { void registerPermissionsFragment(JNIEnv *env, jobject view) { + if (view == NULL) { + return; // detach signal; see registerFragment + } jclass cls = (*env)->GetObjectClass(env, view); jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;"); jobject ctx = (*env)->CallObjectMethod(env, view, mid);