Don't panic if accounts are shorter than 8 bytes

This commit is contained in:
Christian Kamm 2022-09-01 12:00:09 +02:00
parent 5e0001afb8
commit 1f0cd62846
4 changed files with 24 additions and 4 deletions

View File

@ -38,6 +38,13 @@ impl AccountFetcher {
let acc = self.fetch_raw(address)?;
let data = acc.data();
if data.len() < 8 {
anyhow::bail!(
"account at {} has only {} bytes of data",
address,
data.len()
);
}
let disc_bytes = &data[0..8];
if disc_bytes != MangoAccount::discriminator() {
anyhow::bail!("not a mango account at {}", address);

View File

@ -12,7 +12,7 @@ pub fn is_mango_account<'a>(
group_id: &Pubkey,
) -> Option<MangoAccountRefWithHeader<'a>> {
let data = account.data();
if account.owner() != program_id || data.is_empty() {
if account.owner() != program_id || data.len() < 8 {
return None;
}
@ -37,7 +37,7 @@ pub fn is_mango_bank<'a>(
group_id: &Pubkey,
) -> Option<&'a Bank> {
let data = account.data();
if account.owner() != program_id || data.is_empty() {
if account.owner() != program_id || data.len() < 8 {
return None;
}
@ -61,7 +61,7 @@ pub fn is_mint_info<'a>(
group_id: &Pubkey,
) -> Option<&'a MintInfo> {
let data = account.data();
if account.owner() != program_id || data.is_empty() {
if account.owner() != program_id || data.len() < 8 {
return None;
}
@ -85,7 +85,7 @@ pub fn is_perp_market<'a>(
group_id: &Pubkey,
) -> Option<&'a PerpMarket> {
let data = account.data();
if account.owner() != program_id || data.is_empty() {
if account.owner() != program_id || data.len() < 8 {
return None;
}

View File

@ -157,6 +157,9 @@ impl<A: AccountReader> LoadZeroCopy for A {
}
let data = self.data();
if data.len() < 8 {
return Err(ErrorCode::AccountDiscriminatorNotFound.into());
}
let disc_bytes = array_ref![data, 0, 8];
if disc_bytes != &T::discriminator() {
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
@ -178,6 +181,9 @@ impl<'info, 'a> LoadMutZeroCopy for AccountInfoRefMut<'info, 'a> {
return Err(ErrorCode::AccountOwnedByWrongProgram.into());
}
if self.data.len() < 8 {
return Err(ErrorCode::AccountDiscriminatorNotFound.into());
}
let disc_bytes = array_ref![self.data, 0, 8];
if disc_bytes != &T::discriminator() {
return Err(ErrorCode::AccountDiscriminatorMismatch.into());
@ -202,6 +208,9 @@ impl<'info> LoadZeroCopyRef for AccountInfo<'info> {
}
let data = self.try_borrow_data()?;
if data.len() < 8 {
return Err(ErrorCode::AccountDiscriminatorNotFound.into());
}
let disc_bytes = array_ref![data, 0, 8];
if disc_bytes != &T::discriminator() {
@ -228,6 +237,9 @@ impl<'info> LoadMutZeroCopyRef for AccountInfo<'info> {
}
let data = self.try_borrow_mut_data()?;
if data.len() < 8 {
return Err(ErrorCode::AccountDiscriminatorNotFound.into());
}
let disc_bytes = array_ref![data, 0, 8];
if disc_bytes != &T::discriminator() {

View File

@ -189,6 +189,7 @@ fn can_load_as<'a, T: ZeroCopy + Owner>(
match load_result {
Err(Error::AnchorError(error))
if error.error_code_number == ErrorCode::AccountDiscriminatorMismatch as u32
|| error.error_code_number == ErrorCode::AccountDiscriminatorNotFound as u32
|| error.error_code_number == ErrorCode::AccountOwnedByWrongProgram as u32 =>
{
return None;