Skip to content

Commit

Permalink
fix(syn-solidity): correctly parse invalid bytes* etc as custom
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Dec 22, 2024
1 parent ea88d20 commit 1c2d848
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
19 changes: 19 additions & 0 deletions crates/sol-types/tests/macros/sol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,3 +1223,22 @@ fn mapping_getters() {
let _ =
TestIbc::channelsReturn { _0: 0u8, _1: 0u32, _2: 0u32, _3: bytes![], _4: String::new() };
}

// https://github.com/alloy-rs/core/issues/829
#[test]
fn bytes64() {
sol! {
struct bytes64 {
bytes32 a;
bytes32 b;
}

function f(bytes64 x) public returns(bytes64 y) {
bytes64 z = x;
y = z;
}
}

let x = bytes64 { a: B256::ZERO, b: B256::ZERO };
assert_eq!(bytes64::abi_encode_packed(&x), alloy_primitives::B512::ZERO.as_slice());
}
8 changes: 5 additions & 3 deletions crates/syn-solidity/src/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,11 @@ impl Expr {
input.parse().map(Self::Delete)
} else if lookahead.peek(Ident::peek_any) {
let ident = input.call(Ident::parse_any)?;
match Type::parse_ident(ident.clone()) {
Ok(ty) if !ty.is_custom() => ty.parse_payable(input).map(Self::Type),
_ => Ok(Self::Ident(ident.into())),
let ty = Type::parse_ident(ident.clone()).parse_payable(input);
if ty.is_custom() {
Ok(Self::Ident(ident.into()))
} else {
Ok(Self::Type(ty))
}
} else {
Err(lookahead.error())
Expand Down
14 changes: 9 additions & 5 deletions crates/syn-solidity/src/type/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,11 @@ impl Type {
/// keyword separately.
///
/// [ref]: https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.elementaryTypeName
pub fn parse_ident(ident: Ident) -> Result<Self> {
pub fn parse_ident(ident: Ident) -> Self {
Self::try_parse_ident(ident.clone()).unwrap_or_else(|_| Self::custom(ident))
}

pub fn try_parse_ident(ident: Ident) -> Result<Self> {
let span = ident.span();
let s = ident.to_string();
let ret = match s.as_str() {
Expand Down Expand Up @@ -271,11 +275,11 @@ impl Type {

/// Parses the `payable` keyword from the input stream if this type is an
/// address.
pub fn parse_payable(mut self, input: ParseStream<'_>) -> Result<Self> {
pub fn parse_payable(mut self, input: ParseStream<'_>) -> Self {
if let Self::Address(_, opt @ None) = &mut self {
*opt = input.parse()?;
*opt = input.parse().unwrap();
}
Ok(self)
self
}

/// Returns whether this type is ABI-encoded as a single EVM word (32 bytes).
Expand Down Expand Up @@ -478,7 +482,7 @@ impl Type {
input.parse().map(Self::Custom)
} else if input.peek(Ident::peek_any) {
let ident = input.call(Ident::parse_any)?;
Self::parse_ident(ident)?.parse_payable(input)
Ok(Self::parse_ident(ident).parse_payable(input))
} else {
Err(input.error(
"expected a Solidity type: \
Expand Down

0 comments on commit 1c2d848

Please sign in to comment.