Skip to content

Commit

Permalink
fix: assert ascii chainID
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-starkware committed Sep 8, 2023
1 parent 357ce41 commit 154cf21
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
20 changes: 17 additions & 3 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ use serde::{Deserialize, Serialize};
use starknet_crypto::FieldElement;

use crate::hash::{pedersen_hash_array, StarkFelt, StarkHash};
use crate::serde_utils::{BytesAsHex, PrefixedBytesAsHex};
use crate::serde_utils::{deserialize_ascii_string, BytesAsHex, PrefixedBytesAsHex};
use crate::transaction::{Calldata, ContractAddressSalt};
use crate::{impl_from_through_intermediate, StarknetApiError};

/// A chain id.
/// A chain id. Must contain only ASCII characters.
#[derive(Clone, Debug, Display, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)]
pub struct ChainId(pub String);
pub struct ChainId(#[serde(deserialize_with = "deserialize_ascii_string")] String);

impl ChainId {
/// Returns a new [`ChainId`].
pub fn new(chain_id: String) -> Result<Self, StarknetApiError> {
match chain_id.chars().all(|c| c.is_ascii()) {
true => Ok(Self(chain_id)),
false => Err(StarknetApiError::OutOfRange { string: chain_id }),
}
}

/// Returns the chain id as a string.
pub fn as_str(&self) -> &str {
&self.0
}

/// Returns the chain id as a hex string.
pub fn as_hex(&self) -> String {
format!("0x{}", hex::encode(&self.0))
}
Expand Down
20 changes: 19 additions & 1 deletion src/serde_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
#[path = "serde_utils_test.rs"]
mod serde_utils_test;

use serde::de::{Deserialize, Visitor};
use serde::de::{Deserialize, Error as DeserializationError, Visitor};
use serde::ser::{Serialize, SerializeTuple};
use serde::Deserializer;
use serde_json::Value;

use crate::deprecated_contract_class::ContractClassAbiEntry;

Expand Down Expand Up @@ -144,3 +145,20 @@ where
Err(_) => Ok(None),
}
}

pub fn deserialize_ascii_string<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result<String, D::Error> {
let chian_id: _ = match Value::deserialize(deserializer)? {
Value::String(string) => match string.chars().all(|c| c.is_ascii()) {
true => string,
false => {
return Err(DeserializationError::custom(format!(
"Chain id ({string}) must contain only ASCII characters."
)));
}
},
_ => return Err(DeserializationError::custom("Cannot cast value into String.")),
};
Ok(chian_id)
}
14 changes: 14 additions & 0 deletions src/serde_utils_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,17 @@ fn deserialize_optional_contract_class_abi_entry_vector_none() {
let res: DummyContractClass = serde_json::from_str(json).unwrap();
assert_eq!(res, DummyContractClass { abi: None });
}

#[test]
fn chain_id_non_ascii() {
let chain_id_str = r#""חלודה""#;
let chain_id = serde_json::from_str::<crate::core::ChainId>(chain_id_str);
assert_matches!(chain_id, Err(serde_json::Error { .. }));
}

#[test]
fn valid_chain_id() {
let chain_id_str = r#""chain_ID""#;
let chain_id = serde_json::from_str::<crate::core::ChainId>(chain_id_str).unwrap();
assert_eq!(chain_id_str, serde_json::to_string(&chain_id).unwrap())
}

0 comments on commit 154cf21

Please sign in to comment.