2
2
3
3
//! Traits for transmuting types.
4
4
5
+ use core:: simd:: ToBytes ;
5
6
/// Types for which any bit pattern is valid.
6
7
///
7
8
/// Not all types are valid for all values. For example, a `bool` must be either zero or one, so
8
9
/// reading arbitrary bytes into something that contains a `bool` is not okay.
9
10
///
10
11
/// It's okay for the type to have padding, as initializing those bytes has no effect.
11
12
///
13
+ /// # Example
14
+ ///
15
+ /// This example is how to use the FromBytes trait
16
+ /// ```
17
+ /// // Initialize a slice of bytes
18
+ /// let foo = &[1, 2, 3, 4];
19
+ ///
20
+ /// //Use the function implemented by trait in integer type
21
+ /// let result = u8::from_bytes(foo);
22
+ ///
23
+ /// assert_eq!(*result, 0x4030201);
24
+ /// ```
12
25
/// # Safety
13
26
///
14
27
/// All bit-patterns must be valid for this type. This type must not have interior mutability.
15
- pub unsafe trait FromBytes { }
28
+ pub unsafe trait FromBytes {
29
+ ///Get an imutable slice of bytes and converts to a reference to Self
30
+ unsafe fn from_bytes ( slice_of_bytes : & [ u8 ] ) -> & Self ;
31
+ /// Get a mutable slice of bytes and converts to a reference to Self
32
+ ///
33
+ /// # Safety
34
+ ///
35
+ /// Bound ToBytes in order to avoid use with disallowed bit patterns
36
+ unsafe fn from_bytes_mut ( slice_of_bytes : & mut [ u8 ] ) -> & mut Self
37
+ where
38
+ Self : ToBytes ;
39
+ }
16
40
41
+ //Get a reference of slice of bytes and converts into a reference of integer or a slice with a defined size
17
42
macro_rules! impl_frombytes {
18
43
( $( $( { $( $generics: tt) * } ) ? $t: ty, ) * ) => {
19
44
// SAFETY: Safety comments written in the macro invocation.
20
- $( unsafe impl $( $( $generics) * ) ? FromBytes for $t { } ) *
45
+ $( unsafe impl $( $( $generics) * ) ? FromBytes for $t {
46
+ unsafe fn from_bytes( slice_of_bytes: & [ u8 ] ) -> & Self
47
+ {
48
+ unsafe {
49
+ let slice_ptr = slice_of_bytes. as_ptr( ) as * const Self ;
50
+ & * slice_ptr
51
+ }
52
+ }
53
+
54
+ unsafe fn from_bytes_mut( slice_of_bytes: & mut [ u8 ] ) -> & mut Self
55
+ where
56
+ Self : ToBytes ,
57
+ {
58
+ unsafe {
59
+ let slice_ptr = slice_of_bytes. as_mut_ptr( ) as * mut Self ;
60
+ & mut * slice_ptr
61
+ }
62
+
63
+ }
64
+ } ) *
21
65
} ;
22
66
}
23
67
@@ -28,44 +72,52 @@ impl_frombytes! {
28
72
29
73
// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
30
74
// patterns are also acceptable for arrays of that type.
31
- { <T : FromBytes >} [ T ] ,
32
75
{ <T : FromBytes , const N : usize >} [ T ; N ] ,
33
76
}
34
77
35
- /// Types that can be viewed as an immutable slice of initialized bytes.
78
+ /// Get a reference of slice of bytes and converts into a reference of an array of integers
36
79
///
37
- /// If a struct implements this trait, then it is okay to copy it byte-for-byte to userspace. This
38
- /// means that it should not have any padding, as padding bytes are uninitialized. Reading
39
- /// uninitialized memory is not just undefined behavior, it may even lead to leaking sensitive
40
- /// information on the stack to userspace.
80
+ /// Types for which any bit pattern is valid.
41
81
///
42
- /// The struct should also not hold kernel pointers, as kernel pointer addresses are also considered
43
- /// sensitive. However, leaking kernel pointers is not considered undefined behavior by Rust, so
44
- /// this is a correctness requirement, but not a safety requirement.
82
+ /// Not all types are valid for all values. For example, a `bool` must be either zero or one, so
83
+ /// reading arbitrary bytes into something that contains a `bool` is not okay.
45
84
///
46
- /// # Safety
85
+ /// It's okay for the type to have padding, as initializing those bytes has no effect.
47
86
///
48
- /// Values of this type may not contain any uninitialized bytes. This type must not have interior
49
- /// mutability.
50
- pub unsafe trait AsBytes { }
51
-
52
- macro_rules! impl_asbytes {
53
- ( $( $( { $( $generics: tt) * } ) ? $t: ty, ) * ) => {
54
- // SAFETY: Safety comments written in the macro invocation.
55
- $( unsafe impl $( $( $generics) * ) ? AsBytes for $t { } ) *
56
- } ;
57
- }
58
-
59
- impl_asbytes ! {
60
- // SAFETY: Instances of the following types have no uninitialized portions.
61
- u8 , u16 , u32 , u64 , usize ,
62
- i8 , i16 , i32 , i64 , isize ,
63
- bool ,
64
- char ,
65
- str ,
87
+ /// # Example
88
+ ///
89
+ /// This example is how to use the FromBytes trait
90
+ /// ```
91
+ /// // Initialize a slice of bytes
92
+ /// let foo = &[1, 2, 3, 4];
93
+ ///
94
+ /// //Use the function implemented by trait in integer type
95
+ /// let result = <[u32]>::from_bytes(slice_of_bytes);
96
+ ///
97
+ /// assert_eq!(*result, 0x4030201);
98
+ /// ```
99
+ // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
100
+ // patterns are also acceptable for arrays of that type.
101
+ unsafe impl < T : FromBytes > FromBytes for [ T ] {
102
+ unsafe fn from_bytes ( slice_of_bytes : & [ u8 ] ) -> & Self {
103
+ //Safety: Guarantee that all values are initiliazed
104
+ unsafe {
105
+ let slice_ptr = slice_of_bytes. as_ptr ( ) as * const T ;
106
+ let slice_len = slice_of_bytes. len ( ) / core:: mem:: size_of :: < T > ( ) ;
107
+ core:: slice:: from_raw_parts ( slice_ptr, slice_len)
108
+ }
109
+ }
66
110
67
- // SAFETY: If individual values in an array have no uninitialized portions, then the array
68
- // itself does not have any uninitialized portions either.
69
- { <T : AsBytes >} [ T ] ,
70
- { <T : AsBytes , const N : usize >} [ T ; N ] ,
111
+ //Safety: Guarantee that all values are initiliazed
112
+ unsafe fn from_bytes_mut ( slice_of_bytes : & mut [ u8 ] ) -> & mut Self
113
+ where
114
+ Self : ToBytes ,
115
+ {
116
+ //Safety: Guarantee that all values are initiliazed
117
+ unsafe {
118
+ let slice_ptr = slice_of_bytes. as_mut_ptr ( ) as * mut T ;
119
+ let slice_len = slice_of_bytes. len ( ) / core:: mem:: size_of :: < T > ( ) ;
120
+ core:: slice:: from_raw_parts_mut ( slice_ptr, slice_len)
121
+ }
122
+ }
71
123
}
0 commit comments