[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));
|
Object *obj = ObjectDB::get_instance(ObjectID(ID));
|
||||||
ERR_FAIL_NULL(obj);
|
ERR_FAIL_NULL(obj);
|
||||||
|
|
||||||
int res = env->PushLocalFrame(16);
|
|
||||||
ERR_FAIL_COND(res != 0);
|
|
||||||
|
|
||||||
String str_method = jstring_to_string(method, env);
|
String str_method = jstring_to_string(method, env);
|
||||||
|
|
||||||
int count = env->GetArrayLength(params);
|
int count = env->GetArrayLength(params);
|
||||||
|
|
||||||
Variant *vlist = (Variant *)alloca(sizeof(Variant) * count);
|
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++) {
|
for (int i = 0; i < count; i++) {
|
||||||
jobject jobj = env->GetObjectArrayElement(params, i);
|
jobject jobj = env->GetObjectArrayElement(params, i);
|
||||||
Variant v;
|
ERR_FAIL_NULL(jobj);
|
||||||
if (jobj) {
|
memnew_placement(&vlist[i], Variant(_jobject_to_variant(env, jobj)));
|
||||||
v = _jobject_to_variant(env, jobj);
|
|
||||||
}
|
|
||||||
memnew_placement(&vlist[i], Variant);
|
|
||||||
vlist[i] = v;
|
|
||||||
vptr[i] = &vlist[i];
|
vptr[i] = &vlist[i];
|
||||||
env->DeleteLocalRef(jobj);
|
env->DeleteLocalRef(jobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
Callable::CallError err;
|
Callable::CallError err;
|
||||||
obj->callp(str_method, (const Variant **)vptr, count, err);
|
obj->callp(str_method, vptr, count, err);
|
||||||
|
|
||||||
env->PopLocalFrame(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params) {
|
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));
|
Object *obj = ObjectDB::get_instance(ObjectID(ID));
|
||||||
ERR_FAIL_NULL(obj);
|
ERR_FAIL_NULL(obj);
|
||||||
|
|
||||||
int res = env->PushLocalFrame(16);
|
|
||||||
ERR_FAIL_COND(res != 0);
|
|
||||||
|
|
||||||
String str_method = jstring_to_string(method, env);
|
String str_method = jstring_to_string(method, env);
|
||||||
|
|
||||||
int count = env->GetArrayLength(params);
|
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++) {
|
for (int i = 0; i < count; i++) {
|
||||||
jobject jobj = env->GetObjectArrayElement(params, i);
|
jobject jobj = env->GetObjectArrayElement(params, i);
|
||||||
if (jobj) {
|
ERR_FAIL_NULL(jobj);
|
||||||
args[i] = _jobject_to_variant(env, jobj);
|
memnew_placement(&args[i], Variant(_jobject_to_variant(env, jobj)));
|
||||||
}
|
|
||||||
env->DeleteLocalRef(jobj);
|
|
||||||
argptrs[i] = &args[i];
|
argptrs[i] = &args[i];
|
||||||
|
env->DeleteLocalRef(jobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue::get_singleton()->push_callp(obj, str_method, (const Variant **)argptrs, count);
|
MessageQueue::get_singleton()->push_callp(obj, str_method, argptrs, count);
|
||||||
|
|
||||||
env->PopLocalFrame(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jclass clazz, jstring p_permission, jboolean p_result) {
|
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++) {
|
for (int i = 0; i < count; i++) {
|
||||||
jobject j_param = env->GetObjectArrayElement(j_signal_params, 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];
|
args[i] = &variant_params[i];
|
||||||
env->DeleteLocalRef(j_param);
|
env->DeleteLocalRef(j_param);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue