Skip to content

Commit

Permalink
Ensure Query does not use the wrong World (bevyengine#7150)
Browse files Browse the repository at this point in the history
`Query` relies on the `World` it stores being the same as the world used for creating the `QueryState` it stores. If they are not the same then everything is very unsound. This was not actually being checked anywhere, `Query::new` did not have a safety invariant or even an assertion that the `WorldId`'s are the same.

This shouldn't have any user facing impact unless we have really messed up in bevy and have unsoundness elsewhere (in which case we would now get a panic instead of being unsound).
  • Loading branch information
BoxyUwU authored and alradish committed Jan 22, 2023
1 parent a3c29dd commit 98c4ab0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
11 changes: 11 additions & 0 deletions crates/bevy_ecs/src/system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,4 +1202,15 @@ mod tests {
);
});
}

#[test]
#[should_panic = "Attempted to use bevy_ecs::query::state::QueryState<()> with a mismatched World."]
fn query_validates_world_id() {
let mut world1 = World::new();
let world2 = World::new();
let qstate = world1.query::<()>();
// SAFETY: doesnt access anything
let query = unsafe { Query::new(&world2, &qstate, 0, 0) };
query.iter();
}
}
6 changes: 6 additions & 0 deletions crates/bevy_ecs/src/system/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> std::fmt::Debug for Query<'w,
impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
/// Creates a new query.
///
/// # Panics
///
/// This will panic if the world used to create `state` is not `world`.
///
/// # Safety
///
/// This will create a query that could violate memory safety rules. Make sure that this is only
Expand All @@ -306,6 +310,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
last_change_tick: u32,
change_tick: u32,
) -> Self {
state.validate_world(world);

Self {
force_read_only_component_access: false,
world,
Expand Down

0 comments on commit 98c4ab0

Please sign in to comment.