safe_transmute/
trivial.rs

1//! Transmutation of trivial objects
2//!
3//! Functions in this module are guarded from out-of-bounds memory access and
4//! from unsafe transmutation target types through the use of the
5//! [`TriviallyTransmutable`](trait.TriviallyTransmutable.html)) trait.
6//!
7//! If a certain type can be safely constructed out of any byte combination,
8//! then it may implement this trait. This is the case for primitive integer
9//! types (e.g. `i32`, `u32`, `i64`), arrays of other trivially transmutable
10//! types, and `repr(C)` structs composed of trivially transmutable values.
11//!
12//! However, they are still not entirely safe because the source data may not
13//! be correctly aligned for reading and writing a value of the target type.
14//! The effects of this range from less performance (e.g. x86) to trapping or
15//! address flooring (e.g. ARM), but this is undefined behavior nonetheless.
16
17
18use self::super::guard::{PermissiveGuard, PedanticGuard, Guard};
19use self::super::base::{transmute_many, transmute_many_mut, from_bytes};
20#[cfg(feature = "alloc")]
21use self::super::base::transmute_vec;
22use self::super::Error;
23#[cfg(feature = "alloc")]
24use alloc::vec::Vec;
25
26
27/// Type that can be constructed from any combination of bytes.
28///
29/// A type `T` implementing this trait means that any arbitrary slice of bytes
30/// of length `size_of::<T>()` can be safely interpreted as a value of that
31/// type with support for unaligned memory access. In most (but not all)
32/// cases this is a [*POD class*](http://eel.is/c++draft/class#10) or a
33/// [*trivially copyable class*](http://eel.is/c++draft/class#6).
34///
35/// This serves as a marker trait for all functions in this module.
36///
37/// Enable the `const_generics` feature to implement this for arbitrary `[T: TriviallyTransmutable, N]` arrays,
38/// instead of just 1-32.
39/// This, of course, requires a sufficiently fresh rustc (at least 1.51).
40///
41/// *Warning*: if you transmute into a floating-point type you will have a chance to create a signaling NaN,
42/// which, while not illegal, can be unwieldy. Check out [`util::designalise_f{32,64}()`](util/index.html)
43/// for a remedy.
44///
45/// *Nota bene*: `bool` is not `TriviallyTransmutable` because they're restricted to
46/// being `0` or `1`, which means that an additional value check is required.
47///
48/// # Safety
49///
50/// It is only safe to implement `TriviallyTransmutable` for a type `T` if it
51/// is safe to read or write a value `T` at the pointer of an arbitrary slice
52/// `&[u8]`, of length `size_of<T>()`, as long as the same slice is
53/// *well aligned* in memory for reading and writing a `T`.
54///
55/// Consult the [Transmutes section](https://doc.rust-lang.org/nomicon/transmutes.html)
56/// of the Nomicon for more details.
57pub unsafe trait TriviallyTransmutable: Copy {}
58
59
60unsafe impl TriviallyTransmutable for u8 {}
61unsafe impl TriviallyTransmutable for i8 {}
62unsafe impl TriviallyTransmutable for u16 {}
63unsafe impl TriviallyTransmutable for i16 {}
64unsafe impl TriviallyTransmutable for u32 {}
65unsafe impl TriviallyTransmutable for i32 {}
66unsafe impl TriviallyTransmutable for u64 {}
67unsafe impl TriviallyTransmutable for i64 {}
68unsafe impl TriviallyTransmutable for usize {}
69unsafe impl TriviallyTransmutable for isize {}
70unsafe impl TriviallyTransmutable for f32 {}
71unsafe impl TriviallyTransmutable for f64 {}
72#[cfg(i128_type)]
73unsafe impl TriviallyTransmutable for u128 {}
74#[cfg(i128_type)]
75unsafe impl TriviallyTransmutable for i128 {}
76
77#[cfg(not(feature = "const_generics"))]
78mod trivially_transmutable_arrays {
79    use self::super::TriviallyTransmutable;
80    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 1] {}
81    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 2] {}
82    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 3] {}
83    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 4] {}
84    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 5] {}
85    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 6] {}
86    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 7] {}
87    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 8] {}
88    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 9] {}
89    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 10] {}
90    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 11] {}
91    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 12] {}
92    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 13] {}
93    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 14] {}
94    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 15] {}
95    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 16] {}
96    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 17] {}
97    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 18] {}
98    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 19] {}
99    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 20] {}
100    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 21] {}
101    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 22] {}
102    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 23] {}
103    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 24] {}
104    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 25] {}
105    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 26] {}
106    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 27] {}
107    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 28] {}
108    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 29] {}
109    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 30] {}
110    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 31] {}
111    unsafe impl<T: TriviallyTransmutable> TriviallyTransmutable for [T; 32] {}
112}
113
114#[cfg(feature = "const_generics")]
115unsafe impl<T: TriviallyTransmutable, const N: usize> TriviallyTransmutable for [T; N] {}
116
117/// Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
118///
119/// This function is equivalent to
120/// [`std::slice::align_to()`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to).
121///
122/// However, since both source and target types are [trivially transmutable](./trait.TriviallyTransmutable.html),
123/// the operation is always safe.
124///
125/// # Example
126///
127/// ```
128/// # use safe_transmute::trivial::align_to;
129/// let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
130/// let (prefix, shorts, suffix) = align_to::<_, u16>(&bytes);
131///
132/// // less_efficient_algorithm_for_bytes(prefix);
133/// // more_efficient_algorithm_for_aligned_shorts(shorts);
134/// // less_efficient_algorithm_for_bytes(suffix);
135///
136/// assert_eq!(prefix.len() + shorts.len() * 2 + suffix.len(), 7);
137/// ```
138pub fn align_to<S: TriviallyTransmutable, T: TriviallyTransmutable>(slice: &[S]) -> (&[S], &[T], &[S]) {
139    unsafe { slice.align_to::<T>() }
140}
141
142/// Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
143///
144/// This function is equivalent to
145/// [`std::slice::align_to_mut()`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut).
146///
147/// However, since both source and target types are [trivially transmutable](./trait.TriviallyTransmutable.html),
148/// the operation is always safe.
149///
150/// # Example
151///
152/// ```
153/// # use safe_transmute::trivial::align_to_mut;
154/// let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
155/// let (prefix, shorts, suffix) = align_to_mut::<_, u16>(&mut bytes);
156///
157/// // less_efficient_algorithm_for_bytes(prefix);
158/// // more_efficient_algorithm_for_aligned_shorts(shorts);
159/// // less_efficient_algorithm_for_bytes(suffix);
160///
161/// assert_eq!(prefix.len() + shorts.len() * 2 + suffix.len(), 7);
162/// ```
163pub fn align_to_mut<S: TriviallyTransmutable, T: TriviallyTransmutable>(slice: &mut [S]) -> (&mut [S], &mut [T], &mut [S]) {
164    unsafe { slice.align_to_mut::<T>() }
165}
166
167/// Transmute a byte slice into a single instance of a trivially transmutable type.
168///
169/// The byte slice must have at least enough bytes to fill a single instance of a type,
170/// extraneous data is ignored.
171///
172/// # Errors
173///
174/// An error is returned in one of the following situations:
175///
176/// - The data does not have enough bytes for a single value `T`.
177///
178/// # Safety
179///
180/// This function invokes undefined behavior if the data does not have a memory
181/// alignment compatible with `T`. If this cannot be ensured, you will have to
182/// make a copy of the data, or change how it was originally made.
183///
184/// # Examples
185///
186/// ```
187/// # use safe_transmute::trivial::transmute_trivial;
188/// # include!("../tests/test_util/le_to_native.rs");
189/// # fn main() {
190/// // Little-endian
191/// unsafe {
192/// # /*
193///     assert_eq!(transmute_trivial::<u32>(&[0x00, 0x00, 0x00, 0x01])?, 0x0100_0000);
194/// # */
195/// #   assert_eq!(transmute_trivial::<u32>(&Le2NAl4([0x00, 0x00, 0x00, 0x01]).le_to_native::<u32>()).unwrap(), 0x0100_0000);
196/// }
197/// # }
198/// ```
199pub unsafe fn transmute_trivial<T: TriviallyTransmutable>(bytes: &[u8]) -> Result<T, Error<u8, T>> {
200    from_bytes::<T>(bytes)
201}
202
203/// Transmute a byte slice into a single instance of a trivially transmutable type.
204///
205/// The byte slice must have exactly enough bytes to fill a single instance of a type.
206///
207/// # Errors
208///
209/// An error is returned in one of the following situations:
210///
211/// - The data does not have a memory alignment compatible with `T`. You will
212///   have to make a copy anyway, or modify how the data was originally made.
213/// - The data does not have enough bytes for a single value `T`.
214/// - The data has more bytes than those required to produce a single value `T`.
215///
216/// # Safety
217///
218/// This function invokes undefined behavior if the data does not have a memory
219/// alignment compatible with `T`. If this cannot be ensured, you will have to
220/// make a copy of the data, or change how it was originally made.
221///
222/// # Examples
223///
224/// ```
225/// # use safe_transmute::trivial::transmute_trivial_pedantic;
226/// # include!("../tests/test_util/le_to_native.rs");
227/// # fn main() {
228/// // Little-endian
229/// unsafe {
230/// # /*
231///     assert_eq!(transmute_trivial_pedantic::<u16>(&[0x0F, 0x0E])?, 0x0E0F);
232/// # */
233/// #   assert_eq!(transmute_trivial_pedantic::<u16>(&Le2NAl2([0x0F, 0x0E]).le_to_native::<u16>()).unwrap(), 0x0E0F);
234/// }
235/// # }
236/// ```
237pub unsafe fn transmute_trivial_pedantic<T: TriviallyTransmutable>(bytes: &[u8]) -> Result<T, Error<u8, T>> {
238    PedanticGuard::check::<T>(bytes)?;
239    from_bytes(bytes)
240}
241
242/// Transmute a byte slice into a single instance of a trivially transmutable type.
243///
244/// The byte slice must have exactly enough bytes to fill a single instance of a type.
245///
246/// # Errors
247///
248/// An error is returned if the data does not comply with the policies of the
249/// given guard `G`.
250///
251/// # Safety
252///
253/// This function invokes undefined behavior if the data does not have a memory
254/// alignment compatible with `T`. If this cannot be ensured, you will have to
255/// make a copy of the data, or change how it was originally made.
256///
257/// # Examples
258///
259/// ```
260/// # use safe_transmute::trivial::transmute_trivial_many;
261/// # use safe_transmute::SingleManyGuard;
262/// # include!("../tests/test_util/le_to_native.rs");
263/// # fn main() {
264/// // Little-endian
265/// unsafe {
266/// # /*
267///     assert_eq!(transmute_trivial_many::<u16, SingleManyGuard>(&[0x00, 0x01, 0x00, 0x02])?,
268/// # */
269/// #   assert_eq!(transmute_trivial_many::<u16, SingleManyGuard>(&Le2NAl4([0x00, 0x01, 0x00, 0x02]).le_to_native::<u16>()).unwrap(),
270///                &[0x0100, 0x0200]);
271/// }
272/// # }
273/// ```
274pub unsafe fn transmute_trivial_many<T: TriviallyTransmutable, G: Guard>(bytes: &[u8]) -> Result<&[T], Error<u8, T>> {
275    transmute_many::<T, G>(bytes)
276}
277
278/// Transmute a byte slice into a single instance of a trivially transmutable type.
279///
280/// The byte slice must have exactly enough bytes to fill a single instance of a type.
281///
282/// # Errors
283///
284/// An error is returned in one of the following situations:
285///
286/// - The data does not have enough bytes for a single value `T`.
287///
288/// # Safety
289///
290/// This function invokes undefined behavior if the data does not have a memory
291/// alignment compatible with `T`. If this cannot be ensured, you will have to
292/// make a copy of the data, or change how it was originally made.
293///
294/// # Examples
295///
296/// ```
297/// # use safe_transmute::trivial::transmute_trivial_many;
298/// # use safe_transmute::SingleManyGuard;
299/// # include!("../tests/test_util/le_to_native.rs");
300/// # fn main() {
301/// // Little-endian
302/// unsafe {
303/// # /*
304///     assert_eq!(transmute_trivial_many::<u16, SingleManyGuard>(&[0x00, 0x01, 0x00, 0x02])?,
305/// # */
306/// #   assert_eq!(transmute_trivial_many::<u16, SingleManyGuard>(&Le2NAl4([0x00, 0x01, 0x00, 0x02]).le_to_native::<u16>()).unwrap(),
307///                &[0x0100, 0x0200]);
308/// }
309/// # }
310/// ```
311pub unsafe fn transmute_trivial_many_mut<T: TriviallyTransmutable, G: Guard>(bytes: &mut [u8]) -> Result<&mut [T], Error<u8, T>> {
312    transmute_many_mut::<T, G>(bytes)
313}
314
315/// View a byte slice as a slice of a trivially transmutable type.
316///
317/// The resulting slice will have as many instances of a type as will fit, rounded down.
318#[deprecated(since = "0.11.0", note = "see `trivial::transmute_many()` with `PermissiveGuard` for the equivalent behavior")]
319pub unsafe fn guarded_transmute_pod_many_permissive<T: TriviallyTransmutable>(bytes: &[u8]) -> Result<&[T], Error<u8, T>> {
320    Ok(transmute_many::<T, PermissiveGuard>(bytes)?)
321}
322
323/// View a byte slice as a slice of a trivially transmutable type.
324///
325/// The byte slice must have at least enough bytes to fill a single instance of a type,
326/// and should not have extraneous data.
327#[deprecated(since = "0.11.0", note = "see `trivial::transmute_many()` with `PedanticGuard` for the equivalent behavior")]
328pub unsafe fn guarded_transmute_pod_many_pedantic<T: TriviallyTransmutable>(bytes: &[u8]) -> Result<&[T], Error<u8, T>> {
329    transmute_many::<T, PedanticGuard>(bytes)
330}
331
332
333/// Transform a vector into a vector of another element type.
334///
335/// The vector's allocated byte buffer (if already allocated) will be reused.
336///
337/// # Safety
338///
339/// Vector transmutations are **exceptionally** dangerous because of
340/// the constraints imposed by
341/// [`Vec::from_raw_parts()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.from_raw_parts).
342///
343/// Unless *all* of the following requirements are fulfilled, this operation
344/// may result in undefined behavior.
345///
346/// - The target type `T` must have the same size and minimum memory alignment
347///   requirements as the type `S`.
348///
349/// # Examples
350///
351/// ```
352/// # use safe_transmute::trivial::transmute_trivial_vec;
353/// unsafe {
354///     assert_eq!(
355///         transmute_trivial_vec::<u8, i8>(vec![0x00, 0x01, 0x00, 0x02]),
356///         vec![0x00, 0x01, 0x00, 0x02]
357///     );
358/// }
359/// ```
360#[cfg(feature = "alloc")]
361pub unsafe fn transmute_trivial_vec<S: TriviallyTransmutable, T: TriviallyTransmutable>(vec: Vec<S>) -> Vec<T> {
362    transmute_vec::<S, T>(vec)
363}