@@ -21,11 +21,30 @@ extern crate std;
21
21
#[ cfg( feature = "std" ) ]
22
22
use std:: boxed:: Box ;
23
23
24
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
25
+ #[ macro_use]
26
+ extern crate lazy_static;
27
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
28
+ use std:: collections:: HashSet ;
29
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
30
+ use std:: sync:: RwLock ;
31
+
24
32
#[ cfg( all( feature = "std" , feature = "c-types" ) ) ]
25
33
pub mod c;
26
34
27
35
pub mod error;
28
36
37
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
38
+ lazy_static ! {
39
+ static ref LENT : RwLock <HashSet <usize >> = { RwLock :: new( HashSet :: new( ) ) } ;
40
+ }
41
+
42
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
43
+ #[ inline]
44
+ fn is_lent < T > ( pointer : * const T ) -> bool {
45
+ return LENT . read ( ) . unwrap ( ) . contains ( & ( pointer as usize ) ) ;
46
+ }
47
+
29
48
#[ inline]
30
49
fn null_error_check < T > ( pointer : * const T ) -> Result < ( ) , crate :: error:: PointerError > {
31
50
if pointer. is_null ( ) {
@@ -41,7 +60,10 @@ fn null_error_check<T>(pointer: *const T) -> Result<(), crate::error::PointerErr
41
60
#[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
42
61
#[ inline]
43
62
pub fn raw < T > ( data : T ) -> * mut T {
44
- return Box :: into_raw ( Box :: new ( data) ) ;
63
+ let pointer = Box :: into_raw ( Box :: new ( data) ) ;
64
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
65
+ LENT . write ( ) . unwrap ( ) . insert ( pointer as usize ) ;
66
+ return pointer;
45
67
}
46
68
47
69
/// Call to [`own_back<T>()`] ignoring the result.
@@ -78,8 +100,13 @@ pub unsafe fn free<T>(pointer: *mut T) {
78
100
#[ inline]
79
101
pub unsafe fn own_back < T > ( pointer : * mut T ) -> Result < T , crate :: error:: PointerError > {
80
102
null_error_check ( pointer) ?;
81
- // CAUTION: this is the unsafe part of the function.
82
- let boxed = Box :: from_raw ( pointer) ;
103
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
104
+ if !is_lent ( pointer) {
105
+ return Err ( crate :: error:: PointerError :: Invalid ) ;
106
+ }
107
+ let boxed = { Box :: from_raw ( pointer) } ;
108
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
109
+ LENT . write ( ) . unwrap ( ) . remove ( & ( pointer as usize ) ) ;
83
110
return Ok ( * boxed) ;
84
111
}
85
112
@@ -98,7 +125,10 @@ pub unsafe fn own_back<T>(pointer: *mut T) -> Result<T, crate::error::PointerErr
98
125
#[ inline]
99
126
pub unsafe fn object < ' a , T > ( pointer : * const T ) -> Result < & ' a T , crate :: error:: PointerError > {
100
127
null_error_check ( pointer) ?;
101
- // CAUTION: this is unsafe
128
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
129
+ if !is_lent ( pointer) {
130
+ return Err ( crate :: error:: PointerError :: Invalid ) ;
131
+ }
102
132
return Ok ( & * pointer) ;
103
133
}
104
134
@@ -117,6 +147,9 @@ pub unsafe fn object<'a, T>(pointer: *const T) -> Result<&'a T, crate::error::Po
117
147
#[ inline]
118
148
pub unsafe fn mut_object < ' a , T > ( pointer : * mut T ) -> Result < & ' a mut T , crate :: error:: PointerError > {
119
149
null_error_check ( pointer) ?;
120
- // CAUTION: this is unsafe
150
+ #[ cfg( all( feature = "std" , feature = "lender" ) ) ]
151
+ if !is_lent ( pointer) {
152
+ return Err ( crate :: error:: PointerError :: Invalid ) ;
153
+ }
121
154
return Ok ( & mut * pointer) ;
122
155
}
0 commit comments