-
Notifications
You must be signed in to change notification settings - Fork 211
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
Safety redesign #808
Comments
Thanks for creating this issue for discussion on the topic.
I think that
I think it's probably fine to leave it to the user. One note on the engine design is that the only GDScript executed is the GDScript that the user writes. If you want to mix and match, I think it's fine to make the various
In addition to your thoughts above, I think that we can also consider
I agree 100% All in all, I think that typestates are a great way to opt-in to safety from Rust. Even if we have the same functionality available in I'm not quite sure where to draw the line, but I do really like the current type-state approach. Perhaps we can leverage it and make it a bit easier to approach without needing to pepper |
For reference, here is a (likely incomplete) list of APIs that allow custom code execution. GDScript, being a dynamic language, offers a lot of reflection mechanisms. Besides soundness implications (elaborated in first post), such methods can also be a security risk if they are passed unchecked user input -- especially those towards the end of the list.
And this list doesn't even mention networking ( |
Not sure if this belongs here or in one of the related tickets, but I have been trying to get a better grasp on the safety requirements for I did some digital archeology looking for answers and the lifetime split was done to fix #455 in #456. Constraining the lifetime in https://github.com/godot-rust/godot-rust/blob/5f388837a6dc91c7ae9f4abfe3de2a2880e39243/gdnative-core/src/object/bounds.rs#L212 with
This code was added in #669, about 6 months after the lifetime split. I also found this particularly unusual: https://github.com/godot-rust/godot-rust/blob/5f388837a6dc91c7ae9f4abfe3de2a2880e39243/gdnative-core/src/object/bounds.rs#L213 I would expect these lifetimes to be unrelated, since the object is reference counted within the engine. |
I was learning more about the reference systems and their safety dynamics a bit with the help of folks on discord today. ❤️ Jacobsky's description of Through my tinkering I felt like With only Now if I have things right, I can see how I share this hoping it helps provide insight on how others might be looking at things and struggling. I also wanted to share the idea of restructuring and renaming the references a little bit. The idea is rough but I feel like I'm not sure how |
godot-rust historically (v0.8) used
unsafe
for every interaction with the engine. While this was "on the safe side", it was very inconvenient and forced the user to clutter the code withunsafe
. v0.9 took a different approach with type-states: the user opts in to unsafety when convertingRef
toTRef
, and most (but not all) subsequent calls are safe. This improved a lot, but unfortunately there's still quite a bit of friction (#758 among others).The more we looked into safety models, the more it became apparent that there's quite a bit of work left to do to come up with something consistent and uniformly applicable. Most notable, the following questions remain unanswered:
Ref::assume_safe()
? What about the safe ways to obtainTRef
(owner parameter)? Object lifeness is not enough.unsafe
? Or should we draw the boundary at Rust code, leaving the responsibility for correct GDScript implementation to the user? For the record, these are possible causes for UB when calling GDScript:Object::free()
orReference::unreference()
.Thread
classunsafe
from safe codeunsafe
doesn't turn into an inflationary keyword that's used mindlessly whenever any Godot APIs are used? There is no point in being on the "academically correct side" if people start usingunsafe
like it means nothing. Ideally,unsafe
has the following purposes:unsafe
whenever they write itA new model would ideally be consistent in the way that it's clear which methods are unsafe and which aren't, i.e. there should be a ruleset for inclusion/exclusion (with only few exceptions). It should also be pragmatic for above-mentioned reasons, a dogmatic "everything is unsafe" is not helping anyone. We have to embrace the fact that godot-rust's entire point is to deal with non-Rust code, whose safety is outside the library's control.
This issue hosts general discussion and this post serves as tracker for implementation tasks.
Large issues needing considerable design:
More isolated, specific API shortcomings:
RID
arguments need to beunsafe
#836Rid
and APIs accepting it are now unsafe #844set
onVariantArray
with an out of bounds index causes segfault #790Dictionary::get
unsoundness and add a few convenience functions #748The text was updated successfully, but these errors were encountered: