bevyengine / bevyengine/bevy

`Observer`s' underlying system state can change after they have been spawned

Open
#20,737 1 comment 0 reactions 0 assignees View on GitHub
A-ECS C-Bug D-Unsafe I-Unsound
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version and features

https://github.com/bevyengine/bevy/commit/69745d40e594fb34a99507e2f0be2385711e46a6 but also likely 0.16.1

## What you did

```rs
use bevy_ecs::{entity_disabling::Internal, prelude::*, system::IntoObserverSystem};

fn main() {
#[derive(EntityEvent)]
struct Ev;

struct Local1(&'static i32);

impl Default for Local1 {
fn default() -> Self {
Local1(&0)
}
}

#[derive(Default)]
struct Local2(usize);

fn bad_observer(_: On, local: Local) {
println!("{}", local.0);
}

let mut world = World::new();

world.add_observer(bad_observer);

let mut s = IntoObserverSystem::into_system(|_: On, _: Local| {});
s.initialize(&mut world);

*world
.query_filtered::<&mut Observer, With>()
.single_mut(&mut world)
.unwrap() = Observer::new(s);

world.trigger(Ev);
}
```

## What went wrong

This causes a segfault in release mode, because the original system is run with the new system's local, effectively transmuting the local's type.

In debug mode it fails the following assertion:

https://github.com/bevyengine/bevy/blob/69745d40e594fb34a99507e2f0be2385711e46a6/crates/bevy_ecs/src/observer/runner.rs#L56

This is similar to #20736 in that both are caused by the `Observer` component being replaced, however it's different in that it doesn't need the observer to be currenlty running, so a fix that just temporarily moves out the system state while running won't fix this issue too.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.