Core: Fix recursion level check for `VariantWriter::write()` with objects

(cherry picked from commit 5d689ad560)
This commit is contained in:
Danil Alexeev 2023-08-29 15:05:53 +03:00 committed by Yuri Sizov
parent 3c5f715053
commit 6d5127d34b
2 changed files with 21 additions and 38 deletions

View File

@ -1708,7 +1708,7 @@ static String rtos_fix(double p_value) {
} }
} }
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count) { Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count) {
switch (p_variant.get_type()) { switch (p_variant.get_type()) {
case Variant::NIL: { case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null"); p_store_string_func(p_store_string_ud, "null");
@ -1730,10 +1730,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break; } break;
case Variant::STRING: { case Variant::STRING: {
String str = p_variant; String str = p_variant;
str = "\"" + str.c_escape_multiline() + "\""; str = "\"" + str.c_escape_multiline() + "\"";
p_store_string_func(p_store_string_ud, str); p_store_string_func(p_store_string_ud, str);
} break; } break;
// Math types.
case Variant::VECTOR2: { case Variant::VECTOR2: {
Vector2 v = p_variant; Vector2 v = p_variant;
p_store_string_func(p_store_string_ud, "Vector2(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ")"); p_store_string_func(p_store_string_ud, "Vector2(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ")");
@ -1745,12 +1746,10 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::RECT2: { case Variant::RECT2: {
Rect2 aabb = p_variant; Rect2 aabb = p_variant;
p_store_string_func(p_store_string_ud, "Rect2(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ")"); p_store_string_func(p_store_string_ud, "Rect2(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ")");
} break; } break;
case Variant::RECT2I: { case Variant::RECT2I: {
Rect2i aabb = p_variant; Rect2i aabb = p_variant;
p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")"); p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")");
} break; } break;
case Variant::VECTOR3: { case Variant::VECTOR3: {
Vector3 v = p_variant; Vector3 v = p_variant;
@ -1771,17 +1770,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::PLANE: { case Variant::PLANE: {
Plane p = p_variant; Plane p = p_variant;
p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")"); p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")");
} break; } break;
case Variant::AABB: { case Variant::AABB: {
AABB aabb = p_variant; AABB aabb = p_variant;
p_store_string_func(p_store_string_ud, "AABB(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.position.z) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ", " + rtos_fix(aabb.size.z) + ")"); p_store_string_func(p_store_string_ud, "AABB(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.position.z) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ", " + rtos_fix(aabb.size.z) + ")");
} break; } break;
case Variant::QUATERNION: { case Variant::QUATERNION: {
Quaternion quaternion = p_variant; Quaternion quaternion = p_variant;
p_store_string_func(p_store_string_ud, "Quaternion(" + rtos_fix(quaternion.x) + ", " + rtos_fix(quaternion.y) + ", " + rtos_fix(quaternion.z) + ", " + rtos_fix(quaternion.w) + ")"); p_store_string_func(p_store_string_ud, "Quaternion(" + rtos_fix(quaternion.x) + ", " + rtos_fix(quaternion.y) + ", " + rtos_fix(quaternion.z) + ", " + rtos_fix(quaternion.w) + ")");
} break; } break;
case Variant::TRANSFORM2D: { case Variant::TRANSFORM2D: {
String s = "Transform2D("; String s = "Transform2D(";
@ -1796,7 +1792,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, s + ")"); p_store_string_func(p_store_string_ud, s + ")");
} break; } break;
case Variant::BASIS: { case Variant::BASIS: {
String s = "Basis("; String s = "Basis(";
@ -1811,7 +1806,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, s + ")"); p_store_string_func(p_store_string_ud, s + ")");
} break; } break;
case Variant::TRANSFORM3D: { case Variant::TRANSFORM3D: {
String s = "Transform3D("; String s = "Transform3D(";
@ -1845,30 +1839,23 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, s + ")"); p_store_string_func(p_store_string_ud, s + ")");
} break; } break;
// misc types // Misc types.
case Variant::COLOR: { case Variant::COLOR: {
Color c = p_variant; Color c = p_variant;
p_store_string_func(p_store_string_ud, "Color(" + rtos_fix(c.r) + ", " + rtos_fix(c.g) + ", " + rtos_fix(c.b) + ", " + rtos_fix(c.a) + ")"); p_store_string_func(p_store_string_ud, "Color(" + rtos_fix(c.r) + ", " + rtos_fix(c.g) + ", " + rtos_fix(c.b) + ", " + rtos_fix(c.a) + ")");
} break; } break;
case Variant::STRING_NAME: { case Variant::STRING_NAME: {
String str = p_variant; String str = p_variant;
str = "&\"" + str.c_escape() + "\""; str = "&\"" + str.c_escape() + "\"";
p_store_string_func(p_store_string_ud, str); p_store_string_func(p_store_string_ud, str);
} break; } break;
case Variant::NODE_PATH: { case Variant::NODE_PATH: {
String str = p_variant; String str = p_variant;
str = "NodePath(\"" + str.c_escape() + "\")"; str = "NodePath(\"" + str.c_escape() + "\")";
p_store_string_func(p_store_string_ud, str); p_store_string_func(p_store_string_ud, str);
} break; } break;
case Variant::RID: { case Variant::RID: {
RID rid = p_variant; RID rid = p_variant;
if (rid == RID()) { if (rid == RID()) {
p_store_string_func(p_store_string_ud, "RID()"); p_store_string_func(p_store_string_ud, "RID()");
} else { } else {
@ -1885,6 +1872,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break; } break;
case Variant::OBJECT: { case Variant::OBJECT: {
if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "null");
return OK;
}
p_recursion_count++;
Object *obj = p_variant.get_validated_object(); Object *obj = p_variant.get_validated_object();
if (!obj) { if (!obj) {
@ -1934,21 +1928,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, "\"" + E.name + "\":"); p_store_string_func(p_store_string_ud, "\"" + E.name + "\":");
write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
} }
} }
p_store_string_func(p_store_string_ud, ")\n"); p_store_string_func(p_store_string_ud, ")\n");
} break; } break;
case Variant::DICTIONARY: { case Variant::DICTIONARY: {
Dictionary dict = p_variant; Dictionary dict = p_variant;
if (recursion_count > MAX_RECURSION) { if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached"); ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "{}"); p_store_string_func(p_store_string_ud, "{}");
} else { } else {
recursion_count++; p_recursion_count++;
List<Variant> keys; List<Variant> keys;
dict.get_key_list(&keys); dict.get_key_list(&keys);
@ -1961,9 +1954,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "{\n"); p_store_string_func(p_store_string_ud, "{\n");
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count); write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
p_store_string_func(p_store_string_ud, ": "); p_store_string_func(p_store_string_ud, ": ");
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count); write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
if (E->next()) { if (E->next()) {
p_store_string_func(p_store_string_ud, ",\n"); p_store_string_func(p_store_string_ud, ",\n");
} else { } else {
@ -1973,7 +1966,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "}"); p_store_string_func(p_store_string_ud, "}");
} }
} break; } break;
case Variant::ARRAY: { case Variant::ARRAY: {
@ -2009,11 +2001,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "]("); p_store_string_func(p_store_string_ud, "](");
} }
if (recursion_count > MAX_RECURSION) { if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached"); ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "[]"); p_store_string_func(p_store_string_ud, "[]");
} else { } else {
recursion_count++; p_recursion_count++;
p_store_string_func(p_store_string_ud, "["); p_store_string_func(p_store_string_ud, "[");
int len = array.size(); int len = array.size();
@ -2021,7 +2013,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (i > 0) { if (i > 0) {
p_store_string_func(p_store_string_ud, ", "); p_store_string_func(p_store_string_ud, ", ");
} }
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count); write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
} }
p_store_string_func(p_store_string_ud, "]"); p_store_string_func(p_store_string_ud, "]");
@ -2030,7 +2022,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (array.get_typed_builtin() != Variant::NIL) { if (array.get_typed_builtin() != Variant::NIL) {
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} }
} break; } break;
case Variant::PACKED_BYTE_ARRAY: { case Variant::PACKED_BYTE_ARRAY: {
@ -2048,7 +2039,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_INT32_ARRAY: { case Variant::PACKED_INT32_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedInt32Array("); p_store_string_func(p_store_string_ud, "PackedInt32Array(");
@ -2065,7 +2055,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_INT64_ARRAY: { case Variant::PACKED_INT64_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedInt64Array("); p_store_string_func(p_store_string_ud, "PackedInt64Array(");
@ -2082,7 +2071,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_FLOAT32_ARRAY: { case Variant::PACKED_FLOAT32_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedFloat32Array("); p_store_string_func(p_store_string_ud, "PackedFloat32Array(");
@ -2098,7 +2086,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_FLOAT64_ARRAY: { case Variant::PACKED_FLOAT64_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedFloat64Array("); p_store_string_func(p_store_string_ud, "PackedFloat64Array(");
@ -2114,7 +2101,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_STRING_ARRAY: { case Variant::PACKED_STRING_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedStringArray("); p_store_string_func(p_store_string_ud, "PackedStringArray(");
@ -2130,7 +2116,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_VECTOR2_ARRAY: { case Variant::PACKED_VECTOR2_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedVector2Array("); p_store_string_func(p_store_string_ud, "PackedVector2Array(");
@ -2146,7 +2131,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_VECTOR3_ARRAY: { case Variant::PACKED_VECTOR3_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedVector3Array("); p_store_string_func(p_store_string_ud, "PackedVector3Array(");
@ -2162,7 +2146,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
case Variant::PACKED_COLOR_ARRAY: { case Variant::PACKED_COLOR_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedColorArray("); p_store_string_func(p_store_string_ud, "PackedColorArray(");
@ -2178,8 +2161,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, ")"); p_store_string_func(p_store_string_ud, ")");
} break; } break;
default: { default: {
ERR_PRINT("Unknown variant type"); ERR_PRINT("Unknown variant type");
return ERR_BUG; return ERR_BUG;

View File

@ -160,7 +160,7 @@ public:
typedef Error (*StoreStringFunc)(void *ud, const String &p_string); typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource); typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource);
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count = 0); static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0);
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr); static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
}; };