Remove some usage of unsafe rust

This commit is contained in:
kpcyrd 2019-03-16 06:48:16 +01:00 committed by KAMADA Ken'ichi
parent 4874c69c24
commit 288a7e85c5
4 changed files with 25 additions and 30 deletions

View File

@ -46,12 +46,8 @@ pub struct LittleEndian;
macro_rules! generate_load { macro_rules! generate_load {
($name:ident, $int_type:ident, $from_func:ident) => ( ($name:ident, $int_type:ident, $from_func:ident) => (
fn $name(buf: &[u8], offset: usize) -> $int_type { fn $name(buf: &[u8], offset: usize) -> $int_type {
// Check if the specified range of the slice is valid let mut num = [0u8; mem::size_of::<$int_type>()];
// before transmute(). This will also detect the num.copy_from_slice(&buf[offset .. offset + mem::size_of::<$int_type>()]);
// wrap-around of (offset + size_of) in the release mode.
let buf = &buf[offset .. offset + mem::size_of::<$int_type>()];
let ptr = buf.as_ptr() as *const $int_type;
let num = unsafe { mem::transmute(*ptr) };
$int_type::$from_func(num) $int_type::$from_func(num)
} }
) )
@ -61,29 +57,28 @@ macro_rules! generate_write {
($name:ident, $int_type:ident, $type_size:expr, $to_func:ident) => ( ($name:ident, $int_type:ident, $type_size:expr, $to_func:ident) => (
fn $name<W>(w: &mut W, num: $int_type) fn $name<W>(w: &mut W, num: $int_type)
-> io::Result<()> where W: io::Write { -> io::Result<()> where W: io::Write {
let buf: [u8; $type_size] = let buf = num.$to_func();
unsafe { mem::transmute(num.$to_func()) };
w.write_all(&buf) w.write_all(&buf)
} }
) )
} }
impl Endian for BigEndian { impl Endian for BigEndian {
generate_load!(loadu16, u16, from_be); generate_load!(loadu16, u16, from_be_bytes);
generate_load!(loadu32, u32, from_be); generate_load!(loadu32, u32, from_be_bytes);
generate_load!(loadu64, u64, from_be); generate_load!(loadu64, u64, from_be_bytes);
generate_write!(writeu16, u16, 2, to_be); generate_write!(writeu16, u16, 2, to_be_bytes);
generate_write!(writeu32, u32, 4, to_be); generate_write!(writeu32, u32, 4, to_be_bytes);
generate_write!(writeu64, u64, 8, to_be); generate_write!(writeu64, u64, 8, to_be_bytes);
} }
impl Endian for LittleEndian { impl Endian for LittleEndian {
generate_load!(loadu16, u16, from_le); generate_load!(loadu16, u16, from_le_bytes);
generate_load!(loadu32, u32, from_le); generate_load!(loadu32, u32, from_le_bytes);
generate_load!(loadu64, u64, from_le); generate_load!(loadu64, u64, from_le_bytes);
generate_write!(writeu16, u16, 2, to_le); generate_write!(writeu16, u16, 2, to_le_bytes);
generate_write!(writeu32, u32, 4, to_le); generate_write!(writeu32, u32, 4, to_le_bytes);
generate_write!(writeu64, u64, 8, to_le); generate_write!(writeu64, u64, 8, to_le_bytes);
} }
#[cfg(test)] #[cfg(test)]

View File

@ -34,12 +34,12 @@ const ASCII_A: u8 = 0x41;
const ASCII_Z: u8 = 0x5a; const ASCII_Z: u8 = 0x5a;
pub fn read8<R>(reader: &mut R) -> Result<u8, io::Error> where R: io::Read { pub fn read8<R>(reader: &mut R) -> Result<u8, io::Error> where R: io::Read {
let mut buf: [u8; 1] = unsafe { ::std::mem::uninitialized() }; let mut buf = [0u8; 1];
reader.read_exact(&mut buf).and(Ok(buf[0])) reader.read_exact(&mut buf).and(Ok(buf[0]))
} }
pub fn read16<R>(reader: &mut R) -> Result<u16, io::Error> where R: io::Read { pub fn read16<R>(reader: &mut R) -> Result<u16, io::Error> where R: io::Read {
let mut buf: [u8; 2] = unsafe { ::std::mem::uninitialized() }; let mut buf = [0u8; 2];
reader.read_exact(&mut buf)?; reader.read_exact(&mut buf)?;
Ok(((buf[0] as u16) << 8) + buf[1] as u16) Ok(((buf[0] as u16) << 8) + buf[1] as u16)
} }

View File

@ -357,10 +357,10 @@ fn parse_rational<'a, E>(data: &'a [u8], offset: usize, count: usize)
fn parse_sbyte<'a>(data: &'a [u8], offset: usize, count: usize) fn parse_sbyte<'a>(data: &'a [u8], offset: usize, count: usize)
-> Value<'a> { -> Value<'a> {
let uslice = &data[offset .. offset + count]; let bytes = data[offset .. offset + count].into_iter()
let islice = unsafe { ::std::slice::from_raw_parts( .map(|x| *x as i8)
uslice.as_ptr() as *const i8, count) }; .collect();
Value::SByte(islice.to_vec()) Value::SByte(bytes)
} }
fn parse_undefined<'a>(data: &'a [u8], offset: usize, count: usize) fn parse_undefined<'a>(data: &'a [u8], offset: usize, count: usize)

View File

@ -26,7 +26,6 @@
use std::io; use std::io;
use std::io::{Seek, SeekFrom, Write}; use std::io::{Seek, SeekFrom, Write};
use std::slice;
use endian::{Endian, BigEndian, LittleEndian}; use endian::{Endian, BigEndian, LittleEndian};
use error::Error; use error::Error;
@ -527,9 +526,10 @@ fn compose_value<E>(value: &Value)
Ok((5, vec.len(), buf)) Ok((5, vec.len(), buf))
}, },
Value::SByte(ref vec) => { Value::SByte(ref vec) => {
let uslice = unsafe { slice::from_raw_parts( let bytes = vec.into_iter()
vec.as_ptr() as *const u8, vec.len()) }; .map(|x| *x as u8)
Ok((6, vec.len(), uslice.to_vec())) .collect();
Ok((6, vec.len(), bytes))
}, },
Value::Undefined(ref s, _) => Value::Undefined(ref s, _) =>
Ok((7, s.len(), s.to_vec())), Ok((7, s.len(), s.to_vec())),