From 442677a3f0544e66ee0616737a5695ad77bbe6b6 Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Tue, 29 Aug 2023 13:46:53 +0300 Subject: [PATCH] [3.x] Core: Add recursion level check for `VariantWriter::write()` (cherry picked from commit 0213cbbf205bf323583122d2601bd7c70d11fdb2) --- core/variant_parser.cpp | 32 +++++++++++++++++++++++++++----- core/variant_parser.h | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index bb4f7c47cb1..5f617b6866a 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1532,7 +1532,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()) { case Variant::NIL: { p_store_string_func(p_store_string_ud, "null"); @@ -1649,6 +1649,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; 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; if (!obj) { @@ -1698,7 +1705,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } 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); } } @@ -1707,6 +1714,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; 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; List keys; @@ -1719,9 +1733,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (!_check_type(dict[E->get()])) 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, ": "); - 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()) { p_store_string_func(p_store_string_ud, ",\n"); } else { @@ -1733,6 +1747,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; 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, "[ "); Array array = p_variant; int len = array.size(); @@ -1740,7 +1761,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { 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, " ]"); @@ -1871,6 +1892,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, " )"); } break; + default: { } } diff --git a/core/variant_parser.h b/core/variant_parser.h index f3e4357de99..6c1a7518c70 100644 --- a/core/variant_parser.h +++ b/core/variant_parser.h @@ -141,7 +141,7 @@ public: typedef Error (*StoreStringFunc)(void *ud, const String &p_string); 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); };