Skip to content

Commit eb52e2c

Browse files
committed
check discriminant in client deser
1 parent 24e633f commit eb52e2c

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

star_frame/src/client.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::{
1414
instruction::InstructionDiscriminant,
1515
prelude::*,
1616
unsize::{init::UnsizedInit, FromOwned},
17+
ErrorCode,
1718
};
1819

1920
use borsh::{object_length, BorshSerialize};
@@ -104,8 +105,27 @@ pub trait SerializeType: UnsizedType {
104105

105106
impl<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+
107125
pub 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

115135
pub 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

Comments
 (0)