From de4e54dd9150b0bc8bcb2ec643dd40eb4d3598d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Sat, 26 Sep 2020 19:21:09 +0200 Subject: [PATCH] Avoid infinite loop in GDScript at shutdown --- modules/gdscript/gdscript.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 7f303a966de..3519038ae67 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2039,8 +2039,15 @@ GDScriptLanguage::~GDScriptLanguage() { } // Clear dependencies between scripts, to ensure cyclic references are broken (to avoid leaks at exit). - while (script_list.first()) { - GDScript *script = script_list.first()->self(); + SelfList *s = script_list.first(); + while (s) { + GDScript *script = s->self(); + // This ensures the current script is not released before we can check what's the next one + // in the list (we can't get the next upfront because we don't know if the reference breaking + // will cause it -or any other after it, for that matter- to be released so the next one + // is not the same as before). + script->reference(); + for (Map::Element *E = script->member_functions.front(); E; E = E->next()) { GDScriptFunction *func = E->get(); for (int i = 0; i < func->argument_types.size(); i++) { @@ -2051,6 +2058,9 @@ GDScriptLanguage::~GDScriptLanguage() { for (Map::Element *E = script->member_indices.front(); E; E = E->next()) { E->get().data_type.script_type_ref = Ref