amethyst/legion

`<PackedStorage<T> as UnknownComponentStorage>::transfer_component` is unsound

ImmemorConsultrixContrarie opened this issue · 0 comments

This implementation is unsound:

/// Moves a component to a new storage.
fn transfer_component(
&mut self,
src_archetype: ArchetypeIndex,
src_component: ComponentIndex,
dst_archetype: ArchetypeIndex,
dst: &mut dyn UnknownComponentStorage,
) {
let component = self.swap_remove_internal(src_archetype, src_component);
unsafe { dst.extend_memcopy_raw(dst_archetype, &component as *const T as *const u8, 1) };
std::mem::forget(component);
}

because this compiles:

fn soundness_hole() {
    let mut a: PackedStorage<u64> = Default::default();
    let mut b: PackedStorage<u8> = Default::default();
    let a: &mut dyn UnknownComponentStorage = &mut a;
    a.transfer_component(ArchetypeIndex(0), ComponentIndex(0), ArchetypeIndex(0), &mut b);
}

Getting this UB outside of lib is tricky, however unsoundness inside the lib itself is bad too.