Skip to content

Commit

Permalink
fixup! [move] Use u256 instead of bigint for parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
tzakian committed Oct 24, 2024
1 parent b04bcf7 commit 6b941b1
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ pub fn parse_u256(s: &str) -> Result<(U256, NumberFormat), U256FromStrError> {
// Parse an address from a decimal or hex encoding
pub fn parse_address_number(s: &str) -> Option<(AccountAddress, NumberFormat)> {
let (txt, base) = determine_num_text_and_base(s);
let txt = txt.replace('_', "");
let max_len = match base {
NumberFormat::Hex => AccountAddress::LENGTH * 2,
NumberFormat::Decimal => U256_MAX_DECIMAL_DIGITS,
Expand All @@ -458,7 +459,7 @@ pub fn parse_address_number(s: &str) -> Option<(AccountAddress, NumberFormat)> {
return None;
}
let parsed = U256::from_str_radix(
txt,
&txt,
match base {
NumberFormat::Hex => 16,
NumberFormat::Decimal => 10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ impl Token for TypeToken {
Some(':') => (Self::ColonColon, 2),
_ => bail!("unrecognized token: {}", s),
},
'0' if matches!(chars.peek(), Some('x') | Some('X')) => {
'0' if matches!(chars.peek(), Some('x')) => {
chars.next().unwrap();
match chars.next() {
Some(c) if c.is_ascii_hexdigit() || c == '_' => {
Some(c) if c.is_ascii_hexdigit() => {
// 0x + c + remaining
let len = 3 + chars
.take_while(|q| char::is_ascii_hexdigit(q) || *q == '_')
Expand All @@ -106,7 +106,9 @@ impl Token for TypeToken {
}
c if c.is_ascii_digit() => {
// c + remaining
let len = 1 + chars.take_while(char::is_ascii_digit).count();
let len = 1 + chars
.take_while(|c| c.is_ascii_digit() || *c == '_')
.count();
(Self::AddressIdent, len)
}
c if c.is_ascii_whitespace() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,47 @@ use num::BigUint;
use proptest::{prelude::*, proptest};
use std::str::FromStr;

const VALID_ADDRS: &[&str] = &[
"0x0",
"0x1",
"1",
"123",
"0x123",
"0x1234567890abcdef",
"100_00_00",
"0x0_0_0_0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0_00000_0000000000000000000000000000000000000000000000000_000000000",
"000000000000000000000000000000000000000000000000000000000000000000000000000000",
"00_0000000000000000000000000000000000000000000000000000000_00000000000000000_0000",
];

const INVALID_ADDRS: &[&str] = &[
"_x",
"0x",
"_0x0",
"_0",
"0x_",
"0x_00",
"+0x0",
"+0",
"0xg",
"0x0g",
"0X0",
"_0x0",
"_0x0_",
"_0",
"_0_",
"_00_",
"_0_0_",
"0x_00",
"0x00000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000_0000000",
"0x_0_00000_0000000000000000000000000000000000000000000000000_000000000",
"0000000000000000000000000000000000000000000000000000000000000000000000000000000",
"000_0000000000000000000000000000000000000000000000000000000_00000000000000000_0000",
];

#[allow(clippy::unreadable_literal)]
#[test]
fn tests_parse_value_positive() {
Expand Down Expand Up @@ -159,27 +200,6 @@ fn tests_parse_value_negative() {
}
}

#[test]
fn test_parse_type_negative() {
for s in &[
"_",
"_::_::_",
"0x1::_",
"0x1::__::_",
"0x1::_::__",
"0x1::_::foo",
"0x1::foo::_",
"0x1::_::_",
"0x1::bar::foo<0x1::_::foo>",
"0X1::bar::bar",
] {
assert!(
TypeTag::from_str(s).is_err(),
"Parsed type {s} but should have failed"
);
}
}

#[test]
fn test_parse_struct_negative() {
for s in &[
Expand All @@ -203,6 +223,9 @@ fn test_parse_struct_negative() {
"0x1::Foo::Foo,>",
"0x1::Foo::Foo>",
"0x1::Foo::Foo,",
"_0x0_0::a::a",
"_0x_00::a::a",
"_0_0::a::a",
] {
assert!(
TypeTag::from_str(s).is_err(),
Expand All @@ -214,7 +237,12 @@ fn test_parse_struct_negative() {
#[test]
fn test_type_type() {
for s in &[
"u8",
"u16",
"u32",
"u64",
"u128",
"u256",
"bool",
"vector<u8>",
"vector<vector<u64>>",
Expand All @@ -235,9 +263,27 @@ fn test_type_type() {
"0x1::__::__",
"0x1::_bar::_BAR<0x2::_____::______fooo______>",
"0x1::__::__<0x2::_____::______fooo______, 0xff::Bar____::_______foo>",
"0x0_0::a::a",
"0_0::a::a",
] {
assert!(TypeTag::from_str(s).is_ok(), "Failed to parse type {}", s);
}

for valid_addr in VALID_ADDRS {
assert!(
TypeTag::from_str(&format!("{valid_addr}::a::a")).is_ok(),
"Failed to parse type {}::a::a",
valid_addr
);
}

for invalid_addr in INVALID_ADDRS {
assert!(
TypeTag::from_str(&format!("{invalid_addr}::a::a")).is_err(),
"Parse type {}::a::a but should have failed",
invalid_addr
);
}
}

#[test]
Expand Down Expand Up @@ -282,17 +328,17 @@ fn test_parse_valid_struct_type() {

#[test]
fn test_parse_type_list() {
let valid_with_trails = vec![
let valid_with_trails = &[
"<u64,>",
"<u64, 0x0::a::a,>",
"<u64, 0x0::a::a, 0x0::a::a<0x0::a::a>,>",
];
let valid_no_trails = vec![
let valid_no_trails = &[
"<u64>",
"<u64, 0x0::a::a>",
"<u64, 0x0::a::a, 0x0::a::a<0x0::a::a>>",
];
let invalid = vec![
let invalid = &[
"<>",
"<,>",
"<u64,,>",
Expand Down Expand Up @@ -328,15 +374,15 @@ fn test_parse_type_list() {
assert!(parse_type_tags(t, true).is_ok());
}

for t in &valid_no_trails {
for t in valid_no_trails {
assert!(parse_type_tags(t, false).is_ok());
}

for t in &valid_with_trails {
for t in valid_with_trails {
assert!(parse_type_tags(t, false).is_err());
}

for t in &invalid {
for t in invalid {
assert!(parse_type_tags(t, true).is_err(), "parsed type {}", t);
assert!(parse_type_tags(t, false).is_err(), "parsed type {}", t);
}
Expand Down Expand Up @@ -397,6 +443,21 @@ fn parse_type_tags(s: &str, allow_trailing_delim: bool) -> anyhow::Result<Vec<Pa
})
}

#[test]
fn address_parsing() {
for valid_addr in VALID_ADDRS {
assert!(
ParsedAddress::parse(valid_addr).is_ok(),
"parsed address {}",
valid_addr
);
}

for invalid_addr in INVALID_ADDRS {
assert!(ParsedAddress::parse(invalid_addr).is_err());
}
}

proptest! {
#[test]
fn parse_type_tag_list(t in struct_type_gen0(), args in proptest::collection::vec(struct_type_gen0(), 1..=100)) {
Expand Down

0 comments on commit 6b941b1

Please sign in to comment.