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

Node pointers can't be passed into UtilityFunctions::is_instance_valid() to check if they have not been freed; is something needed for this? #1390

Open
id01 opened this issue Feb 11, 2024 · 1 comment
Labels
bug This has been identified as a bug crash discussion

Comments

@id01
Copy link

id01 commented Feb 11, 2024

Godot version

4.2.1.stable

godot-cpp version

4.2.1.stable

System information

Any

Issue description

Currently, is_instance_valid() dereferences object pointers passed to it due to implicit cast to Variant. As such, executing is_instance_valid() on freed nodes, unlike in gdscript, causes a use-after-free crash. Currently, there doesn't seem to be a way to store nodes where UtilityFunctions::is_instance_valid() can work without sacrificing typing (by storing everything as Variant), and the example project simply uses pointers for passing around object pointers as well.

Steps to reproduce

Call UtilityFunctions::is_instance_valid() on a freed node pointer. The program crashes instead of returning false.

Minimal reproduction project

See steps to reproduce.

@AThousandShips AThousandShips added bug This has been identified as a bug crash labels Feb 11, 2024
@dsnopek
Copy link
Contributor

dsnopek commented Feb 11, 2024

In a C++ module, rather than using is_instance_valid(), in situations where you need to store objects that might get freed, you'd store ObjectID and call ObjectDB::get_instance() to check if it's still valid. This is what I'd recommend doing in godot-cpp as well, since we are attempting to emulate modules (and it doesn't suffer from the problem you're encountering).

Regarding fixing is_instance_valid(): I wonder if we should just not expose it in godot-cpp?

There is no way to check if an Object * has been freed, and trying to create a Variant from a freed Object * will cause a crash. This is exactly what will happen if you call is_instance_valid() with a freed Object * (it's automatically converted to Variant), which that function is practically inviting developers to do. This isn't the first time this issue has come up. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This has been identified as a bug crash discussion
Projects
None yet
Development

No branches or pull requests

3 participants