Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use casts instead of transmute #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/abomonated.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

use std::mem::transmute;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

Expand All @@ -8,7 +7,7 @@ use super::{Abomonation, decode};
/// A type wrapping owned decoded abomonated data.
///
/// This type ensures that decoding and pointer correction has already happened,
/// and implements `Deref<Target=T>` using a pointer cast (transmute).
/// and implements `Deref<Target=T>` using a pointer cast.
///
/// #Safety
///
Expand Down Expand Up @@ -121,7 +120,6 @@ impl<T, S: DerefMut<Target=[u8]>> Deref for Abomonated<T, S> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
let result: &T = unsafe { transmute(self.decoded.get_unchecked(0)) };
result
unsafe { &*(self.decoded.as_ptr() as *const T) }
}
}
15 changes: 7 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ pub mod abomonated;
///
#[inline]
pub unsafe fn encode<T: Abomonation, W: Write>(typed: &T, write: &mut W) -> IOResult<()> {
let slice = std::slice::from_raw_parts(mem::transmute(typed), mem::size_of::<T>());
write.write_all(slice)?;
write.write_all(typed_to_bytes(typed))?;
typed.entomb(write)?;
Ok(())
}
Expand Down Expand Up @@ -124,7 +123,7 @@ pub unsafe fn decode<T: Abomonation>(bytes: &mut [u8]) -> Option<(&T, &mut [u8])
if bytes.len() < mem::size_of::<T>() { None }
else {
let (split1, split2) = bytes.split_at_mut(mem::size_of::<T>());
let result: &mut T = mem::transmute(split1.get_unchecked_mut(0));
let result: &mut T = &mut *(split1.as_mut_ptr() as *mut T);
if let Some(remaining) = result.exhume(split2) {
Some((result, remaining))
}
Expand Down Expand Up @@ -468,7 +467,7 @@ impl Abomonation for String {
if self.len() > bytes.len() { None }
else {
let (mine, rest) = bytes.split_at_mut(self.len());
std::ptr::write(self, String::from_raw_parts(mem::transmute(mine.as_ptr()), self.len(), self.len()));
std::ptr::write(self, String::from_raw_parts(mine.as_mut_ptr(), self.len(), self.len()));
Some(rest)
}
}
Expand Down Expand Up @@ -514,7 +513,7 @@ impl<T: Abomonation> Abomonation for Vec<T> {
impl<T: Abomonation> Abomonation for Box<T> {
#[inline]
unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> IOResult<()> {
bytes.write_all(std::slice::from_raw_parts(mem::transmute(&**self), mem::size_of::<T>()))?;
bytes.write_all(typed_to_bytes::<T>(&**self))?;
(**self).entomb(bytes)?;
Ok(())
}
Expand All @@ -524,7 +523,7 @@ impl<T: Abomonation> Abomonation for Box<T> {
if binary_len > bytes.len() { None }
else {
let (mine, mut rest) = bytes.split_at_mut(binary_len);
std::ptr::write(self, mem::transmute(mine.as_mut_ptr() as *mut T));
std::ptr::write(self, Box::from_raw(mine.as_mut_ptr() as *mut T));
let temp = rest; rest = (**self).exhume(temp)?;
Some(rest)
}
Expand All @@ -535,8 +534,8 @@ impl<T: Abomonation> Abomonation for Box<T> {
}

// This method currently enables undefined behavior, by exposing padding bytes.
#[inline] unsafe fn typed_to_bytes<T>(slice: &[T]) -> &[u8] {
std::slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len() * mem::size_of::<T>())
#[inline] unsafe fn typed_to_bytes<T: ?Sized>(typed: &T) -> &[u8] {
std::slice::from_raw_parts(typed as *const T as *const u8, mem::size_of_val(typed))
}

mod network {
Expand Down