alloy_sol_types/abi/
decoder.rs

1// Copyright 2015-2020 Parity Technologies
2// Copyright 2023-2023 Alloy Contributors
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9//
10
11use crate::{
12    abi::{encode_sequence, token::TokenSeq, Token},
13    utils, Error, Result, Word,
14};
15use alloc::{borrow::Cow, vec::Vec};
16use core::{fmt, slice::SliceIndex};
17
18/// The decoder recursion limit.
19/// This is currently hardcoded, but may be parameterizable in the future.
20pub const RECURSION_LIMIT: u8 = 16;
21
22/// The [`Decoder`] wraps a byte slice with necessary info to progressively
23/// deserialize the bytes into a sequence of tokens.
24///
25/// # Usage Note
26///
27/// While the Decoder contains the necessary info, the actual deserialization
28/// is done in the [`crate::SolType`] trait.
29#[derive(Clone, Copy)]
30pub struct Decoder<'de> {
31    // The underlying buffer.
32    buf: &'de [u8],
33    // The current offset in the buffer.
34    offset: usize,
35    // Whether to validate type correctness and blob re-encoding.
36    validate: bool,
37    /// The current recursion depth.
38    depth: u8,
39}
40
41impl fmt::Debug for Decoder<'_> {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        let mut body = self.buf.chunks(32).map(hex::encode_prefixed).collect::<Vec<_>>();
44        body[self.offset / 32].push_str(" <-- Next Word");
45
46        f.debug_struct("Decoder")
47            .field("buf", &body)
48            .field("offset", &self.offset)
49            .field("validate", &self.validate)
50            .field("depth", &self.depth)
51            .finish()
52    }
53}
54
55impl fmt::Display for Decoder<'_> {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        writeln!(f, "Abi Decode Buffer")?;
58
59        for (i, chunk) in self.buf.chunks(32).enumerate() {
60            let idx = i * 32;
61            writeln!(
62                f,
63                "0x{idx:04x}: {}{}",
64                hex::encode_prefixed(chunk),
65                if idx == self.offset { " <-- Next Word" } else { "" }
66            )?;
67        }
68        Ok(())
69    }
70}
71
72impl<'de> Decoder<'de> {
73    /// Instantiate a new decoder from a byte slice and a validation flag.
74    ///
75    /// If `validate` is true, the decoder will check that the bytes conform to
76    /// expected type limitations, and that the decoded values can be re-encoded
77    /// to an identical bytestring.
78    #[inline]
79    pub const fn new(buf: &'de [u8], validate: bool) -> Self {
80        Self { buf, offset: 0, validate, depth: 0 }
81    }
82
83    /// Returns the current offset in the buffer.
84    #[inline]
85    pub const fn offset(&self) -> usize {
86        self.offset
87    }
88
89    /// Returns the number of bytes in the remaining buffer.
90    #[inline]
91    pub const fn remaining(&self) -> Option<usize> {
92        self.buf.len().checked_sub(self.offset)
93    }
94
95    /// Returns the number of words in the remaining buffer.
96    #[inline]
97    pub const fn remaining_words(&self) -> usize {
98        if let Some(remaining) = self.remaining() {
99            remaining / Word::len_bytes()
100        } else {
101            0
102        }
103    }
104
105    /// Returns a reference to the remaining bytes in the buffer.
106    #[inline]
107    pub fn remaining_buf(&self) -> Option<&'de [u8]> {
108        self.buf.get(self.offset..)
109    }
110
111    /// Returns whether the remaining buffer is empty.
112    #[inline]
113    pub const fn is_empty(&self) -> bool {
114        match self.remaining() {
115            Some(0) | None => true,
116            Some(_) => false,
117        }
118    }
119
120    /// Returns `true` if this decoder is validating type correctness.
121    #[inline]
122    pub const fn validate(&self) -> bool {
123        self.validate
124    }
125
126    /// Set whether to validate type correctness.
127    #[inline]
128    pub fn set_validate(&mut self, validate: bool) {
129        self.validate = validate;
130    }
131
132    /// Create a child decoder, starting at `offset` bytes from the current
133    /// decoder's offset.
134    ///
135    /// See [`child`](Self::child).
136    #[inline]
137    pub fn raw_child(&self) -> Result<Self> {
138        self.child(self.offset)
139    }
140
141    /// Create a child decoder, starting at `offset` bytes from the current
142    /// decoder's offset.
143    /// The child decoder shares the buffer and validation flag.
144    #[inline]
145    pub fn child(&self, offset: usize) -> Result<Self, Error> {
146        if self.depth >= RECURSION_LIMIT {
147            return Err(Error::RecursionLimitExceeded(RECURSION_LIMIT));
148        }
149        match self.buf.get(offset..) {
150            Some(buf) => {
151                Ok(Decoder { buf, offset: 0, validate: self.validate, depth: self.depth + 1 })
152            }
153            None => Err(Error::Overrun),
154        }
155    }
156
157    /// Advance the offset by `len` bytes.
158    #[inline]
159    fn increase_offset(&mut self, len: usize) {
160        self.offset += len;
161    }
162
163    /// Peek into the buffer.
164    #[inline]
165    pub fn peek<I: SliceIndex<[u8]>>(&self, index: I) -> Result<&'de I::Output, Error> {
166        self.buf.get(index).ok_or(Error::Overrun)
167    }
168
169    /// Peek a slice of size `len` from the buffer at a specific offset, without
170    /// advancing the offset.
171    #[inline]
172    pub fn peek_len_at(&self, offset: usize, len: usize) -> Result<&'de [u8], Error> {
173        self.peek(offset..offset + len)
174    }
175
176    /// Peek a slice of size `len` from the buffer without advancing the offset.
177    #[inline]
178    pub fn peek_len(&self, len: usize) -> Result<&'de [u8], Error> {
179        self.peek_len_at(self.offset, len)
180    }
181
182    /// Peek a word from the buffer at a specific offset, without advancing the
183    /// offset.
184    #[inline]
185    pub fn peek_word_at(&self, offset: usize) -> Result<&'de Word, Error> {
186        self.peek_len_at(offset, Word::len_bytes()).map(|w| <&Word>::try_from(w).unwrap())
187    }
188
189    /// Peek the next word from the buffer without advancing the offset.
190    #[inline]
191    pub fn peek_word(&self) -> Result<&'de Word, Error> {
192        self.peek_word_at(self.offset)
193    }
194
195    /// Peek a `usize` from the buffer at a specific offset, without advancing
196    /// the offset.
197    #[inline]
198    pub fn peek_offset_at(&self, offset: usize) -> Result<usize> {
199        self.peek_word_at(offset).and_then(|word| utils::as_offset(word, self.validate))
200    }
201
202    /// Peek a `usize` from the buffer, without advancing the offset.
203    #[inline]
204    pub fn peek_offset(&self) -> Result<usize> {
205        self.peek_word().and_then(|word| utils::as_offset(word, self.validate))
206    }
207
208    /// Take a word from the buffer, advancing the offset.
209    #[inline]
210    pub fn take_word(&mut self) -> Result<&'de Word, Error> {
211        let contents = self.peek_word()?;
212        self.increase_offset(Word::len_bytes());
213        Ok(contents)
214    }
215
216    /// Return a child decoder by consuming a word, interpreting it as a
217    /// pointer, and following it.
218    #[inline]
219    pub fn take_indirection(&mut self) -> Result<Self, Error> {
220        self.take_offset().and_then(|offset| self.child(offset))
221    }
222
223    /// Takes a `usize` offset from the buffer by consuming a word.
224    #[inline]
225    pub fn take_offset(&mut self) -> Result<usize> {
226        self.take_word().and_then(|word| utils::as_offset(word, self.validate))
227    }
228
229    /// Takes a slice of bytes of the given length by consuming up to the next
230    /// word boundary.
231    pub fn take_slice(&mut self, len: usize) -> Result<&'de [u8]> {
232        if self.validate {
233            let padded_len = utils::next_multiple_of_32(len);
234            if self.offset + padded_len > self.buf.len() {
235                return Err(Error::Overrun);
236            }
237            if !utils::check_zeroes(self.peek(self.offset + len..self.offset + padded_len)?) {
238                return Err(Error::Other(Cow::Borrowed("non-empty bytes after packed array")));
239            }
240        }
241        self.take_slice_unchecked(len)
242    }
243
244    /// Takes a slice of bytes of the given length.
245    #[inline]
246    pub fn take_slice_unchecked(&mut self, len: usize) -> Result<&'de [u8]> {
247        self.peek_len(len).inspect(|_| self.increase_offset(len))
248    }
249
250    /// Takes the offset from the child decoder and sets it as the current
251    /// offset.
252    #[inline]
253    pub fn take_offset_from(&mut self, child: &Self) {
254        self.set_offset(child.offset + (self.buf.len() - child.buf.len()));
255    }
256
257    /// Sets the current offset in the buffer.
258    #[inline]
259    pub fn set_offset(&mut self, offset: usize) {
260        self.offset = offset;
261    }
262
263    /// Decodes a single token from the underlying buffer.
264    #[inline]
265    pub fn decode<T: Token<'de>>(&mut self) -> Result<T> {
266        T::decode_from(self)
267    }
268
269    /// Decodes a sequence of tokens from the underlying buffer.
270    #[inline]
271    pub fn decode_sequence<T: Token<'de> + TokenSeq<'de>>(&mut self) -> Result<T> {
272        T::decode_sequence(self)
273    }
274}
275
276/// ABI-decodes a token by wrapping it in a single-element tuple.
277///
278/// You are probably looking for
279/// [`SolValue::abi_decode`](crate::SolValue::abi_decode) if you are not
280/// intending to use raw tokens.
281///
282/// See the [`abi`](super) module for more information.
283#[inline(always)]
284pub fn decode<'de, T: Token<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
285    decode_sequence::<(T,)>(data, validate).map(|(t,)| t)
286}
287
288/// ABI-decodes top-level function args.
289///
290/// Decodes as function parameters if [`T` is a tuple](TokenSeq::IS_TUPLE).
291/// Otherwise, decodes it as a single-element tuple.
292///
293/// You are probably looking for
294/// [`SolValue::abi_decode_params`](crate::SolValue::abi_decode_params) if
295/// you are not intending to use raw tokens.
296///
297/// See the [`abi`](super) module for more information.
298#[inline(always)]
299pub fn decode_params<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
300    let decode = const {
301        if T::IS_TUPLE {
302            decode_sequence
303        } else {
304            decode
305        }
306    };
307    decode(data, validate)
308}
309
310/// Decodes ABI compliant vector of bytes into vector of tokens described by
311/// types param.
312///
313/// You are probably looking for
314/// [`SolValue::abi_decode_sequence`](crate::SolValue::abi_decode_sequence) if
315/// you are not intending to use raw tokens.
316///
317/// See the [`abi`](super) module for more information.
318#[inline]
319pub fn decode_sequence<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
320    let mut decoder = Decoder::new(data, validate);
321    let result = decoder.decode_sequence::<T>()?;
322    if validate && encode_sequence(&result) != data {
323        return Err(Error::ReserMismatch);
324    }
325    Ok(result)
326}
327
328#[cfg(test)]
329mod tests {
330    use crate::{sol, sol_data, utils::pad_usize, SolType, SolValue};
331    use alloc::string::ToString;
332    use alloy_primitives::{address, bytes, hex, Address, B256, U256};
333
334    #[test]
335    fn dynamic_array_of_dynamic_arrays() {
336        type MyTy = sol_data::Array<sol_data::Array<sol_data::Address>>;
337        let encoded = hex!(
338            "
339    		0000000000000000000000000000000000000000000000000000000000000020
340    		0000000000000000000000000000000000000000000000000000000000000002
341    		0000000000000000000000000000000000000000000000000000000000000040
342    		0000000000000000000000000000000000000000000000000000000000000080
343    		0000000000000000000000000000000000000000000000000000000000000001
344    		0000000000000000000000001111111111111111111111111111111111111111
345    		0000000000000000000000000000000000000000000000000000000000000001
346    		0000000000000000000000002222222222222222222222222222222222222222
347    	"
348        );
349
350        let ty = vec![vec![Address::repeat_byte(0x11)], vec![Address::repeat_byte(0x22)]];
351        assert_eq!(MyTy::abi_encode_params(&ty), encoded);
352
353        let decoded = MyTy::abi_decode_params(&encoded, false).unwrap();
354        assert_eq!(decoded, ty);
355        assert_eq!(decoded.abi_encode_params(), encoded);
356        assert_eq!(decoded.abi_encoded_size(), encoded.len());
357    }
358
359    #[test]
360    fn decode_static_tuple_of_addresses_and_uints() {
361        type MyTy = (sol_data::Address, sol_data::Address, sol_data::Uint<256>);
362
363        let encoded = hex!(
364            "
365    		0000000000000000000000001111111111111111111111111111111111111111
366    		0000000000000000000000002222222222222222222222222222222222222222
367    		1111111111111111111111111111111111111111111111111111111111111111
368    	"
369        );
370        let address1 = Address::from([0x11u8; 20]);
371        let address2 = Address::from([0x22u8; 20]);
372        let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
373        let expected = (address1, address2, uint);
374        let decoded = MyTy::abi_decode_sequence(&encoded, true).unwrap();
375        assert_eq!(decoded, expected);
376        assert_eq!(decoded.abi_encode_params(), encoded);
377        assert_eq!(decoded.abi_encoded_size(), encoded.len());
378    }
379
380    #[test]
381    fn decode_dynamic_tuple() {
382        type MyTy = (sol_data::String, sol_data::String);
383        let encoded = hex!(
384            "
385    		0000000000000000000000000000000000000000000000000000000000000020
386    		0000000000000000000000000000000000000000000000000000000000000040
387    		0000000000000000000000000000000000000000000000000000000000000080
388    		0000000000000000000000000000000000000000000000000000000000000009
389    		6761766f66796f726b0000000000000000000000000000000000000000000000
390    		0000000000000000000000000000000000000000000000000000000000000009
391    		6761766f66796f726b0000000000000000000000000000000000000000000000
392    	"
393        );
394        let string1 = "gavofyork".to_string();
395        let string2 = "gavofyork".to_string();
396        let expected = (string1, string2);
397
398        // this test vector contains a top-level indirect
399        let decoded = MyTy::abi_decode(&encoded, true).unwrap();
400        assert_eq!(decoded, expected);
401        assert_eq!(decoded.abi_encode(), encoded);
402        assert_eq!(decoded.abi_encoded_size(), encoded.len());
403    }
404
405    #[test]
406    fn decode_nested_tuple() {
407        type MyTy = (
408            sol_data::String,
409            sol_data::Bool,
410            sol_data::String,
411            (sol_data::String, sol_data::String, (sol_data::String, sol_data::String)),
412        );
413
414        let encoded = hex!(
415            "
416    		0000000000000000000000000000000000000000000000000000000000000020
417    		0000000000000000000000000000000000000000000000000000000000000080
418    		0000000000000000000000000000000000000000000000000000000000000001
419    		00000000000000000000000000000000000000000000000000000000000000c0
420    		0000000000000000000000000000000000000000000000000000000000000100
421    		0000000000000000000000000000000000000000000000000000000000000004
422    		7465737400000000000000000000000000000000000000000000000000000000
423    		0000000000000000000000000000000000000000000000000000000000000006
424    		6379626f72670000000000000000000000000000000000000000000000000000
425    		0000000000000000000000000000000000000000000000000000000000000060
426    		00000000000000000000000000000000000000000000000000000000000000a0
427    		00000000000000000000000000000000000000000000000000000000000000e0
428    		0000000000000000000000000000000000000000000000000000000000000005
429    		6e69676874000000000000000000000000000000000000000000000000000000
430    		0000000000000000000000000000000000000000000000000000000000000003
431    		6461790000000000000000000000000000000000000000000000000000000000
432    		0000000000000000000000000000000000000000000000000000000000000040
433    		0000000000000000000000000000000000000000000000000000000000000080
434    		0000000000000000000000000000000000000000000000000000000000000004
435    		7765656500000000000000000000000000000000000000000000000000000000
436    		0000000000000000000000000000000000000000000000000000000000000008
437    		66756e7465737473000000000000000000000000000000000000000000000000
438    	"
439        );
440        let string1 = "test".into();
441        let string2 = "cyborg".into();
442        let string3 = "night".into();
443        let string4 = "day".into();
444        let string5 = "weee".into();
445        let string6 = "funtests".into();
446        let bool = true;
447        let deep_tuple = (string5, string6);
448        let inner_tuple = (string3, string4, deep_tuple);
449        let expected = (string1, bool, string2, inner_tuple);
450
451        let decoded = MyTy::abi_decode(&encoded, true).unwrap();
452        assert_eq!(decoded, expected);
453        assert_eq!(decoded.abi_encode(), encoded);
454        assert_eq!(decoded.abi_encoded_size(), encoded.len());
455    }
456
457    #[test]
458    fn decode_complex_tuple_of_dynamic_and_static_types() {
459        type MyTy = (sol_data::Uint<256>, sol_data::String, sol_data::Address, sol_data::Address);
460
461        let encoded = hex!(
462            "
463    		0000000000000000000000000000000000000000000000000000000000000020
464    		1111111111111111111111111111111111111111111111111111111111111111
465    		0000000000000000000000000000000000000000000000000000000000000080
466    		0000000000000000000000001111111111111111111111111111111111111111
467    		0000000000000000000000002222222222222222222222222222222222222222
468    		0000000000000000000000000000000000000000000000000000000000000009
469    		6761766f66796f726b0000000000000000000000000000000000000000000000
470    	"
471        );
472        let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
473        let string = "gavofyork".to_string();
474        let address1 = Address::from([0x11u8; 20]);
475        let address2 = Address::from([0x22u8; 20]);
476        let expected = (uint, string, address1, address2);
477
478        let decoded = MyTy::abi_decode(&encoded, true).unwrap();
479        assert_eq!(decoded, expected);
480        assert_eq!(decoded.abi_encode(), encoded);
481        assert_eq!(decoded.abi_encoded_size(), encoded.len());
482    }
483
484    #[test]
485    fn decode_params_containing_dynamic_tuple() {
486        type MyTy = (
487            sol_data::Address,
488            (sol_data::Bool, sol_data::String, sol_data::String),
489            sol_data::Address,
490            sol_data::Address,
491            sol_data::Bool,
492        );
493
494        let encoded = hex!(
495            "
496    		0000000000000000000000002222222222222222222222222222222222222222
497    		00000000000000000000000000000000000000000000000000000000000000a0
498    		0000000000000000000000003333333333333333333333333333333333333333
499    		0000000000000000000000004444444444444444444444444444444444444444
500    		0000000000000000000000000000000000000000000000000000000000000000
501    		0000000000000000000000000000000000000000000000000000000000000001
502    		0000000000000000000000000000000000000000000000000000000000000060
503    		00000000000000000000000000000000000000000000000000000000000000a0
504    		0000000000000000000000000000000000000000000000000000000000000009
505    		7370616365736869700000000000000000000000000000000000000000000000
506    		0000000000000000000000000000000000000000000000000000000000000006
507    		6379626f72670000000000000000000000000000000000000000000000000000
508    	"
509        );
510        let address1 = Address::from([0x22u8; 20]);
511        let bool1 = true;
512        let string1 = "spaceship".to_string();
513        let string2 = "cyborg".to_string();
514        let tuple = (bool1, string1, string2);
515        let address2 = Address::from([0x33u8; 20]);
516        let address3 = Address::from([0x44u8; 20]);
517        let bool2 = false;
518        let expected = (address1, tuple, address2, address3, bool2);
519
520        let decoded = MyTy::abi_decode_params(&encoded, true).unwrap();
521        assert_eq!(decoded, expected);
522        assert_eq!(decoded.abi_encode_params(), encoded);
523        assert_eq!(decoded.abi_encoded_size(), encoded.len() + 32);
524    }
525
526    #[test]
527    fn decode_params_containing_static_tuple() {
528        type MyTy = (
529            sol_data::Address,
530            (sol_data::Address, sol_data::Bool, sol_data::Bool),
531            sol_data::Address,
532            sol_data::Address,
533        );
534
535        let encoded = hex!(
536            "
537    		0000000000000000000000001111111111111111111111111111111111111111
538    		0000000000000000000000002222222222222222222222222222222222222222
539    		0000000000000000000000000000000000000000000000000000000000000001
540    		0000000000000000000000000000000000000000000000000000000000000000
541    		0000000000000000000000003333333333333333333333333333333333333333
542    		0000000000000000000000004444444444444444444444444444444444444444
543    	"
544        );
545        let address1 = Address::from([0x11u8; 20]);
546        let address2 = Address::from([0x22u8; 20]);
547        let bool1 = true;
548        let bool2 = false;
549        let tuple = (address2, bool1, bool2);
550        let address3 = Address::from([0x33u8; 20]);
551        let address4 = Address::from([0x44u8; 20]);
552
553        let expected = (address1, tuple, address3, address4);
554
555        let decoded = MyTy::abi_decode_params(&encoded, false).unwrap();
556        assert_eq!(decoded, expected);
557    }
558
559    #[test]
560    fn decode_data_with_size_that_is_not_a_multiple_of_32() {
561        type MyTy = (
562            sol_data::Uint<256>,
563            sol_data::String,
564            sol_data::String,
565            sol_data::Uint<256>,
566            sol_data::Uint<256>,
567        );
568
569        let data = (
570            pad_usize(0).into(),
571            "12203967b532a0c14c980b5aeffb17048bdfaef2c293a9509f08eb3c6b0f5f8f0942e7b9cc76ca51cca26ce546920448e308fda6870b5e2ae12a2409d942de428113P720p30fps16x9".to_string(),
572            "93c717e7c0a6517a".to_string(),
573            pad_usize(1).into(),
574            pad_usize(5538829).into()
575        );
576
577        let encoded = hex!(
578            "
579            0000000000000000000000000000000000000000000000000000000000000000
580            00000000000000000000000000000000000000000000000000000000000000a0
581            0000000000000000000000000000000000000000000000000000000000000152
582            0000000000000000000000000000000000000000000000000000000000000001
583            000000000000000000000000000000000000000000000000000000000054840d
584            0000000000000000000000000000000000000000000000000000000000000092
585            3132323033393637623533326130633134633938306235616566666231373034
586            3862646661656632633239336139353039663038656233633662306635663866
587            3039343265376239636337366361353163636132366365353436393230343438
588            6533303866646136383730623565326165313261323430396439343264653432
589            3831313350373230703330667073313678390000000000000000000000000000
590            0000000000000000000000000000000000103933633731376537633061363531
591            3761
592        "
593        );
594
595        assert_eq!(MyTy::abi_decode_sequence(&encoded, false).unwrap(), data);
596    }
597
598    #[test]
599    fn decode_after_fixed_bytes_with_less_than_32_bytes() {
600        type MyTy = (
601            sol_data::Address,
602            sol_data::FixedBytes<32>,
603            sol_data::FixedBytes<4>,
604            sol_data::String,
605        );
606
607        let encoded = hex!(
608            "
609    		0000000000000000000000008497afefdc5ac170a664a231f6efb25526ef813f
610    		0101010101010101010101010101010101010101010101010101010101010101
611    		0202020202020202020202020202020202020202020202020202020202020202
612    		0000000000000000000000000000000000000000000000000000000000000080
613    		000000000000000000000000000000000000000000000000000000000000000a
614    		3078303030303030314600000000000000000000000000000000000000000000
615    	    "
616        );
617
618        assert_eq!(
619            MyTy::abi_decode_params(&encoded, false).unwrap(),
620            (
621                address!("0x8497afefdc5ac170a664a231f6efb25526ef813f"),
622                B256::repeat_byte(0x01),
623                [0x02; 4].into(),
624                "0x0000001F".into(),
625            )
626        );
627    }
628
629    #[test]
630    fn decode_broken_utf8() {
631        let encoded = hex!(
632            "
633    		0000000000000000000000000000000000000000000000000000000000000020
634    		0000000000000000000000000000000000000000000000000000000000000004
635    		e4b88de500000000000000000000000000000000000000000000000000000000
636            "
637        );
638
639        assert_eq!(sol_data::String::abi_decode(&encoded, false).unwrap(), "不�".to_string());
640    }
641
642    #[test]
643    #[cfg_attr(miri, ignore = "OOM https://github.com/rust-lang/miri/issues/3637")]
644    fn decode_corrupted_dynamic_array() {
645        type MyTy = sol_data::Array<sol_data::Uint<32>>;
646        // line 1 at 0x00 =   0: tail offset of array
647        // line 2 at 0x20 =  32: length of array
648        // line 3 at 0x40 =  64: first word
649        // line 4 at 0x60 =  96: second word
650        let encoded = hex!(
651            "
652    	0000000000000000000000000000000000000000000000000000000000000020
653    	00000000000000000000000000000000000000000000000000000000ffffffff
654    	0000000000000000000000000000000000000000000000000000000000000001
655    	0000000000000000000000000000000000000000000000000000000000000002
656        "
657        );
658        assert!(MyTy::abi_decode_sequence(&encoded, true).is_err());
659    }
660
661    #[test]
662    fn decode_verify_addresses() {
663        let input = hex!(
664            "
665    	0000000000000000000000000000000000000000000000000000000000012345
666    	0000000000000000000000000000000000000000000000000000000000054321
667    	"
668        );
669        assert!(sol_data::Address::abi_decode(&input, false).is_ok());
670        assert!(sol_data::Address::abi_decode(&input, true).is_err());
671        assert!(<(sol_data::Address, sol_data::Address)>::abi_decode(&input, true).is_ok());
672    }
673
674    #[test]
675    fn decode_verify_bytes() {
676        type MyTy = (sol_data::Address, sol_data::FixedBytes<20>);
677        type MyTy2 = (sol_data::Address, sol_data::Address);
678
679        let input = hex!(
680            "
681    	0000000000000000000000001234500000000000000000000000000000012345
682    	0000000000000000000000005432100000000000000000000000000000054321
683    	"
684        );
685        MyTy::abi_decode_params(&input, true).unwrap_err();
686        assert!(MyTy2::abi_decode_params(&input, true).is_ok());
687    }
688
689    #[test]
690    fn signed_int_dirty_high_bytes() {
691        type MyTy = sol_data::Int<8>;
692
693        let dirty_negative =
694            hex!("f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
695
696        assert_eq!(MyTy::abi_decode(&dirty_negative, false).unwrap(), -1);
697
698        assert!(
699            matches!(
700                MyTy::abi_decode(&dirty_negative, true),
701                Err(crate::Error::TypeCheckFail { .. }),
702            ),
703            "did not match error"
704        );
705
706        let dirty_positive =
707            hex!("700000000000000000000000000000000000000000000000000000000000007f");
708
709        assert_eq!(MyTy::abi_decode(&dirty_positive, false).unwrap(), 127);
710
711        assert!(
712            matches!(
713                MyTy::abi_decode(&dirty_positive, true),
714                Err(crate::Error::TypeCheckFail { .. }),
715            ),
716            "did not match error"
717        );
718    }
719
720    // https://github.com/alloy-rs/core/issues/433
721    #[test]
722    fn fixed_before_dynamic() {
723        sol! {
724            #[derive(Debug, PartialEq, Eq)]
725            struct Ty {
726                bytes32[3] arr;
727                bytes dyn;
728            }
729        }
730
731        let ty = Ty {
732            arr: [[0x11u8; 32].into(), [0x22u8; 32].into(), [0x33u8; 32].into()],
733            r#dyn: bytes![0x44u8; 4],
734        };
735        let encoded = hex!(
736            "0000000000000000000000000000000000000000000000000000000000000020"
737            "1111111111111111111111111111111111111111111111111111111111111111"
738            "2222222222222222222222222222222222222222222222222222222222222222"
739            "3333333333333333333333333333333333333333333333333333333333333333"
740            "0000000000000000000000000000000000000000000000000000000000000080"
741            "0000000000000000000000000000000000000000000000000000000000000004"
742            "4444444400000000000000000000000000000000000000000000000000000000"
743        );
744        assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
745        assert_eq!(ty.abi_encoded_size(), encoded.len());
746
747        assert_eq!(<Ty as SolType>::abi_decode(&encoded, true).unwrap(), ty);
748    }
749
750    #[test]
751    fn dynarray_before_dynamic() {
752        sol! {
753            #[derive(Debug, PartialEq, Eq)]
754            struct Ty {
755                bytes[3] arr;
756                bytes dyn;
757            }
758        }
759
760        let ty = Ty {
761            arr: [bytes![0x11u8; 32], bytes![0x22u8; 32], bytes![0x33u8; 32]],
762            r#dyn: bytes![0x44u8; 4],
763        };
764        let encoded = hex!(
765            "0000000000000000000000000000000000000000000000000000000000000020" // struct offset
766            "0000000000000000000000000000000000000000000000000000000000000040" // arr offset
767            "0000000000000000000000000000000000000000000000000000000000000160" // dyn offset
768            "0000000000000000000000000000000000000000000000000000000000000060" // arr[0] offset
769            "00000000000000000000000000000000000000000000000000000000000000a0" // arr[1] offset
770            "00000000000000000000000000000000000000000000000000000000000000e0" // arr[2] offset
771            "0000000000000000000000000000000000000000000000000000000000000020" // arr[0]
772            "1111111111111111111111111111111111111111111111111111111111111111"
773            "0000000000000000000000000000000000000000000000000000000000000020" // arr[1]
774            "2222222222222222222222222222222222222222222222222222222222222222"
775            "0000000000000000000000000000000000000000000000000000000000000020" // arr[2]
776            "3333333333333333333333333333333333333333333333333333333333333333"
777            "0000000000000000000000000000000000000000000000000000000000000004" // dyn
778            "4444444400000000000000000000000000000000000000000000000000000000"
779        );
780        assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
781        assert_eq!(ty.abi_encoded_size(), encoded.len());
782
783        assert_eq!(<Ty as SolType>::abi_decode(&encoded, false).unwrap(), ty);
784    }
785}