`Observer`s' system state can become invalid while they're running
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version and features
69745d40 but also likely 0.16.1
## What you did
```rs
use bevy_ecs::{entity_disabling::Internal, prelude::*};
fn main() {
#[derive(EntityEvent)]
struct Ev;
fn bad_observer(_: On, q: Query<&mut Observer, With>, mut state: Local) {
*state = String::from("foobar12345");
for mut o in q {
*o = Observer::new(|_: On| {});
}
println!("{}", &*state);
}
let mut world = World::new();
world.add_observer(bad_observer);
world.trigger(Insert);
}
```
## What went wrong
The system causes undefied behaviour due to a use-after-free.
This safety comment is incorrect:
https://github.com/bevyengine/bevy/blob/69745d40e594fb34a99507e2f0be2385711e46a6/crates/bevy_ecs/src/observer/runner.rs#L53
Observers get mutable access to every entity/component, including their own state, so they can indeed drop their own state before the system has finished running.
I think it's fundamentally unsound to store the state of a running observer on a component that could be mutated while that is running.
Contributor guide
Assessment
This issue has not been assessed yet.