You've already forked godot
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:
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user