Explorar o código

check that unpack is tolerant of small sizes (#3416)

anatoly yakovenko %!s(int64=3) %!d(string=hai) anos
pai
achega
c2546035de
Modificáronse 1 ficheiros con 23 adicións e 0 borrados
  1. 23 0
      program/src/instruction.rs

+ 23 - 0
program/src/instruction.rs

@@ -519,6 +519,9 @@ impl<'a> TokenInstruction<'a> {
             10 => Self::FreezeAccount,
             11 => Self::ThawAccount,
             12 => {
+                if rest.len() < 8 {
+                    return Err(TokenError::InvalidInstruction.into());
+                }
                 let (amount, rest) = rest.split_at(8);
                 let amount = amount
                     .try_into()
@@ -530,6 +533,9 @@ impl<'a> TokenInstruction<'a> {
                 Self::TransferChecked { amount, decimals }
             }
             13 => {
+                if rest.len() < 8 {
+                    return Err(TokenError::InvalidInstruction.into());
+                }
                 let (amount, rest) = rest.split_at(8);
                 let amount = amount
                     .try_into()
@@ -541,6 +547,9 @@ impl<'a> TokenInstruction<'a> {
                 Self::ApproveChecked { amount, decimals }
             }
             14 => {
+                if rest.len() < 8 {
+                    return Err(TokenError::InvalidInstruction.into());
+                }
                 let (amount, rest) = rest.split_at(8);
                 let amount = amount
                     .try_into()
@@ -552,6 +561,9 @@ impl<'a> TokenInstruction<'a> {
                 Self::MintToChecked { amount, decimals }
             }
             15 => {
+                if rest.len() < 8 {
+                    return Err(TokenError::InvalidInstruction.into());
+                }
                 let (amount, rest) = rest.split_at(8);
                 let amount = amount
                     .try_into()
@@ -588,6 +600,9 @@ impl<'a> TokenInstruction<'a> {
             21 => Self::GetAccountDataSize,
             22 => Self::InitializeImmutableOwner,
             23 => {
+                if rest.len() < 8 {
+                    return Err(TokenError::InvalidInstruction.into());
+                }
                 let (amount, _rest) = rest.split_at(8);
                 let amount = amount
                     .try_into()
@@ -1689,4 +1704,12 @@ mod test {
         let unpacked = TokenInstruction::unpack(&expect).unwrap();
         assert_eq!(unpacked, check);
     }
+
+    #[test]
+    fn test_instruction_unpack_panic() {
+        for i in 0..255u8 {
+            let expect = Vec::from([i, 1, 0, 0, 0, 0, 0, 0, 0, 2]);
+            _ = TokenInstruction::unpack(&expect[0..2]);
+        }
+    }
 }