Skip to content

Commit

Permalink
fixed incorrect alignment when deserializing BinaryBlob
Browse files Browse the repository at this point in the history
- fixes #710
  • Loading branch information
mrDIMAS committed Jan 7, 2025
1 parent 3c443e6 commit 09ff1cf
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions fyrox-core/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -540,24 +541,27 @@ impl_field_data!(Vector4<u64>, FieldKind::Vector4U64);

impl<T> 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::<T>(),
bytes.capacity() / std::mem::size_of::<T>(),
)
};
let len = data.len() / size_of::<T>();
let mut vec = Vec::<T>::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(())
}
Expand Down

0 comments on commit 09ff1cf

Please sign in to comment.