mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-16 10:28:05 +00:00
fix: Upgrade to v0.3.8 and fix parsing security issues
- Upgrade to version 0.3.8 - Add data length validation to prevent out-of-bounds access - Fix boundary check issues in all protocol parsers
This commit is contained in:
@@ -136,6 +136,9 @@ pub fn pool_state_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < POOL_STATE_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(pool_state) = pool_state_decode(&account.data[8..POOL_STATE_SIZE + 8]) {
|
||||
Some(Box::new(BonkPoolStateAccountEvent {
|
||||
metadata,
|
||||
@@ -184,6 +187,9 @@ pub fn global_config_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < GLOBAL_CONFIG_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(global_config) = global_config_decode(&account.data[8..GLOBAL_CONFIG_SIZE + 8]) {
|
||||
Some(Box::new(BonkGlobalConfigAccountEvent {
|
||||
metadata,
|
||||
@@ -227,6 +233,9 @@ pub fn platform_config_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < PLATFORM_CONFIG_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(platform_config) =
|
||||
platform_config_decode(&account.data[8..PLATFORM_CONFIG_SIZE + 8])
|
||||
{
|
||||
|
||||
@@ -35,6 +35,9 @@ pub fn bonding_curve_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < BONDING_CURVE_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(bonding_curve) = bonding_curve_decode(&account.data[8..BONDING_CURVE_SIZE + 8]) {
|
||||
Some(Box::new(PumpFunBondingCurveAccountEvent {
|
||||
metadata,
|
||||
@@ -82,6 +85,9 @@ pub fn global_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < GLOBAL_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(global) = global_decode(&account.data[8..GLOBAL_SIZE + 8]) {
|
||||
Some(Box::new(PumpFunGlobalAccountEvent {
|
||||
metadata,
|
||||
|
||||
@@ -37,6 +37,9 @@ pub fn global_config_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < GLOBAL_CONFIG_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(config) = global_config_decode(&account.data[8..GLOBAL_CONFIG_SIZE + 8]) {
|
||||
Some(Box::new(PumpSwapGlobalConfigAccountEvent {
|
||||
metadata,
|
||||
@@ -79,6 +82,9 @@ pub fn pool_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < POOL_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(pool) = pool_decode(&account.data[8..POOL_SIZE + 8]) {
|
||||
Some(Box::new(PumpSwapPoolAccountEvent {
|
||||
metadata,
|
||||
|
||||
@@ -80,6 +80,9 @@ pub struct AmmInfo {
|
||||
pub const AMM_INFO_SIZE: usize = 752;
|
||||
|
||||
pub fn amm_info_decode(data: &[u8]) -> Option<AmmInfo> {
|
||||
if data.len() < AMM_INFO_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<AmmInfo>(&data[..AMM_INFO_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -134,5 +137,8 @@ pub struct MarketState {
|
||||
pub const MARKET_STATE_SIZE: usize = 388;
|
||||
|
||||
pub fn market_state_decode(data: &[u8]) -> Option<MarketState> {
|
||||
if data.len() < MARKET_STATE_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<MarketState>(&data[..MARKET_STATE_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ pub struct AmmConfig {
|
||||
pub const AMM_CONFIG_SIZE: usize = 1 + 2 + 32 + 4 * 2 + 2 + 4 * 2 + 32 + 8 * 3;
|
||||
|
||||
pub fn amm_config_decode(data: &[u8]) -> Option<AmmConfig> {
|
||||
if data.len() < AMM_CONFIG_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<AmmConfig>(&data[..AMM_CONFIG_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -38,7 +41,7 @@ pub fn amm_config_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < AMM_CONFIG_SIZE {
|
||||
if account.data.len() < AMM_CONFIG_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(amm_config) = amm_config_decode(&account.data[8..AMM_CONFIG_SIZE + 8]) {
|
||||
@@ -116,6 +119,9 @@ pub struct PoolState {
|
||||
pub const POOL_STATE_SIZE: usize = 1536;
|
||||
|
||||
pub fn pool_state_decode(data: &[u8]) -> Option<PoolState> {
|
||||
if data.len() < POOL_STATE_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<PoolState>(&data[..POOL_STATE_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -123,7 +129,7 @@ pub fn pool_state_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < POOL_STATE_SIZE {
|
||||
if account.data.len() < POOL_STATE_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(pool_state) = pool_state_decode(&account.data[8..POOL_STATE_SIZE + 8]) {
|
||||
@@ -194,6 +200,9 @@ impl Default for TickArrayState {
|
||||
pub const TICK_ARRAY_STATE_SIZE: usize = 10232;
|
||||
|
||||
pub fn tick_array_state_decode(data: &[u8]) -> Option<TickArrayState> {
|
||||
if data.len() < TICK_ARRAY_STATE_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<TickArrayState>(&data[..TICK_ARRAY_STATE_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -201,7 +210,7 @@ pub fn tick_array_state_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < TICK_ARRAY_STATE_SIZE {
|
||||
if account.data.len() < TICK_ARRAY_STATE_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(tick_array_state) =
|
||||
|
||||
@@ -30,6 +30,9 @@ pub struct AmmConfig {
|
||||
pub const AMM_CONFIG_SIZE: usize = 228;
|
||||
|
||||
pub fn amm_config_decode(data: &[u8]) -> Option<AmmConfig> {
|
||||
if data.len() < AMM_CONFIG_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<AmmConfig>(&data[..AMM_CONFIG_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -37,7 +40,7 @@ pub fn amm_config_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < AMM_CONFIG_SIZE {
|
||||
if account.data.len() < AMM_CONFIG_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(amm_config) = amm_config_decode(&account.data[8..AMM_CONFIG_SIZE + 8]) {
|
||||
@@ -85,6 +88,9 @@ pub struct PoolState {
|
||||
pub const POOL_STATE_SIZE: usize = 629;
|
||||
|
||||
pub fn pool_state_decode(data: &[u8]) -> Option<PoolState> {
|
||||
if data.len() < POOL_STATE_SIZE {
|
||||
return None;
|
||||
}
|
||||
borsh::from_slice::<PoolState>(&data[..POOL_STATE_SIZE]).ok()
|
||||
}
|
||||
|
||||
@@ -92,7 +98,7 @@ pub fn pool_state_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
if account.data.len() < POOL_STATE_SIZE {
|
||||
if account.data.len() < POOL_STATE_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(pool_state) = pool_state_decode(&account.data[8..POOL_STATE_SIZE + 8]) {
|
||||
|
||||
Reference in New Issue
Block a user