idl: Disallow account discriminators that can conflict with the `zero` constraint (#3365)

This commit is contained in:
acheron 2024-11-15 00:15:24 +01:00 committed by GitHub
parent ef7b3ed3df
commit c4ce2d771b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 0 deletions

View File

@ -60,6 +60,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- avm: Add Windows support for renaming anchor binary ([#3325](https://github.com/coral-xyz/anchor/pull/3325)).
- cli: Add optional `package-manager` flag in `init` command to set package manager field in Anchor.toml ([#3328](https://github.com/coral-xyz/anchor/pull/3328)).
- cli: Add test template for [Mollusk](https://github.com/buffalojoec/mollusk) ([#3352](https://github.com/coral-xyz/anchor/pull/3352)).
- idl: Disallow account discriminators that can conflict with the `zero` constraint ([#3365](https://github.com/coral-xyz/anchor/pull/3365)).
### Fixes

View File

@ -404,5 +404,35 @@ fn verify(idl: &Idl) -> Result<()> {
));
}
// Disallow account discriminators that can conflict with the `zero` constraint.
//
// Problematic scenario:
//
// 1. Account 1's discriminator starts with 0 (but not all 0s, since that's disallowed)
// 2. Account 2's discriminator is a 1-byte custom discriminator
// 3. Account 2 gets initialized using the `zero` constraint.
//
// In this case, it's possible to pass an already initialized Account 1 to a place that expects
// non-initialized Account 2, because the first byte of Account 1 is also 0, which is what the
// `zero` constraint checks.
for account in &idl.accounts {
let zero_count = account
.discriminator
.iter()
.take_while(|b| **b == 0)
.count();
if let Some(account2) = idl
.accounts
.iter()
.find(|acc| acc.discriminator.len() <= zero_count)
{
return Err(anyhow!(
"Accounts may allow substitution when used with the `zero` constraint: `{}` `{}`",
account.name,
account2.name
));
}
}
Ok(())
}