@@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range};
66use  crate :: arch:: asm; 
77use  crate :: cell:: UnsafeCell ; 
88use  crate :: convert:: TryInto ; 
9- use  crate :: mem:: { self ,  ManuallyDrop } ; 
9+ use  crate :: mem:: { self ,  ManuallyDrop ,   MaybeUninit } ; 
1010use  crate :: ops:: { CoerceUnsized ,  Deref ,  DerefMut ,  Index ,  IndexMut } ; 
1111use  crate :: pin:: PinCoerceUnsized ; 
1212use  crate :: ptr:: { self ,  NonNull } ; 
@@ -209,6 +209,45 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
209209    } 
210210} 
211211
212+ /// A type which can a destination for safely copying from userspace. 
213+ /// 
214+ /// # Safety 
215+ /// 
216+ /// Requires that `T` and `Self` have identical layouts. 
217+ #[ unstable( feature = "sgx_platform" ,  issue = "56975" ) ]  
218+ pub  unsafe  trait  UserSafeCopyDestination < T :  ?Sized >  { 
219+     /// Returns a pointer for writing to the value. 
220+ fn  as_mut_ptr ( & mut  self )  -> * mut  T ; 
221+ } 
222+ 
223+ #[ unstable( feature = "sgx_platform" ,  issue = "56975" ) ]  
224+ unsafe  impl < T >  UserSafeCopyDestination < T >  for  T  { 
225+     fn  as_mut_ptr ( & mut  self )  -> * mut  T  { 
226+         self  as  _ 
227+     } 
228+ } 
229+ 
230+ #[ unstable( feature = "sgx_platform" ,  issue = "56975" ) ]  
231+ unsafe  impl < T >  UserSafeCopyDestination < [ T ] >  for  [ T ]  { 
232+     fn  as_mut_ptr ( & mut  self )  -> * mut  [ T ]  { 
233+         self  as  _ 
234+     } 
235+ } 
236+ 
237+ #[ unstable( feature = "sgx_platform" ,  issue = "56975" ) ]  
238+ unsafe  impl < T >  UserSafeCopyDestination < T >  for  MaybeUninit < T >  { 
239+     fn  as_mut_ptr ( & mut  self )  -> * mut  T  { 
240+         self  as  * mut  Self  as  _ 
241+     } 
242+ } 
243+ 
244+ #[ unstable( feature = "sgx_platform" ,  issue = "56975" ) ]  
245+ unsafe  impl < T >  UserSafeCopyDestination < [ T ] >  for  [ MaybeUninit < T > ]  { 
246+     fn  as_mut_ptr ( & mut  self )  -> * mut  [ T ]  { 
247+         self  as  * mut  Self  as  _ 
248+     } 
249+ } 
250+ 
212251#[ unstable( feature = "sgx_platform" ,  issue = "56975" ) ]  
213252impl < T :  ?Sized >  User < T > 
214253where 
@@ -544,12 +583,12 @@ where
544583/// # Panics 
545584/// This function panics if the destination doesn't have the same size as 
546585/// the source. This can happen for dynamically-sized types such as slices. 
547- pub  fn  copy_to_enclave ( & self ,  dest :  & mut  T )  { 
586+ pub  fn  copy_to_enclave < U :  ? Sized  +  UserSafeCopyDestination < T > > ( & self ,  dest :  & mut  U )  { 
548587        unsafe  { 
549588            assert_eq ! ( size_of_val( dest) ,  size_of_val( & * self . 0 . get( ) ) ) ; 
550589            copy_from_userspace ( 
551590                self . 0 . get ( )  as  * const  T  as  * const  u8 , 
552-                 dest  as   * mut   T  as  * mut  u8 , 
591+                 dest. as_mut_ptr ( )  as  * mut  u8 , 
553592                size_of_val ( dest) , 
554593            ) ; 
555594        } 
@@ -639,25 +678,18 @@ where
639678        unsafe  {  ( * self . 0 . get ( ) ) . len ( )  } 
640679    } 
641680
642-     /// Copies the value from user memory and place it into `dest`. Afterwards, 
643- /// `dest` will contain exactly `self.len()` elements. 
644- /// 
645- /// # Panics 
646- /// This function panics if the destination doesn't have the same size as 
647- /// the source. This can happen for dynamically-sized types such as slices. 
648- pub  fn  copy_to_enclave_vec ( & self ,  dest :  & mut  Vec < T > )  { 
649-         if  let  Some ( missing)  = self . len ( ) . checked_sub ( dest. capacity ( ) )  { 
650-             dest. reserve ( missing) 
651-         } 
681+     /// Copies the value from user memory and appends it to `dest`. 
682+ pub  fn  append_to_enclave_vec ( & self ,  dest :  & mut  Vec < T > )  { 
683+         dest. reserve ( self . len ( ) ) ; 
684+         self . copy_to_enclave ( & mut  dest. spare_capacity_mut ( ) [ ..self . len ( ) ] ) ; 
652685        // SAFETY: We reserve enough space above. 
653-         unsafe  {  dest. set_len ( self . len ( ) )  } ; 
654-         self . copy_to_enclave ( & mut  dest[ ..] ) ; 
686+         unsafe  {  dest. set_len ( dest. len ( )  + self . len ( ) )  } ; 
655687    } 
656688
657689    /// Copies the value from user memory into a vector in enclave memory. 
658690pub  fn  to_enclave ( & self )  -> Vec < T >  { 
659691        let  mut  ret = Vec :: with_capacity ( self . len ( ) ) ; 
660-         self . copy_to_enclave_vec ( & mut  ret) ; 
692+         self . append_to_enclave_vec ( & mut  ret) ; 
661693        ret
662694    } 
663695
0 commit comments