diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2020-01-19 22:06:26 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2020-01-19 22:08:40 +0100 |
commit | 6472e09a85a6b00c72adf53dc1b8bdd873913a5b (patch) | |
tree | 6f0a0ac20305ba2afe889fb6eb1aba7c101916eb | |
parent | 90a224c6eb202c1e6d87bded6adf50d7e40f08fc (diff) |
SceneTree: Abort change_scene if we're quitting
Otherwise we can have a segmentation fault if we try to call
`add_child` on an already freed node.
Fixes #35323.
-rw-r--r-- | scene/main/scene_tree.cpp | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 7c43d8fb14..238d6c20cc 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -459,10 +459,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { } void SceneTree::init() { - - //_quit=false; initialized = true; - root->_set_tree(this); MainLoop::init(); } @@ -1285,6 +1282,14 @@ void SceneTree::_change_scene(Node *p_to) { current_scene = NULL; } + // If we're quitting, abort. + if (unlikely(_quit)) { + if (p_to) { // Prevent memory leak. + memdelete(p_to); + } + return; + } + if (p_to) { current_scene = p_to; root->add_child(p_to); @@ -1292,15 +1297,14 @@ void SceneTree::_change_scene(Node *p_to) { } Error SceneTree::change_scene(const String &p_path) { - Ref<PackedScene> new_scene = ResourceLoader::load(p_path); if (new_scene.is_null()) return ERR_CANT_OPEN; return change_scene_to(new_scene); } -Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) { +Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) { Node *new_scene = NULL; if (p_scene.is_valid()) { new_scene = p_scene->instance(); @@ -1310,8 +1314,8 @@ Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) { call_deferred("_change_scene", new_scene); return OK; } -Error SceneTree::reload_current_scene() { +Error SceneTree::reload_current_scene() { ERR_FAIL_COND_V(!current_scene, ERR_UNCONFIGURED); String fname = current_scene->get_filename(); return change_scene(fname); @@ -1322,6 +1326,7 @@ void SceneTree::add_current_scene(Node *p_current) { current_scene = p_current; root->add_child(p_current); } + #ifdef DEBUG_ENABLED static void _fill_array(Node *p_node, Array &array, int p_level) { |