From f3149817ffffab9ca2eb2a3f764ec7d8816d692f Mon Sep 17 00:00:00 2001 From: Thakee Nathees Date: Thu, 19 Mar 2020 11:48:46 +0530 Subject: [PATCH] fixed: saving gdscript with cyclic inheritance crash the editor Fix: #9609 (cherry picked from commit c2ab35bdde2ad5dd0e5cb1a9312bf8da26623f79) --- modules/gdscript/gdscript.cpp | 29 ++++++++++++++++++++++++++--- modules/gdscript/gdscript.h | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index c183709b2c4..d948352edca 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -390,10 +390,15 @@ void GDScript::_update_exports_values(Map &values, List base_caches; + if (!p_recursive_call) + base_caches.clear(); + base_caches.push_back(this); + bool changed = false; if (source_changed_cache) { @@ -487,7 +492,22 @@ bool GDScript::_update_exports() { placeholder_fallback_enabled = false; if (base_cache.is_valid() && base_cache->is_valid()) { - if (base_cache->_update_exports()) { + for (int i = 0; i < base_caches.size(); i++) { + if (base_caches[i] == base_cache.ptr()) { + if (r_err) + *r_err = true; + valid = false; // to show error in the editor + base_cache->valid = false; + base_cache->inheriters_cache.clear(); // to prevent future stackoverflows + base_cache.unref(); + base.unref(); + _base = nullptr; + ERR_FAIL_V_MSG(false, "Cyclic inheritance in script class."); + } + } + if (base_cache->_update_exports(r_err, true)) { + if (r_err && *r_err) + return false; changed = true; } } @@ -515,7 +535,10 @@ void GDScript::update_exports() { #ifdef TOOLS_ENABLED - _update_exports(); + bool cyclic_error = false; + _update_exports(&cyclic_error); + if (cyclic_error) + return; Set copy = inheriters_cache; //might get modified diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 62b6d516ba1..029a5ba9b80 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -132,7 +132,7 @@ class GDScript : public Script { #endif - bool _update_exports(); + bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false); void _save_orphaned_subclasses();