1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Merge pull request #110452 from limbonaut/prevent-jni-variant-conv-stack-overflow

Prevent JNI Variant conversion stack overflow
This commit is contained in:
Thaddeus Crews
2025-09-19 09:17:05 -05:00
2 changed files with 17 additions and 9 deletions

View File

@@ -86,9 +86,15 @@ String charsequence_to_string(JNIEnv *p_env, jobject p_charsequence) {
return result;
}
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject) {
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject, int p_depth) {
jvalret v;
if (p_depth > Variant::MAX_RECURSION_DEPTH) {
ERR_PRINT("Variant is too deep! Bailing.");
v.val.i = 0;
return v;
}
switch (p_type) {
case Variant::BOOL: {
if (force_jobject) {
@@ -185,7 +191,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
for (int j = 0; j < keys.size(); j++) {
Variant var = dict[keys[j]];
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true);
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true, p_depth + 1);
env->SetObjectArrayElement(jvalues, j, valret.val.l);
if (valret.obj) {
env->DeleteLocalRef(valret.obj);
@@ -208,7 +214,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
for (int j = 0; j < array.size(); j++) {
Variant var = array[j];
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true);
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true, p_depth + 1);
env->SetObjectArrayElement(arr, j, valret.val.l);
if (valret.obj) {
env->DeleteLocalRef(valret.obj);
@@ -297,7 +303,9 @@ String _get_class_name(JNIEnv *env, jclass cls, bool *array) {
return name;
}
Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
Variant _jobject_to_variant(JNIEnv *env, jobject obj, int p_depth) {
ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, Variant(), "Variant is too deep! Bailing.");
if (obj == nullptr) {
return Variant();
}
@@ -434,7 +442,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
for (int i = 0; i < objCount; i++) {
jobject jobj = env->GetObjectArrayElement(arr, i);
Variant v = _jobject_to_variant(env, jobj);
Variant v = _jobject_to_variant(env, jobj, p_depth + 1);
varr.push_back(v);
env->DeleteLocalRef(jobj);
}
@@ -448,13 +456,13 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;");
jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys);
PackedStringArray keys = _jobject_to_variant(env, arr);
PackedStringArray keys = _jobject_to_variant(env, arr, p_depth + 1);
env->DeleteLocalRef(arr);
jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;");
arr = (jobjectArray)env->CallObjectMethod(obj, get_values);
Array vals = _jobject_to_variant(env, arr);
Array vals = _jobject_to_variant(env, arr, p_depth + 1);
env->DeleteLocalRef(arr);
for (int i = 0; i < keys.size(); i++) {

View File

@@ -44,11 +44,11 @@ struct jvalret {
jvalret() { obj = nullptr; }
};
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject = false);
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject = false, int p_depth = 0);
String _get_class_name(JNIEnv *env, jclass cls, bool *array);
Variant _jobject_to_variant(JNIEnv *env, jobject obj);
Variant _jobject_to_variant(JNIEnv *env, jobject obj, int p_depth = 0);
Variant::Type get_jni_type(const String &p_type);