Skip to content

Commit

Permalink
idl: Disallow account discriminators that can conflict with the `zero…
Browse files Browse the repository at this point in the history
…` constraint (#3365)
  • Loading branch information
acheroncrypto authored Nov 14, 2024
1 parent ef7b3ed commit c4ce2d7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 30 additions & 0 deletions idl/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

0 comments on commit c4ce2d7

Please sign in to comment.