Explorar el Código

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

acheron hace 10 meses
padre
commit
c4ce2d771b
Se han modificado 2 ficheros con 31 adiciones y 0 borrados
  1. 1 0
      CHANGELOG.md
  2. 30 0
      idl/src/build.rs

+ 1 - 0
CHANGELOG.md

@@ -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
 

+ 30 - 0
idl/src/build.rs

@@ -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(())
 }