Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix blend_node crash with invalid AnimationNode reference #86321

Merged
merged 1 commit into from
Feb 22, 2024

Conversation

jsjtxietian
Copy link
Contributor

Fixes #86070

It's a regression because 5acf6b4 changed node_state.connections.clear() to p_node->node_state.connections.clear() , previously the crash can be prevented by null check in _blend_node .

Copy link
Member

@TokageItLab TokageItLab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the null check in the first line of _blend_node() could be removed, as it would be a duplicate check. If so, does it cause a problem that there is no check on the call within blend_input()?

scene/animation/animation_tree.cpp Outdated Show resolved Hide resolved
@jsjtxietian
Copy link
Contributor Author

If so, does it cause a problem that there is no check on the call within blend_input()

Reading the code, it looks like the provided p_node must be a valid one.

@akien-mga
Copy link
Member

It looks like the null check in the first line of _blend_node() could be removed, as it would be a duplicate check. If so, does it cause a problem that there is no check on the call within blend_input()?

_blend_node() is also called in other places. Those would also need a check if we're removing it from _blend_node itself:

scene/animation/animation_blend_tree.cpp
1410:   return _blend_node(output, "output", this, pi, FILTER_IGNORE, true, p_test_only, nullptr);

scene/animation/animation_tree.h
87:     double _blend_node(Ref<AnimationNode> p_node, const StringName &p_subpath, AnimationNode *p_new_parent, AnimationMixer::PlaybackInfo p_playback_info, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false, real_t *r_activity = nullptr);

scene/animation/animation_tree.cpp
146:    double ret = _blend_node(node, node_name, nullptr, p_playback_info, p_filter, p_sync, p_test_only, &activity);
157:    return _blend_node(p_node, p_subpath, this, p_playback_info, p_filter, p_sync, p_test_only, nullptr);

@akien-mga akien-mga changed the title Fix blend_node crash with invalid p_node Fix blend_node crash with invalid AnimationNode reference Feb 20, 2024
@jsjtxietian
Copy link
Contributor Author

jsjtxietian commented Feb 20, 2024

Those would also need a check if we're removing it from _blend_node itself:

I'm not 100% sure about the logic here. But like I said earlier, from the code, the other places calling _blend_node seems all get the AnimationNode reference from the nodes in defined in AnimationNodeBlendTree, which seems to assumes that it's always have a valid node.

But there's no harm in adding more checkes I guess, or just keep the check inside _blend_node

@TokageItLab
Copy link
Member

TokageItLab commented Feb 21, 2024

I prefer to add more two checks to

animation_tree.cpp line 167:

	Ref<AnimationNode> node = blend_tree->get_node(node_name);
	ERR_FAIL_COND_V (node.is_null(), NodeTimeInfo());

	real_t activity = 0.0;
	Vector<AnimationTree::Activity> *activity_ptr = process_state->tree->input_activity_map.getptr(node_state.base_path);
	NodeTimeInfo nti = _blend_node(node, node_name, nullptr, p_playback_info, p_filter, p_sync, p_test_only, &activity);

	if (activity_ptr && p_input < activity_ptr->size()) {
		activity_ptr->write[p_input].last_pass = process_state->last_pass;
		activity_ptr->write[p_input].activity = activity;
	}
	return nti;

animation_blend_tree.cpp line 1635:

AnimationNode::NodeTimeInfo AnimationNodeBlendTree::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) {
	Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
	node_state.connections = nodes[SceneStringNames::get_singleton()->output].connections;
	ERR_FAIL_COND_V (output.is_null(), NodeTimeInfo());

	AnimationMixer::PlaybackInfo pi = p_playback_info;
	pi.weight = 1.0;

	return _blend_node(output, "output", this, pi, FILTER_IGNORE, true, p_test_only, nullptr);
}

@akien-mga akien-mga merged commit efa4d0a into godotengine:master Feb 22, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks!

@jsjtxietian jsjtxietian deleted the fix-blendnode-crash branch February 22, 2024 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Executing AnimationNode.blend_node function crashes Godot
4 participants