fix(rpc): treat number without 0x prefix as errors (#1895)

This commit is contained in:
Matthias Seitz
2023-03-21 20:35:48 +01:00
committed by GitHub
parent f2cb8bec63
commit 9af53aeecb

View File

@@ -6,7 +6,7 @@ use serde::{
ser::SerializeStruct,
Deserialize, Deserializer, Serialize, Serializer,
};
use std::{fmt, fmt::Formatter, ops::Deref, str::FromStr};
use std::{fmt, fmt::Formatter, num::ParseIntError, ops::Deref, str::FromStr};
/// Ethereum full block.
///
@@ -500,7 +500,7 @@ impl<'de> Deserialize<'de> for BlockNumberOrTag {
}
impl FromStr for BlockNumberOrTag {
type Err = String;
type Err = ParseBlockNumberError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let block = match s {
@@ -510,14 +510,18 @@ impl FromStr for BlockNumberOrTag {
"earliest" => Self::Earliest,
"pending" => Self::Pending,
_number => {
let hex_string = s.trim_start_matches("0x");
let number = u64::from_str_radix(hex_string, 16).map_err(|err| err.to_string());
BlockNumberOrTag::Number(number?)
if let Some(hex_val) = s.strip_prefix("0x") {
let number = u64::from_str_radix(hex_val, 16);
BlockNumberOrTag::Number(number?)
} else {
return Err(HexStringMissingPrefixError::default().into())
}
}
};
Ok(block)
}
}
impl fmt::Display for BlockNumberOrTag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@@ -531,6 +535,23 @@ impl fmt::Display for BlockNumberOrTag {
}
}
/// Error variants when parsing a [BlockNumberOrTag]
#[derive(Debug, thiserror::Error)]
pub enum ParseBlockNumberError {
/// Failed to parse hex value
#[error(transparent)]
ParseIntErr(#[from] ParseIntError),
/// Block numbers should be 0x-prefixed
#[error(transparent)]
MissingPrefix(#[from] HexStringMissingPrefixError),
}
/// Thrown when a 0x-prefixed hex string was expected
#[derive(Debug, Default, thiserror::Error)]
#[non_exhaustive]
#[error("hex string without 0x prefix")]
pub struct HexStringMissingPrefixError;
/// A block hash which may have
/// a boolean requireCanonical field.
/// If false, an RPC call should raise if a block
@@ -725,4 +746,11 @@ mod test {
);
assert_eq!(parsed, expected);
}
#[test]
fn serde_blocknumber_non_0xprefix() {
let s = "\"2\"";
let err = serde_json::from_str::<BlockNumberOrTag>(s).unwrap_err();
assert_eq!(err.to_string(), HexStringMissingPrefixError::default().to_string());
}
}