Merge pull request #81114 from dalexeev/3.x-core-add-recursion-check-for-variant-writer

[3.x] Core: Add recursion level check for `VariantWriter::write()`
This commit is contained in:
Rémi Verschelde 2023-09-06 13:04:23 +02:00
commit 2a6c7fc9f0
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 28 additions and 6 deletions

View file

@ -1588,7 +1588,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) { 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");
@ -1705,6 +1705,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; Object *obj = p_variant;
if (!obj) { if (!obj) {
@ -1754,7 +1761,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} }
p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":"); p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":");
write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
} }
} }
@ -1763,6 +1770,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break; } break;
case Variant::DICTIONARY: { case Variant::DICTIONARY: {
if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "{}");
return OK;
}
p_recursion_count++;
Dictionary dict = p_variant; Dictionary dict = p_variant;
List<Variant> keys; List<Variant> keys;
@ -1775,9 +1789,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (!_check_type(dict[E->get()])) if (!_check_type(dict[E->get()]))
continue; continue;
*/ */
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); 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); 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 {
@ -1789,6 +1803,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break; } break;
case Variant::ARRAY: { case Variant::ARRAY: {
if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "[]");
return OK;
}
p_recursion_count++;
p_store_string_func(p_store_string_ud, "[ "); p_store_string_func(p_store_string_ud, "[ ");
Array array = p_variant; Array array = p_variant;
int len = array.size(); int len = array.size();
@ -1796,7 +1817,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); 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, " ]");
@ -1927,6 +1948,7 @@ 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: {
} }
} }

View file

@ -166,7 +166,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 RES &p_resource); typedef String (*EncodeResourceFunc)(void *ud, const RES &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); 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);
}; };