Skip to content

Commit 476b901

Browse files
committed
Prevent JNI Variant conversion stack overflow
1 parent 9b50ea8 commit 476b901

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

platform/android/jni_utils.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,15 @@ String charsequence_to_string(JNIEnv *p_env, jobject p_charsequence) {
8686
return result;
8787
}
8888

89-
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject) {
89+
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject, int p_depth) {
9090
jvalret v;
9191

92+
if (p_depth > Variant::MAX_RECURSION_DEPTH) {
93+
ERR_PRINT("Variant is too deep! Bailing.");
94+
v.val.i = 0;
95+
return v;
96+
}
97+
9298
switch (p_type) {
9399
case Variant::BOOL: {
94100
if (force_jobject) {
@@ -185,7 +191,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
185191

186192
for (int j = 0; j < keys.size(); j++) {
187193
Variant var = dict[keys[j]];
188-
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true);
194+
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true, p_depth + 1);
189195
env->SetObjectArrayElement(jvalues, j, valret.val.l);
190196
if (valret.obj) {
191197
env->DeleteLocalRef(valret.obj);
@@ -208,7 +214,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
208214

209215
for (int j = 0; j < array.size(); j++) {
210216
Variant var = array[j];
211-
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true);
217+
jvalret valret = _variant_to_jvalue(env, var.get_type(), &var, true, p_depth + 1);
212218
env->SetObjectArrayElement(arr, j, valret.val.l);
213219
if (valret.obj) {
214220
env->DeleteLocalRef(valret.obj);
@@ -297,7 +303,9 @@ String _get_class_name(JNIEnv *env, jclass cls, bool *array) {
297303
return name;
298304
}
299305

300-
Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
306+
Variant _jobject_to_variant(JNIEnv *env, jobject obj, int p_depth) {
307+
ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, Variant(), "Variant is too deep! Bailing.");
308+
301309
if (obj == nullptr) {
302310
return Variant();
303311
}
@@ -434,7 +442,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
434442

435443
for (int i = 0; i < objCount; i++) {
436444
jobject jobj = env->GetObjectArrayElement(arr, i);
437-
Variant v = _jobject_to_variant(env, jobj);
445+
Variant v = _jobject_to_variant(env, jobj, p_depth + 1);
438446
varr.push_back(v);
439447
env->DeleteLocalRef(jobj);
440448
}
@@ -448,13 +456,13 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
448456
jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;");
449457
jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys);
450458

451-
PackedStringArray keys = _jobject_to_variant(env, arr);
459+
PackedStringArray keys = _jobject_to_variant(env, arr, p_depth + 1);
452460
env->DeleteLocalRef(arr);
453461

454462
jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;");
455463
arr = (jobjectArray)env->CallObjectMethod(obj, get_values);
456464

457-
Array vals = _jobject_to_variant(env, arr);
465+
Array vals = _jobject_to_variant(env, arr, p_depth + 1);
458466
env->DeleteLocalRef(arr);
459467

460468
for (int i = 0; i < keys.size(); i++) {

platform/android/jni_utils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ struct jvalret {
4444
jvalret() { obj = nullptr; }
4545
};
4646

47-
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject = false);
47+
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject = false, int p_depth = 0);
4848

4949
String _get_class_name(JNIEnv *env, jclass cls, bool *array);
5050

51-
Variant _jobject_to_variant(JNIEnv *env, jobject obj);
51+
Variant _jobject_to_variant(JNIEnv *env, jobject obj, int p_depth = 0);
5252

5353
Variant::Type get_jni_type(const String &p_type);
5454

0 commit comments

Comments
 (0)