Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 8de9536

Browse files
author
Joe C
authored
token-2022: adjust PodAccount initialized check (#6953)
1 parent 3a71851 commit 8de9536

File tree

2 files changed

+126
-3
lines changed

2 files changed

+126
-3
lines changed

token/program-2022/src/extension/mod.rs

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,9 @@ mod test {
15121512
pubkey::Pubkey,
15131513
},
15141514
spl_pod::{
1515-
bytemuck::pod_bytes_of, optional_keys::OptionalNonZeroPubkey, primitives::PodU64,
1515+
bytemuck::pod_bytes_of,
1516+
optional_keys::OptionalNonZeroPubkey,
1517+
primitives::{PodBool, PodU64},
15161518
},
15171519
transfer_fee::test::test_transfer_fee_config,
15181520
};
@@ -1575,8 +1577,28 @@ mod test {
15751577
1, 1, // data
15761578
];
15771579

1580+
const ACCOUNT_WITH_EXTENSION: &[u8] = &[
1581+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1582+
1, 1, // mint
1583+
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1584+
2, 2, // owner
1585+
3, 0, 0, 0, 0, 0, 0, 0, // amount
1586+
1, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1587+
4, 4, 4, 4, 4, 4, // delegate
1588+
2, // account state
1589+
1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, // is native
1590+
6, 0, 0, 0, 0, 0, 0, 0, // delegated amount
1591+
1, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1592+
7, 7, 7, 7, 7, 7, // close authority
1593+
2, // account type
1594+
15, 0, // extension type
1595+
1, 0, // length
1596+
1, // data
1597+
];
1598+
15781599
#[test]
15791600
fn unpack_opaque_buffer() {
1601+
// Mint
15801602
let state = PodStateWithExtensions::<PodMint>::unpack(MINT_WITH_EXTENSION).unwrap();
15811603
assert_eq!(state.base, &TEST_POD_MINT);
15821604
let extension = state.get_extension::<MintCloseAuthority>().unwrap();
@@ -1598,10 +1620,28 @@ mod test {
15981620
let mut test_mint = TEST_MINT_SLICE.to_vec();
15991621
let state = PodStateWithExtensionsMut::<PodMint>::unpack(&mut test_mint).unwrap();
16001622
assert_eq!(state.base, &TEST_POD_MINT);
1623+
1624+
// Account
1625+
let state = PodStateWithExtensions::<PodAccount>::unpack(ACCOUNT_WITH_EXTENSION).unwrap();
1626+
assert_eq!(state.base, &TEST_POD_ACCOUNT);
1627+
let extension = state.get_extension::<TransferHookAccount>().unwrap();
1628+
let transferring = PodBool::from(true);
1629+
assert_eq!(extension.transferring, transferring);
1630+
assert_eq!(
1631+
PodStateWithExtensions::<PodMint>::unpack(ACCOUNT_WITH_EXTENSION),
1632+
Err(ProgramError::InvalidAccountData)
1633+
);
1634+
1635+
let state = PodStateWithExtensions::<PodAccount>::unpack(TEST_ACCOUNT_SLICE).unwrap();
1636+
assert_eq!(state.base, &TEST_POD_ACCOUNT);
1637+
1638+
let mut test_account = TEST_ACCOUNT_SLICE.to_vec();
1639+
let state = PodStateWithExtensionsMut::<PodAccount>::unpack(&mut test_account).unwrap();
1640+
assert_eq!(state.base, &TEST_POD_ACCOUNT);
16011641
}
16021642

16031643
#[test]
1604-
fn fail_unpack_opaque_buffer() {
1644+
fn mint_fail_unpack_opaque_buffer() {
16051645
// input buffer too small
16061646
let mut buffer = vec![0, 3];
16071647
assert_eq!(
@@ -1679,6 +1719,89 @@ mod test {
16791719
);
16801720
}
16811721

1722+
#[test]
1723+
fn account_fail_unpack_opaque_buffer() {
1724+
// input buffer too small
1725+
let mut buffer = vec![0, 3];
1726+
assert_eq!(
1727+
PodStateWithExtensions::<PodAccount>::unpack(&buffer),
1728+
Err(ProgramError::InvalidAccountData)
1729+
);
1730+
assert_eq!(
1731+
PodStateWithExtensionsMut::<PodAccount>::unpack(&mut buffer),
1732+
Err(ProgramError::InvalidAccountData)
1733+
);
1734+
assert_eq!(
1735+
PodStateWithExtensionsMut::<PodAccount>::unpack_uninitialized(&mut buffer),
1736+
Err(ProgramError::InvalidAccountData)
1737+
);
1738+
1739+
// input buffer invalid
1740+
// all 5's - not a valid `AccountState`
1741+
let mut buffer = vec![5; BASE_ACCOUNT_LENGTH];
1742+
assert_eq!(
1743+
PodStateWithExtensions::<PodAccount>::unpack(&buffer),
1744+
Err(ProgramError::UninitializedAccount)
1745+
);
1746+
assert_eq!(
1747+
PodStateWithExtensionsMut::<PodAccount>::unpack(&mut buffer),
1748+
Err(ProgramError::UninitializedAccount)
1749+
);
1750+
1751+
// tweak the account type
1752+
let mut buffer = ACCOUNT_WITH_EXTENSION.to_vec();
1753+
buffer[BASE_ACCOUNT_LENGTH] = 3;
1754+
assert_eq!(
1755+
PodStateWithExtensions::<PodAccount>::unpack(&buffer),
1756+
Err(ProgramError::InvalidAccountData)
1757+
);
1758+
1759+
// clear the state byte
1760+
let mut buffer = ACCOUNT_WITH_EXTENSION.to_vec();
1761+
buffer[108] = 0;
1762+
assert_eq!(
1763+
PodStateWithExtensions::<PodAccount>::unpack(&buffer),
1764+
Err(ProgramError::UninitializedAccount)
1765+
);
1766+
1767+
// tweak the extension type
1768+
let mut buffer = ACCOUNT_WITH_EXTENSION.to_vec();
1769+
buffer[BASE_ACCOUNT_LENGTH + 1] = 12;
1770+
let state = PodStateWithExtensions::<PodAccount>::unpack(&buffer).unwrap();
1771+
assert_eq!(
1772+
state.get_extension::<TransferHookAccount>(),
1773+
Err(ProgramError::Custom(
1774+
TokenError::ExtensionTypeMismatch as u32
1775+
))
1776+
);
1777+
1778+
// tweak the length, too big
1779+
let mut buffer = ACCOUNT_WITH_EXTENSION.to_vec();
1780+
buffer[BASE_ACCOUNT_LENGTH + 3] = 100;
1781+
let state = PodStateWithExtensions::<PodAccount>::unpack(&buffer).unwrap();
1782+
assert_eq!(
1783+
state.get_extension::<TransferHookAccount>(),
1784+
Err(ProgramError::InvalidAccountData)
1785+
);
1786+
1787+
// tweak the length, too small
1788+
let mut buffer = ACCOUNT_WITH_EXTENSION.to_vec();
1789+
buffer[BASE_ACCOUNT_LENGTH + 3] = 10;
1790+
let state = PodStateWithExtensions::<PodAccount>::unpack(&buffer).unwrap();
1791+
assert_eq!(
1792+
state.get_extension::<TransferHookAccount>(),
1793+
Err(ProgramError::InvalidAccountData)
1794+
);
1795+
1796+
// data buffer is too small
1797+
let buffer = &ACCOUNT_WITH_EXTENSION[..ACCOUNT_WITH_EXTENSION.len() - 1];
1798+
let state = PodStateWithExtensions::<PodAccount>::unpack(buffer).unwrap();
1799+
assert_eq!(
1800+
state.get_extension::<TransferHookAccount>(),
1801+
Err(ProgramError::InvalidAccountData)
1802+
);
1803+
}
1804+
16821805
#[test]
16831806
fn get_extension_types_with_opaque_buffer() {
16841807
// incorrect due to the length

token/program-2022/src/pod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl PodAccount {
101101
}
102102
impl IsInitialized for PodAccount {
103103
fn is_initialized(&self) -> bool {
104-
self.state != 0
104+
self.state == AccountState::Initialized as u8 || self.state == AccountState::Frozen as u8
105105
}
106106
}
107107
impl PackedSizeOf for PodAccount {

0 commit comments

Comments
 (0)