@@ -14,6 +14,7 @@ use crate::{
1414 instruction:: InstructionDiscriminant ,
1515 prelude:: * ,
1616 unsize:: { init:: UnsizedInit , FromOwned } ,
17+ ErrorCode ,
1718} ;
1819
1920use borsh:: { object_length, BorshSerialize } ;
@@ -104,8 +105,27 @@ pub trait SerializeType: UnsizedType {
104105
105106impl < T > SerializeType for T where T : UnsizedType + ?Sized { }
106107
108+ #[ inline]
109+ fn check_discriminant < T : ProgramAccount + ?Sized > ( data : & [ u8 ] ) -> Result < ( ) > {
110+ let discriminant_bytes = data. get ( 0 ..size_of_val ( & T :: DISCRIMINANT ) ) . ok_or_else ( || {
111+ error ! (
112+ ErrorCode :: DiscriminantMismatch ,
113+ "Not enough bytes for the discriminant"
114+ )
115+ } ) ?;
116+ let expected_discriminant = & T :: DISCRIMINANT ;
117+ ensure_eq ! (
118+ discriminant_bytes,
119+ bytes_of( expected_discriminant) ,
120+ ErrorCode :: DiscriminantMismatch ,
121+ ) ;
122+ Ok ( ( ) )
123+ }
124+
107125pub trait DeserializeAccount : UnsizedType + ProgramAccount {
108126 fn deserialize_account ( data : & [ u8 ] ) -> Result < Self :: Owned > {
127+ check_discriminant :: < Self > ( data)
128+ . ctx ( "Failed to validate the discriminant in DeserializeAccount" ) ?;
109129 <AccountDiscriminant < Self > as DeserializeType >:: deserialize_type ( data)
110130 }
111131}
@@ -114,11 +134,8 @@ impl<T> DeserializeAccount for T where T: UnsizedType + ProgramAccount + ?Sized
114134
115135pub trait DeserializeBorshAccount : BorshDeserialize + ProgramAccount {
116136 fn deserialize_account ( data : & [ u8 ] ) -> Result < Self > {
117- ensure ! (
118- data. len( ) > size_of:: <OwnerProgramDiscriminant <Self >>( ) ,
119- ProgramError :: AccountDataTooSmall ,
120- "Account data is too short to fit discriminant"
121- ) ;
137+ check_discriminant :: < Self > ( data)
138+ . ctx ( "Failed to validate the discriminant in DeserializeBorshAccount" ) ?;
122139 let data = & data[ size_of :: < OwnerProgramDiscriminant < Self > > ( ) ..] ;
123140 BorshDeserialize :: try_from_slice ( data) . map_err ( Into :: into)
124141 }
0 commit comments