From 39e61b76c6186f42c578b10cbae9a5cfeaa51a2c Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Wed, 28 Feb 2024 05:38:33 +0000 Subject: [PATCH] Fix SceneTree dock filter crash The filter was crashing for two reasons: 1) Deleting a child invalidated the iteration of children 2) Child was accessed after deletion --- editor/scene_tree_editor.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 1b8db32c18b..1a0f83a2947 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -594,9 +594,16 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select } bool keep_for_children = false; + + // Get the list of children ahead of time, as the list may be invalidated by deleting one of them. + LocalVector children; for (TreeItem *child = p_parent->get_children(); child; child = child->get_next()) { + children.push_back(child); + } + + for (uint32_t n = 0; n < children.size(); n++) { // Always keep if at least one of the children are kept. - keep_for_children = _update_filter(child, p_scroll_to_selected) || keep_for_children; + keep_for_children = _update_filter(children[n], p_scroll_to_selected) || keep_for_children; } // Now find other reasons to keep this Node, too. @@ -617,8 +624,6 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select } } } - } else { - memdelete(p_parent); } if (editor_selection) { @@ -635,6 +640,10 @@ bool SceneTreeEditor::_update_filter(TreeItem *p_parent, bool p_scroll_to_select } } + if (!(keep || keep_for_children)) { + memdelete(p_parent); + } + return keep || keep_for_children; }