[Android] Fix dynamic Variant params stack constructions in JNI callbacks
Emitting signals with params from Android plugins could crash due to object assignment with uninitialised mem. Instead, use 'memnew_placement' to construct into stack addresses. Make similar JNI callbacks consistent. Fixes #75754.
This commit is contained in:
parent
9f12e7b52d
commit
92ade92fce
|
@ -446,39 +446,29 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en
|
|||
Object *obj = ObjectDB::get_instance(ObjectID(ID));
|
||||
ERR_FAIL_NULL(obj);
|
||||
|
||||
int res = env->PushLocalFrame(16);
|
||||
ERR_FAIL_COND(res != 0);
|
||||
|
||||
String str_method = jstring_to_string(method, env);
|
||||
|
||||
int count = env->GetArrayLength(params);
|
||||
|
||||
Variant *vlist = (Variant *)alloca(sizeof(Variant) * count);
|
||||
Variant **vptr = (Variant **)alloca(sizeof(Variant *) * count);
|
||||
const Variant **vptr = (const Variant **)alloca(sizeof(Variant *) * count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
jobject jobj = env->GetObjectArrayElement(params, i);
|
||||
Variant v;
|
||||
if (jobj) {
|
||||
v = _jobject_to_variant(env, jobj);
|
||||
}
|
||||
memnew_placement(&vlist[i], Variant);
|
||||
vlist[i] = v;
|
||||
ERR_FAIL_NULL(jobj);
|
||||
memnew_placement(&vlist[i], Variant(_jobject_to_variant(env, jobj)));
|
||||
vptr[i] = &vlist[i];
|
||||
env->DeleteLocalRef(jobj);
|
||||
}
|
||||
|
||||
Callable::CallError err;
|
||||
obj->callp(str_method, (const Variant **)vptr, count, err);
|
||||
|
||||
env->PopLocalFrame(nullptr);
|
||||
obj->callp(str_method, vptr, count, err);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params) {
|
||||
Object *obj = ObjectDB::get_instance(ObjectID(ID));
|
||||
ERR_FAIL_NULL(obj);
|
||||
|
||||
int res = env->PushLocalFrame(16);
|
||||
ERR_FAIL_COND(res != 0);
|
||||
|
||||
String str_method = jstring_to_string(method, env);
|
||||
|
||||
int count = env->GetArrayLength(params);
|
||||
|
@ -488,16 +478,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *
|
|||
|
||||
for (int i = 0; i < count; i++) {
|
||||
jobject jobj = env->GetObjectArrayElement(params, i);
|
||||
if (jobj) {
|
||||
args[i] = _jobject_to_variant(env, jobj);
|
||||
}
|
||||
env->DeleteLocalRef(jobj);
|
||||
ERR_FAIL_NULL(jobj);
|
||||
memnew_placement(&args[i], Variant(_jobject_to_variant(env, jobj)));
|
||||
argptrs[i] = &args[i];
|
||||
env->DeleteLocalRef(jobj);
|
||||
}
|
||||
|
||||
MessageQueue::get_singleton()->push_callp(obj, str_method, (const Variant **)argptrs, count);
|
||||
|
||||
env->PopLocalFrame(nullptr);
|
||||
MessageQueue::get_singleton()->push_callp(obj, str_method, argptrs, count);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jclass clazz, jstring p_permission, jboolean p_result) {
|
||||
|
|
|
@ -120,7 +120,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
|
|||
|
||||
for (int i = 0; i < count; i++) {
|
||||
jobject j_param = env->GetObjectArrayElement(j_signal_params, i);
|
||||
variant_params[i] = _jobject_to_variant(env, j_param);
|
||||
ERR_FAIL_NULL(j_param);
|
||||
memnew_placement(&variant_params[i], Variant(_jobject_to_variant(env, j_param)));
|
||||
args[i] = &variant_params[i];
|
||||
env->DeleteLocalRef(j_param);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue