@@ -930,8 +930,8 @@ mod tests {
930930 #[ test]
931931 fn test_borrow_data ( ) {
932932 // 8-bytes aligned account data.
933- let mut data = [ 0u64 ; size_of :: < Account > ( ) / size_of :: < u64 > ( ) ] ;
934- // Set the borrow state.
933+ let mut data = [ 0u64 ; size_of :: < Account > ( ) / size_of :: < u64 > ( ) + 1 ] ; // extra byte at end for account data
934+ // Set the borrow state.
935935 data[ 0 ] = NOT_BORROWED as u64 ;
936936 let account_info = AccountInfo {
937937 raw : data. as_mut_ptr ( ) as * mut Account ,
@@ -943,6 +943,13 @@ mod tests {
943943 assert ! ( account_info. can_borrow_lamports( ) . is_ok( ) ) ;
944944 assert ! ( account_info. can_borrow_mut_lamports( ) . is_ok( ) ) ;
945945
946+ // It should be sound to mutate the data through the data pointer while no other borrows exist
947+ let data_ptr = account_info. data_ptr ( ) ;
948+ unsafe {
949+ let data = core:: slice:: from_raw_parts_mut ( data_ptr, 1 ) ; // Data is 1 byte long!
950+ data[ 0 ] = 1 ;
951+ }
952+
946953 // Borrow immutable data (7 immutable borrows available).
947954 const ACCOUNT_REF : MaybeUninit < Ref < [ u8 ] > > = MaybeUninit :: < Ref < [ u8 ] > > :: uninit ( ) ;
948955 let mut refs = [ ACCOUNT_REF ; 7 ] ;
@@ -975,6 +982,8 @@ mod tests {
975982
976983 // Borrow mutable data.
977984 let ref_mut = account_info. try_borrow_mut_data ( ) . unwrap ( ) ;
985+ // It should be sound to get the data pointer while the data is borrowed as long as we don't use it
986+ let _data_ptr = account_info. data_ptr ( ) ;
978987
979988 // Check that we cannot borrow the data anymore.
980989 assert ! ( account_info. can_borrow_data( ) . is_err( ) ) ;
@@ -1076,10 +1085,17 @@ mod tests {
10761085 assert_eq ! ( account. data_len( ) , 100 ) ;
10771086 assert_eq ! ( account. resize_delta( ) , 0 ) ;
10781087
1088+ // We should be able to get the data pointer whenever as long as we don't use it while the data is borrowed
1089+ let data_ptr_before = account. data_ptr ( ) ;
1090+
10791091 // increase the size.
10801092
10811093 account. realloc ( 200 , false ) . unwrap ( ) ;
10821094
1095+ let data_ptr_after = account. data_ptr ( ) ;
1096+ // The data pointer should point to the same address regardless of the reallocation
1097+ assert_eq ! ( data_ptr_before, data_ptr_after) ;
1098+
10831099 assert_eq ! ( account. data_len( ) , 200 ) ;
10841100 assert_eq ! ( account. resize_delta( ) , 100 ) ;
10851101
0 commit comments