From 09ff1cfc4e716b1a2ee3d718ba584dc6c90c4328 Mon Sep 17 00:00:00 2001 From: Dmitry Stepanov Date: Tue, 7 Jan 2025 10:44:56 +0300 Subject: [PATCH] fixed incorrect alignment when deserializing `BinaryBlob` - fixes #710 --- fyrox-core/src/visitor.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/fyrox-core/src/visitor.rs b/fyrox-core/src/visitor.rs index 59e6ea530..499c77168 100644 --- a/fyrox-core/src/visitor.rs +++ b/fyrox-core/src/visitor.rs @@ -40,6 +40,7 @@ use crate::{ Complex, Const, Matrix, Matrix2, Matrix3, Matrix4, Quaternion, RawStorage, RawStorageMut, SVector, Scalar, UnitComplex, UnitQuaternion, Vector2, Vector3, Vector4, U1, }, + array_as_u8_slice_mut, io::{self, FileLoadError}, pool::{Handle, Pool}, replace_slashes, @@ -540,24 +541,27 @@ impl_field_data!(Vector4, FieldKind::Vector4U64); impl Visit for BinaryBlob<'_, T> where - T: Copy, + T: Copy + bytemuck::Pod, { fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult { if visitor.reading { if let Some(field) = visitor.find_field(name) { match &field.kind { FieldKind::BinaryBlob(data) => { - let mut bytes = std::mem::ManuallyDrop::new(data.clone()); - - // SAFETY: This is kinda safe, but may cause portability issues because of various byte order. - // However it seems to be fine, since big-endian is pretty much dead and unused nowadays. - *self.vec = unsafe { - Vec::from_raw_parts( - bytes.as_mut_ptr() as *mut T, - bytes.len() / std::mem::size_of::(), - bytes.capacity() / std::mem::size_of::(), - ) - }; + let len = data.len() / size_of::(); + let mut vec = Vec::::with_capacity(len); + + unsafe { + std::ptr::copy_nonoverlapping( + data.as_ptr(), + array_as_u8_slice_mut(&mut vec).as_mut_ptr(), + data.len(), + ); + + vec.set_len(len); + } + + *self.vec = vec; Ok(()) }