Fix loadu16/32 so that they do not access invalid memory.

This commit is contained in:
KAMADA Ken'ichi 2016-10-28 05:37:39 +09:00
parent f99eae06ca
commit 2940079ae9
1 changed files with 14 additions and 2 deletions

View File

@ -24,6 +24,8 @@
// SUCH DAMAGE. // SUCH DAMAGE.
// //
use std::mem;
// This is a module to select endianess by using generics // This is a module to select endianess by using generics
// in order to avoid run-time dispatching penalty at the cost of // in order to avoid run-time dispatching penalty at the cost of
// increased object size. // increased object size.
@ -39,8 +41,12 @@ 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 {
let ptr = (buf.as_ptr() as usize + offset) as *const $int_type; // Check if the specified range of the slice is valid
let num = unsafe { ::std::mem::transmute(*ptr) }; // before transmute(). This will also detect the
// 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)
} }
) )
@ -99,4 +105,10 @@ mod tests {
assert!(dispatch_sub::<BigEndian> as *const () != assert!(dispatch_sub::<BigEndian> as *const () !=
dispatch_sub::<LittleEndian> as *const ()); dispatch_sub::<LittleEndian> as *const ());
} }
#[test]
#[should_panic(expected = "index 3 out of range for slice of length 2")]
fn out_of_range() {
BigEndian::loadu16(&[0x01, 0x02], 1);
}
} }