From 53c571d759c88540062bf46fba11b4eca9a0044e Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Wed, 17 Apr 2024 14:35:07 +0200 Subject: [PATCH] =?UTF-8?q?tendermint:=20ensure=20ValidatorIndex=20is=20?= =?UTF-8?q?=E2=89=A4=20i32::MAX=20(#1411)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During conversion from usize to ValidatorIndex first convert the value to `i32` to make sure that the value is ≤ i32::MAX. Without that intermediate conversion, `u32::MAX as usize` is successfully converted into the index. --- .../1411-validator-index-i32-max-limit.md | 3 +++ tendermint/src/vote/validator_index.rs | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 .changelog/unreleased/improvements/1411-validator-index-i32-max-limit.md diff --git a/.changelog/unreleased/improvements/1411-validator-index-i32-max-limit.md b/.changelog/unreleased/improvements/1411-validator-index-i32-max-limit.md new file mode 100644 index 000000000..1ae1d3520 --- /dev/null +++ b/.changelog/unreleased/improvements/1411-validator-index-i32-max-limit.md @@ -0,0 +1,3 @@ +- `[tendermint]` Check `index ≤ i32::MAX` invariant when converting `usize` + into `ValidatorIndex`. + ([\#1411](https://github.com/informalsystems/tendermint-rs/issues/1411)) diff --git a/tendermint/src/vote/validator_index.rs b/tendermint/src/vote/validator_index.rs index 7f04967c1..d150c218a 100644 --- a/tendermint/src/vote/validator_index.rs +++ b/tendermint/src/vote/validator_index.rs @@ -44,9 +44,9 @@ impl TryFrom for ValidatorIndex { type Error = Error; fn try_from(value: usize) -> Result { - Ok(ValidatorIndex( - value.try_into().map_err(Error::integer_overflow)?, - )) + // Convert to i32 first to perform ≤ i32::MAX check. + let value = i32::try_from(value).map_err(Error::integer_overflow)?; + ValidatorIndex::try_from(value) } } @@ -88,3 +88,11 @@ impl FromStr for ValidatorIndex { ) } } + +#[test] +fn test_i32_max_limit() { + assert!(ValidatorIndex::try_from(u32::MAX).is_err()); + assert!(ValidatorIndex::try_from(u32::MAX as usize).is_err()); + let value = u32::MAX.to_string(); + assert!(ValidatorIndex::from_str(&value).is_err()); +}