Backport soundness fix (#3685)
#3001 discovered a soundness bug in World::resource_scope, this PR backports the fix with a smaller PR to patch out the bug sooner. Fixes #3147
This commit is contained in:
		
							parent
							
								
									e928acb9ff
								
							
						
					
					
						commit
						142e7f3c50
					
				| @ -926,24 +926,30 @@ impl World { | |||||||
|             // the ptr value / drop is called when T is dropped
 |             // the ptr value / drop is called when T is dropped
 | ||||||
|             unsafe { column.swap_remove_and_forget_unchecked(0) } |             unsafe { column.swap_remove_and_forget_unchecked(0) } | ||||||
|         }; |         }; | ||||||
|         // SAFE: pointer is of type T
 |         // SAFE: pointer is of type T and valid to move out of
 | ||||||
|         let value = Mut { |         // Read the value onto the stack to avoid potential mut aliasing.
 | ||||||
|             value: unsafe { &mut *ptr.cast::<T>() }, |         let mut value = unsafe { std::ptr::read(ptr.cast::<T>()) }; | ||||||
|  |         let value_mut = Mut { | ||||||
|  |             value: &mut value, | ||||||
|             ticks: Ticks { |             ticks: Ticks { | ||||||
|                 component_ticks: &mut ticks, |                 component_ticks: &mut ticks, | ||||||
|                 last_change_tick: self.last_change_tick(), |                 last_change_tick: self.last_change_tick(), | ||||||
|                 change_tick: self.change_tick(), |                 change_tick: self.change_tick(), | ||||||
|             }, |             }, | ||||||
|         }; |         }; | ||||||
|         let result = f(self, value); |         let result = f(self, value_mut); | ||||||
|  |         assert!(!self.contains_resource::<T>()); | ||||||
|         let resource_archetype = self.archetypes.resource_mut(); |         let resource_archetype = self.archetypes.resource_mut(); | ||||||
|         let unique_components = resource_archetype.unique_components_mut(); |         let unique_components = resource_archetype.unique_components_mut(); | ||||||
|         let column = unique_components |         let column = unique_components | ||||||
|             .get_mut(component_id) |             .get_mut(component_id) | ||||||
|             .unwrap_or_else(|| panic!("resource does not exist: {}", std::any::type_name::<T>())); |             .unwrap_or_else(|| panic!("resource does not exist: {}", std::any::type_name::<T>())); | ||||||
|  | 
 | ||||||
|  |         // Wrap the value in MaybeUninit to prepare for passing the value back into the ECS
 | ||||||
|  |         let mut nodrop_wrapped_value = std::mem::MaybeUninit::new(value); | ||||||
|         unsafe { |         unsafe { | ||||||
|             // SAFE: pointer is of type T
 |             // SAFE: pointer is of type T, and valid to move out of
 | ||||||
|             column.push(ptr, ticks); |             column.push(nodrop_wrapped_value.as_mut_ptr() as *mut _, ticks); | ||||||
|         } |         } | ||||||
|         result |         result | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 TheRawMeatball
						TheRawMeatball