rust-xdr
rust-xdr copied to clipboard
Fix badness around fixed-size array decoding
The generated code for fixed size arrays is currently:
let mut buf: [#ty; #value as usize] = unsafe { ::std::mem::uninitialized() };
let sz = xdr_codec::unpack_array(input, &mut buf[..], #value as usize, None)?;
(buf, sz)
This is unsafe because the array is uninitialized, and unpack_array will replace each field as it unpacks each element - ie, it will try to destruct the old (uninitialized) value.
The safe way to do this is with std::ptr::write, which simply overwrites the pointer without dropping it:
fn uninit_ptr_setter<T>(p: &mut T, v: T) {
unsafe { ::std::ptr::write(p as *mut T, v) }
}
let mut buf: [#ty; #value as usize] = unsafe { ::std::mem::uninitialized() };
let sz = xdr_codec::unpack_array_with(input, &mut buf[..], #value as usize, uninit_ptr_setter, None)?;
(buf, sz)
but this still has problems if unpack_array_with() fails and leaves the array partially initialized - it's Drop will end up trying to destruct uninitialized elements.