diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs b/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs index 36880e96..1fecc143 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs @@ -1,6 +1,8 @@ use super::*; use crate::storage_manager::SignedValueData; +const MAX_VALUE_CHANGED_SUBKEYS_LEN: usize = 512; + #[derive(Debug, Clone)] pub(in crate::rpc_processor) struct RPCOperationValueChanged { key: TypedKey, @@ -16,13 +18,21 @@ impl RPCOperationValueChanged { subkeys: ValueSubkeyRangeSet, count: u32, value: SignedValueData, - ) -> Self { - Self { + ) -> Result { + // Needed because RangeSetBlaze uses different types here all the time + #[allow(clippy::unnecessary_cast)] + let subkeys_len = subkeys.ranges_len() as usize; + + if subkeys_len > MAX_VALUE_CHANGED_SUBKEYS_LEN { + return Err(RPCError::protocol("ValueChanged subkeys length too long")); + } + + Ok(Self { key, subkeys, count, value, - } + }) } pub fn validate(&mut self, _validate_context: &RPCValidateContext) -> Result<(), RPCError> { @@ -62,6 +72,10 @@ impl RPCOperationValueChanged { let key = decode_typed_key(&k_reader)?; let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?; + if sk_reader.len() as usize > MAX_VALUE_CHANGED_SUBKEYS_LEN { + return Err(RPCError::protocol("ValueChanged subkeys length too long")); + } + let mut subkeys = ValueSubkeyRangeSet::new(); for skr in sk_reader.iter() { let vskr = (skr.get_start(), skr.get_end()); diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index d58c3198..de35c662 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -185,7 +185,7 @@ impl RPCOperationWatchValueQ { let mut sk_builder = builder.reborrow().init_subkeys( self.subkeys - .len() + .ranges_len() .try_into() .map_err(RPCError::map_internal("invalid subkey range list length"))?, ); diff --git a/veilid-core/src/rpc_processor/rpc_value_changed.rs b/veilid-core/src/rpc_processor/rpc_value_changed.rs index 555dd104..b0ba8c15 100644 --- a/veilid-core/src/rpc_processor/rpc_value_changed.rs +++ b/veilid-core/src/rpc_processor/rpc_value_changed.rs @@ -16,7 +16,7 @@ impl RPCProcessor { count: u32, value: SignedValueData, ) -> RPCNetworkResult<()> { - let value_changed = RPCOperationValueChanged::new(key, subkeys, count, value); + let value_changed = RPCOperationValueChanged::new(key, subkeys, count, value)?; let statement = RPCStatement::new(RPCStatementDetail::ValueChanged(Box::new(value_changed)));