1use crate::{
12 Error, Result, Word,
13 abi::{Token, token::TokenSeq},
14 utils,
15};
16use alloc::vec::Vec;
17use alloy_primitives::hex;
18use core::{cell::Cell, fmt, mem, slice::SliceIndex};
19
20#[deprecated(note = "use `AbiDecoderConfig` to configure the recursion limit")]
24pub const RECURSION_LIMIT: usize = 16;
25
26const DEFAULT_MEMORY_LIMIT: usize = 1 << 30;
27
28#[allow(missing_copy_implementations, missing_debug_implementations)]
30pub struct AbiDecoderConfig {
31 recursion_limit: usize,
32 memory_limit: usize,
33 validate: bool,
34 strict: bool,
35 validate_allow_trailing_bytes: bool,
36}
37
38impl Default for AbiDecoderConfig {
39 #[inline]
40 fn default() -> Self {
41 Self::new()
42 }
43}
44
45impl Clone for AbiDecoderConfig {
46 #[inline]
47 fn clone(&self) -> Self {
48 *self
49 }
50}
51
52impl Copy for AbiDecoderConfig {}
53
54impl fmt::Debug for AbiDecoderConfig {
55 #[inline]
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 f.debug_struct("AbiDecoderConfig")
58 .field("recursion_limit", &self.recursion_limit)
59 .field("memory_limit", &self.memory_limit)
60 .field("validate", &self.validate)
61 .field("strict", &self.strict)
62 .field("validate_allow_trailing_bytes", &self.validate_allow_trailing_bytes)
63 .finish()
64 }
65}
66
67impl AbiDecoderConfig {
68 #[inline]
70 pub const fn new() -> Self {
71 Self {
72 recursion_limit: 16,
73 memory_limit: DEFAULT_MEMORY_LIMIT,
74 validate: false,
75 strict: false,
76 validate_allow_trailing_bytes: false,
77 }
78 }
79
80 #[inline]
82 pub const fn get_recursion_limit(&self) -> usize {
83 self.recursion_limit
84 }
85
86 #[inline]
88 pub const fn get_memory_limit(&self) -> usize {
89 self.memory_limit
90 }
91
92 #[inline]
94 pub const fn get_validate(&self) -> bool {
95 self.validate || self.get_strict()
96 }
97
98 #[inline]
104 pub const fn get_strict(&self) -> bool {
105 self.strict
106 }
107
108 #[inline]
110 pub const fn get_validate_allow_trailing_bytes(&self) -> bool {
111 self.validate_allow_trailing_bytes
112 }
113
114 #[inline]
116 pub const fn recursion_limit(mut self, limit: usize) -> Self {
117 self.recursion_limit = limit;
118 self
119 }
120
121 #[inline]
123 pub const fn memory_limit(mut self, limit: usize) -> Self {
124 self.memory_limit = limit;
125 self
126 }
127
128 #[inline]
136 pub const fn validate(mut self, validate: bool) -> Self {
137 self.validate = validate;
138 self
139 }
140
141 #[inline]
148 pub const fn strict(mut self, strict: bool) -> Self {
149 self.strict = strict;
150 self
151 }
152
153 #[inline]
176 pub const fn validate_allow_trailing_bytes(mut self, allow: bool) -> Self {
177 self.validate_allow_trailing_bytes = allow;
178 self
179 }
180
181 #[inline]
183 pub const fn set_recursion_limit(&mut self, limit: usize) {
184 self.recursion_limit = limit;
185 }
186
187 #[inline]
189 pub const fn set_memory_limit(&mut self, limit: usize) {
190 self.memory_limit = limit;
191 }
192
193 #[inline]
195 pub const fn set_validate(&mut self, validate: bool) {
196 self.validate = validate;
197 }
198
199 #[inline]
201 pub const fn set_strict(&mut self, strict: bool) {
202 self.strict = strict;
203 }
204
205 #[inline]
207 pub const fn set_validate_allow_trailing_bytes(&mut self, allow: bool) {
208 self.validate_allow_trailing_bytes = allow;
209 }
210}
211
212enum DecoderState<'state> {
213 Root {
214 memory_used: Cell<usize>,
215 strict_next_offset: Cell<usize>,
216 },
217 Child {
218 memory_used: &'state Cell<usize>,
219 strict_next_offset: Cell<usize>,
220 strict_parent: Option<StrictParent<'state>>,
221 },
222}
223
224impl<'state> DecoderState<'state> {
225 #[inline]
226 const fn memory_used(&self) -> &Cell<usize> {
227 match self {
228 Self::Root { memory_used, .. } => memory_used,
229 Self::Child { memory_used, .. } => memory_used,
230 }
231 }
232
233 #[inline]
234 const fn strict_next_offset(&self) -> &Cell<usize> {
235 match self {
236 Self::Root { strict_next_offset, .. } | Self::Child { strict_next_offset, .. } => {
237 strict_next_offset
238 }
239 }
240 }
241
242 #[inline]
243 const fn strict_parent(&self) -> Option<&StrictParent<'state>> {
244 match self {
245 Self::Root { .. } => None,
246 Self::Child { strict_parent, .. } => strict_parent.as_ref(),
247 }
248 }
249}
250
251struct StrictParent<'state> {
252 next_offset: &'state Cell<usize>,
253 start: usize,
254}
255
256pub struct Decoder<'de, 'state> {
264 buf: &'de [u8],
266 offset: usize,
268 depth: usize,
270 config: AbiDecoderConfig,
272 state: DecoderState<'state>,
274}
275
276impl fmt::Debug for Decoder<'_, '_> {
277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
278 let mut body = self.buf.chunks(32).map(hex::encode_prefixed).collect::<Vec<_>>();
279 if let Some(word) = body.get_mut(self.offset / 32) {
280 word.push_str(" <-- Next Word");
281 }
282
283 f.debug_struct("Decoder")
284 .field("buf", &body)
285 .field("offset", &self.offset)
286 .field("depth", &self.depth)
287 .field("config", &self.config)
288 .finish()
289 }
290}
291
292impl fmt::Display for Decoder<'_, '_> {
293 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
294 writeln!(f, "Abi Decode Buffer")?;
295
296 for (i, chunk) in self.buf.chunks(32).enumerate() {
297 let idx = i * 32;
298 writeln!(
299 f,
300 "0x{idx:04x}: {}{}",
301 hex::encode_prefixed(chunk),
302 if idx == self.offset { " <-- Next Word" } else { "" }
303 )?;
304 }
305 Ok(())
306 }
307}
308
309impl<'de> Decoder<'de, 'static> {
310 #[inline]
312 pub const fn new(buf: &'de [u8]) -> Self {
313 Self::with_config(buf, AbiDecoderConfig::new())
314 }
315
316 #[inline]
317 const fn with_config(buf: &'de [u8], config: AbiDecoderConfig) -> Self {
318 Self {
319 buf,
320 offset: 0,
321 depth: 0,
322 config,
323 state: DecoderState::Root {
324 memory_used: Cell::new(0),
325 strict_next_offset: Cell::new(0),
326 },
327 }
328 }
329}
330
331impl<'de, 'state> Decoder<'de, 'state> {
332 #[inline]
333 const fn new_child<'child>(parent: &'child Self, buf: &'de [u8]) -> Decoder<'de, 'child> {
334 Decoder {
335 buf,
336 offset: 0,
337 depth: parent.depth + 1,
338 config: parent.config,
339 state: DecoderState::Child {
340 memory_used: parent.memory_used(),
341 strict_next_offset: Cell::new(0),
342 strict_parent: if parent.config.get_strict() {
343 Some(StrictParent {
344 next_offset: parent.state.strict_next_offset(),
345 start: parent.buf.len() - buf.len(),
346 })
347 } else {
348 None
349 },
350 },
351 }
352 }
353
354 #[inline]
355 const fn memory_used(&self) -> &Cell<usize> {
356 self.state.memory_used()
357 }
358
359 #[doc(hidden)]
361 #[inline]
362 pub fn set_strict_head_words(&self, words: usize) -> Result<()> {
363 if self.config.get_strict() {
364 let bytes = words.checked_mul(Word::len_bytes()).ok_or(Error::Overrun)?;
365 let offset = self.offset.checked_add(bytes).ok_or(Error::Overrun)?;
366 let next = self.state.strict_next_offset();
367 next.set(next.get().max(offset));
368 }
369 Ok(())
370 }
371
372 #[inline]
373 pub(crate) const fn is_strict(&self) -> bool {
374 self.config.get_strict()
375 }
376
377 #[inline]
379 pub const fn offset(&self) -> usize {
380 self.offset
381 }
382
383 #[inline]
385 pub const fn remaining(&self) -> Option<usize> {
386 self.buf.len().checked_sub(self.offset)
387 }
388
389 #[inline]
391 pub const fn remaining_words(&self) -> usize {
392 if let Some(remaining) = self.remaining() { remaining / Word::len_bytes() } else { 0 }
393 }
394
395 #[inline]
397 pub fn remaining_buf(&self) -> Option<&'de [u8]> {
398 self.buf.get(self.offset..)
399 }
400
401 #[inline]
403 pub const fn is_empty(&self) -> bool {
404 match self.remaining() {
405 Some(0) | None => true,
406 Some(_) => false,
407 }
408 }
409
410 #[inline]
415 pub fn raw_child<'child>(&'child self) -> Result<Decoder<'de, 'child>> {
416 self.child(self.offset)
417 }
418
419 #[inline]
423 pub fn child<'child>(&'child self, offset: usize) -> Result<Decoder<'de, 'child>, Error> {
424 let recursion_limit = self.config.get_recursion_limit();
425 if self.depth >= recursion_limit {
426 return Err(Error::RecursionLimitExceeded(recursion_limit));
427 }
428 match self.buf.get(offset..) {
429 Some(buf) => Ok(Self::new_child(self, buf)),
430 None => Err(Error::Overrun),
431 }
432 }
433
434 #[doc(hidden)]
436 #[inline]
437 pub fn reserve(&mut self, bytes: usize) -> Result<()> {
438 let memory_limit = self.config.get_memory_limit();
439 let used = self
440 .memory_used()
441 .get()
442 .checked_add(bytes)
443 .ok_or(Error::MemoryLimitExceeded(memory_limit))?;
444 if used > memory_limit {
445 return Err(Error::MemoryLimitExceeded(memory_limit));
446 }
447 self.memory_used().set(used);
448 Ok(())
449 }
450
451 #[doc(hidden)]
452 #[inline]
453 pub fn reserve_elements<T>(&mut self, len: usize) -> Result<()> {
454 let bytes = len
455 .checked_mul(mem::size_of::<T>())
456 .ok_or(Error::MemoryLimitExceeded(self.config.get_memory_limit()))?;
457 self.reserve(bytes)
458 }
459
460 #[inline]
462 const fn increase_offset(&mut self, len: usize) {
463 self.offset += len;
464 }
465
466 #[inline]
468 pub fn peek<I: SliceIndex<[u8]>>(&self, index: I) -> Result<&'de I::Output, Error> {
469 self.buf.get(index).ok_or(Error::Overrun)
470 }
471
472 #[inline]
475 pub fn peek_len_at(&self, offset: usize, len: usize) -> Result<&'de [u8], Error> {
476 let end = offset.checked_add(len).ok_or(Error::Overrun)?;
477 self.peek(offset..end)
478 }
479
480 #[inline]
482 pub fn peek_len(&self, len: usize) -> Result<&'de [u8], Error> {
483 self.peek_len_at(self.offset, len)
484 }
485
486 #[inline]
489 pub fn peek_word_at(&self, offset: usize) -> Result<&'de Word, Error> {
490 self.peek_len_at(offset, Word::len_bytes()).map(|w| <&Word>::try_from(w).unwrap())
491 }
492
493 #[inline]
495 pub fn peek_word(&self) -> Result<&'de Word, Error> {
496 self.peek_word_at(self.offset)
497 }
498
499 #[inline]
502 pub fn peek_offset_at(&self, offset: usize) -> Result<usize> {
503 self.peek_word_at(offset).and_then(utils::as_offset)
504 }
505
506 #[inline]
508 pub fn peek_offset(&self) -> Result<usize> {
509 self.peek_word().and_then(utils::as_offset)
510 }
511
512 #[inline]
514 pub fn take_word(&mut self) -> Result<&'de Word, Error> {
515 let contents = self.peek_word()?;
516 self.increase_offset(Word::len_bytes());
517 Ok(contents)
518 }
519
520 #[inline]
523 pub fn take_indirection<'child>(&'child mut self) -> Result<Decoder<'de, 'child>, Error> {
524 let offset = self.take_offset()?;
525 if self.is_strict() && offset != self.state.strict_next_offset().get() {
526 return Err(Error::ReserMismatch);
527 }
528 self.child(offset)
529 }
530
531 #[inline]
533 pub fn take_offset(&mut self) -> Result<usize> {
534 self.take_word().and_then(utils::as_offset)
535 }
536
537 #[inline]
539 pub fn take_slice(&mut self, len: usize) -> Result<&'de [u8]> {
540 self.peek_len(len).inspect(|_| self.increase_offset(len))
541 }
542
543 #[doc(hidden)]
545 #[inline]
546 pub fn take_padded_slice(&mut self, len: usize) -> Result<&'de [u8]> {
547 let bytes = self.take_slice(len)?;
548 if self.is_strict() {
549 let padding = (Word::len_bytes() - len % Word::len_bytes()) % Word::len_bytes();
550 if self.take_slice(padding)?.iter().any(|&byte| byte != 0) {
551 return Err(Error::ReserMismatch);
552 }
553 }
554 Ok(bytes)
555 }
556
557 #[inline]
560 pub const fn take_offset_from(&mut self, child: &Decoder<'de, '_>) {
561 self.set_offset(self.offset_from_child(child));
562 }
563
564 #[inline]
566 pub const fn offset_from_child(&self, child: &Decoder<'de, '_>) -> usize {
567 child.offset + (self.buf.len() - child.buf.len())
568 }
569
570 #[inline]
572 pub const fn set_offset(&mut self, offset: usize) {
573 self.offset = offset;
574 }
575
576 #[inline]
578 pub fn decode<T: Token<'de>>(&mut self) -> Result<T> {
579 T::decode_from(self)
580 }
581
582 #[inline]
584 pub fn decode_sequence<T: Token<'de> + TokenSeq<'de>>(&mut self) -> Result<T> {
585 T::decode_sequence(self)
586 }
587}
588
589impl Drop for Decoder<'_, '_> {
590 fn drop(&mut self) {
591 if let Some(parent) = self.state.strict_parent() {
592 let offset =
593 parent.start.saturating_add(self.offset.max(self.state.strict_next_offset().get()));
594 parent.next_offset.set(parent.next_offset.get().max(offset));
595 }
596 }
597}
598
599#[inline(always)]
607pub fn decode<'de, T: Token<'de>>(data: &'de [u8]) -> Result<T> {
608 decode_with_config(data, AbiDecoderConfig::default())
609}
610
611#[inline(always)]
613pub fn decode_with_config<'de, T: Token<'de>>(
614 data: &'de [u8],
615 config: AbiDecoderConfig,
616) -> Result<T> {
617 decode_sequence_with_config::<(T,)>(data, config).map(|(t,)| t)
618}
619
620#[inline(always)]
631pub fn decode_params<'de, T: TokenSeq<'de>>(data: &'de [u8]) -> Result<T> {
632 decode_params_with_config(data, AbiDecoderConfig::default())
633}
634
635#[inline(always)]
637pub fn decode_params_with_config<'de, T: TokenSeq<'de>>(
638 data: &'de [u8],
639 config: AbiDecoderConfig,
640) -> Result<T> {
641 if T::IS_TUPLE {
642 decode_sequence_with_config(data, config)
643 } else {
644 decode_with_config(data, config)
645 }
646}
647
648#[inline]
657pub fn decode_sequence<'de, T: TokenSeq<'de>>(data: &'de [u8]) -> Result<T> {
658 decode_sequence_with_config(data, AbiDecoderConfig::default())
659}
660
661#[inline]
663pub fn decode_sequence_with_config<'de, T: TokenSeq<'de>>(
664 data: &'de [u8],
665 config: AbiDecoderConfig,
666) -> Result<T> {
667 let mut decoder = Decoder::with_config(data, config);
668 let result = decoder.decode_sequence::<T>()?;
669 if config.get_strict()
670 && !config.get_validate_allow_trailing_bytes()
671 && decoder.state.strict_next_offset().get() != data.len()
672 {
673 return Err(Error::ReserMismatch);
674 }
675 Ok(result)
676}
677
678#[cfg(test)]
679mod tests {
680 use super::*;
681 use crate::{SolCall, SolType, SolValue, sol, sol_data, utils::pad_usize};
682 use alloc::string::ToString;
683 use alloy_primitives::{Address, B256, U256, address, bytes, hex};
684
685 #[test]
686 fn dynamic_array_of_dynamic_arrays() {
687 type MyTy = sol_data::Array<sol_data::Array<sol_data::Address>>;
688 let encoded = hex!(
689 "
690 0000000000000000000000000000000000000000000000000000000000000020
691 0000000000000000000000000000000000000000000000000000000000000002
692 0000000000000000000000000000000000000000000000000000000000000040
693 0000000000000000000000000000000000000000000000000000000000000080
694 0000000000000000000000000000000000000000000000000000000000000001
695 0000000000000000000000001111111111111111111111111111111111111111
696 0000000000000000000000000000000000000000000000000000000000000001
697 0000000000000000000000002222222222222222222222222222222222222222
698 "
699 );
700
701 let ty = vec![vec![Address::repeat_byte(0x11)], vec![Address::repeat_byte(0x22)]];
702 assert_eq!(MyTy::abi_encode_params(&ty), encoded);
703
704 let decoded = MyTy::abi_decode_params(&encoded).unwrap();
705 assert_eq!(decoded, ty);
706 assert_eq!(decoded.abi_encode_params(), encoded);
707 assert_eq!(decoded.abi_encoded_size(), encoded.len());
708 }
709
710 #[test]
711 fn decode_static_tuple_of_addresses_and_uints() {
712 type MyTy = (sol_data::Address, sol_data::Address, sol_data::Uint<256>);
713
714 let encoded = hex!(
715 "
716 0000000000000000000000001111111111111111111111111111111111111111
717 0000000000000000000000002222222222222222222222222222222222222222
718 1111111111111111111111111111111111111111111111111111111111111111
719 "
720 );
721 let address1 = Address::from([0x11u8; 20]);
722 let address2 = Address::from([0x22u8; 20]);
723 let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
724 let expected = (address1, address2, uint);
725 let decoded = MyTy::abi_decode_sequence(&encoded).unwrap();
726 assert_eq!(decoded, expected);
727 assert_eq!(decoded.abi_encode_params(), encoded);
728 assert_eq!(decoded.abi_encoded_size(), encoded.len());
729 }
730
731 #[test]
732 fn decode_dynamic_tuple() {
733 type MyTy = (sol_data::String, sol_data::String);
734 let encoded = hex!(
735 "
736 0000000000000000000000000000000000000000000000000000000000000020
737 0000000000000000000000000000000000000000000000000000000000000040
738 0000000000000000000000000000000000000000000000000000000000000080
739 0000000000000000000000000000000000000000000000000000000000000009
740 6761766f66796f726b0000000000000000000000000000000000000000000000
741 0000000000000000000000000000000000000000000000000000000000000009
742 6761766f66796f726b0000000000000000000000000000000000000000000000
743 "
744 );
745 let string1 = "gavofyork".to_string();
746 let string2 = "gavofyork".to_string();
747 let expected = (string1, string2);
748
749 let decoded = MyTy::abi_decode(&encoded).unwrap();
751 assert_eq!(decoded, expected);
752 assert_eq!(decoded.abi_encode(), encoded);
753 assert_eq!(decoded.abi_encoded_size(), encoded.len());
754 }
755
756 #[test]
757 fn decode_nested_tuple() {
758 type MyTy = (
759 sol_data::String,
760 sol_data::Bool,
761 sol_data::String,
762 (sol_data::String, sol_data::String, (sol_data::String, sol_data::String)),
763 );
764
765 let encoded = hex!(
766 "
767 0000000000000000000000000000000000000000000000000000000000000020
768 0000000000000000000000000000000000000000000000000000000000000080
769 0000000000000000000000000000000000000000000000000000000000000001
770 00000000000000000000000000000000000000000000000000000000000000c0
771 0000000000000000000000000000000000000000000000000000000000000100
772 0000000000000000000000000000000000000000000000000000000000000004
773 7465737400000000000000000000000000000000000000000000000000000000
774 0000000000000000000000000000000000000000000000000000000000000006
775 6379626f72670000000000000000000000000000000000000000000000000000
776 0000000000000000000000000000000000000000000000000000000000000060
777 00000000000000000000000000000000000000000000000000000000000000a0
778 00000000000000000000000000000000000000000000000000000000000000e0
779 0000000000000000000000000000000000000000000000000000000000000005
780 6e69676874000000000000000000000000000000000000000000000000000000
781 0000000000000000000000000000000000000000000000000000000000000003
782 6461790000000000000000000000000000000000000000000000000000000000
783 0000000000000000000000000000000000000000000000000000000000000040
784 0000000000000000000000000000000000000000000000000000000000000080
785 0000000000000000000000000000000000000000000000000000000000000004
786 7765656500000000000000000000000000000000000000000000000000000000
787 0000000000000000000000000000000000000000000000000000000000000008
788 66756e7465737473000000000000000000000000000000000000000000000000
789 "
790 );
791 let string1 = "test".into();
792 let string2 = "cyborg".into();
793 let string3 = "night".into();
794 let string4 = "day".into();
795 let string5 = "weee".into();
796 let string6 = "funtests".into();
797 let bool = true;
798 let deep_tuple = (string5, string6);
799 let inner_tuple = (string3, string4, deep_tuple);
800 let expected = (string1, bool, string2, inner_tuple);
801
802 let decoded = MyTy::abi_decode(&encoded).unwrap();
803 assert_eq!(decoded, expected);
804 assert_eq!(decoded.abi_encode(), encoded);
805 assert_eq!(decoded.abi_encoded_size(), encoded.len());
806 }
807
808 #[test]
809 fn decode_complex_tuple_of_dynamic_and_static_types() {
810 type MyTy = (sol_data::Uint<256>, sol_data::String, sol_data::Address, sol_data::Address);
811
812 let encoded = hex!(
813 "
814 0000000000000000000000000000000000000000000000000000000000000020
815 1111111111111111111111111111111111111111111111111111111111111111
816 0000000000000000000000000000000000000000000000000000000000000080
817 0000000000000000000000001111111111111111111111111111111111111111
818 0000000000000000000000002222222222222222222222222222222222222222
819 0000000000000000000000000000000000000000000000000000000000000009
820 6761766f66796f726b0000000000000000000000000000000000000000000000
821 "
822 );
823 let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
824 let string = "gavofyork".to_string();
825 let address1 = Address::from([0x11u8; 20]);
826 let address2 = Address::from([0x22u8; 20]);
827 let expected = (uint, string, address1, address2);
828
829 let decoded = MyTy::abi_decode(&encoded).unwrap();
830 assert_eq!(decoded, expected);
831 assert_eq!(decoded.abi_encode(), encoded);
832 assert_eq!(decoded.abi_encoded_size(), encoded.len());
833 }
834
835 #[test]
836 fn decode_params_containing_dynamic_tuple() {
837 type MyTy = (
838 sol_data::Address,
839 (sol_data::Bool, sol_data::String, sol_data::String),
840 sol_data::Address,
841 sol_data::Address,
842 sol_data::Bool,
843 );
844
845 let encoded = hex!(
846 "
847 0000000000000000000000002222222222222222222222222222222222222222
848 00000000000000000000000000000000000000000000000000000000000000a0
849 0000000000000000000000003333333333333333333333333333333333333333
850 0000000000000000000000004444444444444444444444444444444444444444
851 0000000000000000000000000000000000000000000000000000000000000000
852 0000000000000000000000000000000000000000000000000000000000000001
853 0000000000000000000000000000000000000000000000000000000000000060
854 00000000000000000000000000000000000000000000000000000000000000a0
855 0000000000000000000000000000000000000000000000000000000000000009
856 7370616365736869700000000000000000000000000000000000000000000000
857 0000000000000000000000000000000000000000000000000000000000000006
858 6379626f72670000000000000000000000000000000000000000000000000000
859 "
860 );
861 let address1 = Address::from([0x22u8; 20]);
862 let bool1 = true;
863 let string1 = "spaceship".to_string();
864 let string2 = "cyborg".to_string();
865 let tuple = (bool1, string1, string2);
866 let address2 = Address::from([0x33u8; 20]);
867 let address3 = Address::from([0x44u8; 20]);
868 let bool2 = false;
869 let expected = (address1, tuple, address2, address3, bool2);
870
871 let decoded = MyTy::abi_decode_params(&encoded).unwrap();
872 assert_eq!(decoded, expected);
873 assert_eq!(decoded.abi_encode_params(), encoded);
874 assert_eq!(decoded.abi_encoded_size(), encoded.len() + 32);
875 }
876
877 #[test]
878 fn decode_params_containing_static_tuple() {
879 type MyTy = (
880 sol_data::Address,
881 (sol_data::Address, sol_data::Bool, sol_data::Bool),
882 sol_data::Address,
883 sol_data::Address,
884 );
885
886 let encoded = hex!(
887 "
888 0000000000000000000000001111111111111111111111111111111111111111
889 0000000000000000000000002222222222222222222222222222222222222222
890 0000000000000000000000000000000000000000000000000000000000000001
891 0000000000000000000000000000000000000000000000000000000000000000
892 0000000000000000000000003333333333333333333333333333333333333333
893 0000000000000000000000004444444444444444444444444444444444444444
894 "
895 );
896 let address1 = Address::from([0x11u8; 20]);
897 let address2 = Address::from([0x22u8; 20]);
898 let bool1 = true;
899 let bool2 = false;
900 let tuple = (address2, bool1, bool2);
901 let address3 = Address::from([0x33u8; 20]);
902 let address4 = Address::from([0x44u8; 20]);
903
904 let expected = (address1, tuple, address3, address4);
905
906 let decoded = MyTy::abi_decode_params(&encoded).unwrap();
907 assert_eq!(decoded, expected);
908 }
909
910 #[test]
911 fn decode_data_with_size_that_is_not_a_multiple_of_32() {
912 type MyTy = (
913 sol_data::Uint<256>,
914 sol_data::String,
915 sol_data::String,
916 sol_data::Uint<256>,
917 sol_data::Uint<256>,
918 );
919
920 let data = (
921 pad_usize(0).into(),
922 "12203967b532a0c14c980b5aeffb17048bdfaef2c293a9509f08eb3c6b0f5f8f0942e7b9cc76ca51cca26ce546920448e308fda6870b5e2ae12a2409d942de428113P720p30fps16x9".to_string(),
923 "93c717e7c0a6517a".to_string(),
924 pad_usize(1).into(),
925 pad_usize(5538829).into()
926 );
927
928 let encoded = hex!(
929 "
930 0000000000000000000000000000000000000000000000000000000000000000
931 00000000000000000000000000000000000000000000000000000000000000a0
932 0000000000000000000000000000000000000000000000000000000000000152
933 0000000000000000000000000000000000000000000000000000000000000001
934 000000000000000000000000000000000000000000000000000000000054840d
935 0000000000000000000000000000000000000000000000000000000000000092
936 3132323033393637623533326130633134633938306235616566666231373034
937 3862646661656632633239336139353039663038656233633662306635663866
938 3039343265376239636337366361353163636132366365353436393230343438
939 6533303866646136383730623565326165313261323430396439343264653432
940 3831313350373230703330667073313678390000000000000000000000000000
941 0000000000000000000000000000000000103933633731376537633061363531
942 3761
943 "
944 );
945
946 assert_eq!(MyTy::abi_decode_sequence(&encoded).unwrap(), data);
947 }
948
949 #[test]
950 fn decode_after_fixed_bytes_with_less_than_32_bytes() {
951 type MyTy = (
952 sol_data::Address,
953 sol_data::FixedBytes<32>,
954 sol_data::FixedBytes<4>,
955 sol_data::String,
956 );
957
958 let encoded = hex!(
959 "
960 0000000000000000000000008497afefdc5ac170a664a231f6efb25526ef813f
961 0101010101010101010101010101010101010101010101010101010101010101
962 0202020202020202020202020202020202020202020202020202020202020202
963 0000000000000000000000000000000000000000000000000000000000000080
964 000000000000000000000000000000000000000000000000000000000000000a
965 3078303030303030314600000000000000000000000000000000000000000000
966 "
967 );
968
969 assert_eq!(
970 MyTy::abi_decode_params(&encoded).unwrap(),
971 (
972 address!("0x8497afefdc5ac170a664a231f6efb25526ef813f"),
973 B256::repeat_byte(0x01),
974 [0x02; 4].into(),
975 "0x0000001F".into(),
976 )
977 );
978 }
979
980 #[test]
981 fn decode_broken_utf8() {
982 let encoded = hex!(
983 "
984 0000000000000000000000000000000000000000000000000000000000000020
985 0000000000000000000000000000000000000000000000000000000000000004
986 e4b88de500000000000000000000000000000000000000000000000000000000
987 "
988 );
989
990 assert_eq!(sol_data::String::abi_decode(&encoded).unwrap(), "不�".to_string());
991 }
992
993 #[test]
994 #[cfg_attr(miri, ignore = "OOM https://github.com/rust-lang/miri/issues/3637")]
995 fn decode_corrupted_dynamic_array() {
996 type MyTy = sol_data::Array<sol_data::Uint<32>>;
997 let encoded = hex!(
1002 "
1003 0000000000000000000000000000000000000000000000000000000000000020
1004 00000000000000000000000000000000000000000000000000000000ffffffff
1005 0000000000000000000000000000000000000000000000000000000000000001
1006 0000000000000000000000000000000000000000000000000000000000000002
1007 "
1008 );
1009 assert!(MyTy::abi_decode_sequence(&encoded).is_err());
1010 }
1011
1012 #[test]
1013 fn decode_dynamic_array_preallocation() {
1014 type MyTy = sol_data::Array<sol_data::Uint<32>>;
1015 let mut encoded = Vec::with_capacity(64);
1016 encoded.extend_from_slice(pad_usize(32).as_slice());
1017 encoded.extend_from_slice(pad_usize(usize::MAX).as_slice());
1018
1019 let err = MyTy::abi_decode_sequence(&encoded).unwrap_err();
1020 assert_eq!(err, Error::Overrun);
1021 }
1022
1023 #[test]
1024 fn decode_dynamic_array_of_zero_sized_type() {
1025 type MyTy = sol_data::Array<()>;
1026 let mut encoded = Vec::with_capacity(64);
1027 encoded.extend_from_slice(pad_usize(32).as_slice());
1028 encoded.extend_from_slice(pad_usize(2).as_slice());
1029
1030 assert_eq!(MyTy::abi_decode_sequence(&encoded).unwrap(), vec![(), ()]);
1031 }
1032
1033 #[test]
1034 fn decode_huge_dynamic_array_of_zero_sized_type_exceeds_memory_limit() {
1035 type MyTy = sol_data::Array<()>;
1036 let mut encoded = Vec::with_capacity(64);
1037 encoded.extend_from_slice(pad_usize(32).as_slice());
1038 encoded.extend_from_slice(pad_usize(u32::MAX as usize).as_slice());
1039
1040 assert_eq!(
1041 decode_sequence::<<MyTy as SolType>::Token<'_>>(&encoded),
1042 Err(Error::MemoryLimitExceeded(DEFAULT_MEMORY_LIMIT)),
1043 );
1044 }
1045
1046 #[test]
1047 fn decode_nested_dynamic_array_of_zero_sized_type() {
1048 type MyTy = sol_data::Array<sol_data::Array<()>>;
1049 let mut encoded = Vec::with_capacity(128);
1050 encoded.extend_from_slice(pad_usize(32).as_slice());
1051 encoded.extend_from_slice(pad_usize(1).as_slice());
1052 encoded.extend_from_slice(pad_usize(32).as_slice());
1053 encoded.extend_from_slice(pad_usize(2).as_slice());
1054
1055 assert_eq!(MyTy::abi_decode_sequence(&encoded).unwrap(), vec![vec![(), ()]]);
1056 }
1057
1058 #[test]
1059 fn decode_dynamic_array_of_multiword_static_type() {
1060 type MyTy = sol_data::Array<sol_data::FixedArray<sol_data::Uint<32>, 2>>;
1061 let mut encoded = Vec::with_capacity(96);
1062 encoded.extend_from_slice(pad_usize(32).as_slice());
1063 encoded.extend_from_slice(pad_usize(1).as_slice());
1064 encoded.extend_from_slice(pad_usize(1).as_slice());
1066
1067 let err = MyTy::abi_decode_sequence(&encoded).unwrap_err();
1068 assert_eq!(err, Error::Overrun);
1069 }
1070
1071 #[test]
1072 fn decode_dynamic_array_required_words_overflow() {
1073 type MyTy = sol_data::Array<sol_data::FixedArray<sol_data::Uint<32>, 2>>;
1074 let mut encoded = Vec::with_capacity(64);
1075 encoded.extend_from_slice(pad_usize(32).as_slice());
1076 encoded.extend_from_slice(pad_usize(usize::MAX).as_slice());
1077
1078 let err = MyTy::abi_decode_sequence(&encoded).unwrap_err();
1079 assert_eq!(err, Error::Overrun);
1080 }
1081
1082 #[test]
1083 fn decode_dynamic_array_of_dynamic_type() {
1084 type MyTy = sol_data::Array<sol_data::Array<sol_data::FixedArray<sol_data::Uint<32>, 3>>>;
1085 let mut encoded = Vec::with_capacity(128);
1086 encoded.extend_from_slice(pad_usize(32).as_slice());
1087 encoded.extend_from_slice(pad_usize(1).as_slice());
1088 encoded.extend_from_slice(pad_usize(32).as_slice());
1090 encoded.extend_from_slice(pad_usize(0).as_slice());
1092
1093 let decoded = MyTy::abi_decode_sequence(&encoded).unwrap();
1094 assert_eq!(decoded.len(), 1);
1095 assert!(decoded[0].is_empty());
1096 }
1097
1098 #[test]
1099 fn decode_verify_addresses() {
1100 let input = hex!(
1101 "
1102 0000000000000000000000000000000000000000000000000000000000012345
1103 0000000000000000000000000000000000000000000000000000000000054321
1104 "
1105 );
1106
1107 assert_eq!(
1108 sol_data::Address::abi_decode(&input).unwrap(),
1109 address!("0000000000000000000000000000000000012345")
1110 );
1111 assert!(<(sol_data::Address, sol_data::Address)>::abi_decode(&input).is_ok());
1112 }
1113
1114 #[test]
1115 fn decode_verify_bytes() {
1116 type MyTy2 = (sol_data::Address, sol_data::Address);
1117
1118 let input = hex!(
1119 "
1120 0000000000000000000000001234500000000000000000000000000000012345
1121 0000000000000000000000005432100000000000000000000000000000054321
1122 "
1123 );
1124 assert!(MyTy2::abi_decode_params(&input).is_ok());
1125 }
1126
1127 #[test]
1128 fn signed_int_dirty_high_bytes() {
1129 type MyTy = sol_data::Int<8>;
1130
1131 let dirty_negative =
1132 hex!("f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
1133
1134 assert_eq!(MyTy::abi_decode(&dirty_negative).unwrap(), -1);
1135
1136 let dirty_positive =
1137 hex!("700000000000000000000000000000000000000000000000000000000000007f");
1138
1139 assert_eq!(MyTy::abi_decode(&dirty_positive).unwrap(), 127);
1140 }
1141
1142 #[test]
1144 fn fixed_before_dynamic() {
1145 sol! {
1146 #[derive(Debug, PartialEq, Eq)]
1147 struct Ty {
1148 bytes32[3] arr;
1149 bytes dyn;
1150 }
1151 }
1152
1153 let ty = Ty {
1154 arr: [[0x11u8; 32].into(), [0x22u8; 32].into(), [0x33u8; 32].into()],
1155 r#dyn: bytes![0x44u8; 4],
1156 };
1157 let encoded = hex!(
1158 "0000000000000000000000000000000000000000000000000000000000000020"
1159 "1111111111111111111111111111111111111111111111111111111111111111"
1160 "2222222222222222222222222222222222222222222222222222222222222222"
1161 "3333333333333333333333333333333333333333333333333333333333333333"
1162 "0000000000000000000000000000000000000000000000000000000000000080"
1163 "0000000000000000000000000000000000000000000000000000000000000004"
1164 "4444444400000000000000000000000000000000000000000000000000000000"
1165 );
1166 assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
1167 assert_eq!(ty.abi_encoded_size(), encoded.len());
1168
1169 assert_eq!(<Ty as SolType>::abi_decode(&encoded).unwrap(), ty);
1170 }
1171
1172 #[test]
1173 fn dynarray_before_dynamic() {
1174 sol! {
1175 #[derive(Debug, PartialEq, Eq)]
1176 struct Ty {
1177 bytes[3] arr;
1178 bytes dyn;
1179 }
1180 }
1181
1182 let ty = Ty {
1183 arr: [bytes![0x11u8; 32], bytes![0x22u8; 32], bytes![0x33u8; 32]],
1184 r#dyn: bytes![0x44u8; 4],
1185 };
1186 let encoded = hex!(
1187 "0000000000000000000000000000000000000000000000000000000000000020" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000160" "0000000000000000000000000000000000000000000000000000000000000060" "00000000000000000000000000000000000000000000000000000000000000a0" "00000000000000000000000000000000000000000000000000000000000000e0" "0000000000000000000000000000000000000000000000000000000000000020" "1111111111111111111111111111111111111111111111111111111111111111"
1195 "0000000000000000000000000000000000000000000000000000000000000020" "2222222222222222222222222222222222222222222222222222222222222222"
1197 "0000000000000000000000000000000000000000000000000000000000000020" "3333333333333333333333333333333333333333333333333333333333333333"
1199 "0000000000000000000000000000000000000000000000000000000000000004" "4444444400000000000000000000000000000000000000000000000000000000"
1201 );
1202 assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
1203 assert_eq!(ty.abi_encoded_size(), encoded.len());
1204
1205 assert_eq!(<Ty as SolType>::abi_decode(&encoded).unwrap(), ty);
1206 }
1207
1208 #[test]
1209 fn offset_overflow() {
1210 let encoded = hex!(
1211 "0000000000000000000000000000000000000000000000000000000000000020"
1212 "000000000000000000000000000000000000000000000000ffffffffffffffff"
1213 "0000000000000000000000000000000000000000000000000000000000000000"
1214 );
1215 let err = <sol_data::String as SolType>::abi_decode(&encoded).unwrap_err();
1216 assert_eq!(err, Error::Overrun);
1217 }
1218
1219 #[test]
1220 fn config_defaults_and_setters() {
1221 let mut config = AbiDecoderConfig::new();
1222 assert_eq!(config.get_recursion_limit(), 16);
1223 assert_eq!(config.get_memory_limit(), DEFAULT_MEMORY_LIMIT);
1224 assert!(!config.get_validate());
1225 assert!(!config.get_strict());
1226 assert!(!config.get_validate_allow_trailing_bytes());
1227
1228 config.set_recursion_limit(300);
1229 config.set_memory_limit(42);
1230 config.set_validate(true);
1231 config.set_strict(true);
1232 assert_eq!(config.get_recursion_limit(), 300);
1233 assert_eq!(config.get_memory_limit(), 42);
1234 assert!(config.get_validate());
1235 assert!(config.get_strict());
1236
1237 let config = AbiDecoderConfig::new().recursion_limit(400).memory_limit(24).strict(true);
1238 assert_eq!(config.get_recursion_limit(), 400);
1239 assert_eq!(config.get_memory_limit(), 24);
1240 assert!(config.get_validate());
1241 assert!(config.get_strict());
1242 }
1243
1244 #[test]
1245 fn validate_allow_trailing_bytes_config() {
1246 let mut config = AbiDecoderConfig::new().validate_allow_trailing_bytes(true);
1247 assert!(!config.get_validate());
1248 assert!(!config.get_strict());
1249 assert!(config.get_validate_allow_trailing_bytes());
1250
1251 config.set_validate_allow_trailing_bytes(false);
1252 assert!(!config.get_validate());
1253 assert!(!config.get_strict());
1254 assert!(!config.get_validate_allow_trailing_bytes());
1255
1256 config.set_strict(true);
1257 config.set_validate_allow_trailing_bytes(true);
1258 config.set_validate_allow_trailing_bytes(false);
1259 assert!(config.get_strict());
1260 assert!(config.get_validate());
1261
1262 config.set_strict(false);
1263 config.set_validate(true);
1264 config.set_validate_allow_trailing_bytes(true);
1265 assert!(!config.get_strict());
1266 assert!(config.get_validate());
1267 assert!(config.get_validate_allow_trailing_bytes());
1268 config.set_validate_allow_trailing_bytes(false);
1269 assert!(!config.get_strict());
1270 assert!(config.get_validate());
1271 assert!(!config.get_validate_allow_trailing_bytes());
1272 }
1273
1274 #[test]
1275 fn validate_allow_trailing_bytes_accepts_encoded_prefixes() {
1276 fn check<T: SolType>(value: &T::RustType)
1277 where
1278 T::RustType: PartialEq + core::fmt::Debug,
1279 for<'de> T::Token<'de>: TokenSeq<'de>,
1280 {
1281 type Encode<T> = fn(&<T as SolType>::RustType) -> Vec<u8>;
1282 type Decode<T> = fn(&[u8], AbiDecoderConfig) -> Result<<T as SolType>::RustType>;
1283 let codecs: [(Encode<T>, Decode<T>); 3] = [
1284 (T::abi_encode, T::abi_decode_with_config),
1285 (T::abi_encode_params, |data, config| {
1286 T::abi_decode_params_with_config(data, config)
1287 }),
1288 (T::abi_encode_sequence, |data, config| {
1289 T::abi_decode_sequence_with_config(data, config)
1290 }),
1291 ];
1292 for (encode, decode) in codecs {
1293 for suffix in [&[][..], &[0xff][..], &[0xaa; 32][..], &[0xbb; 33][..]] {
1294 let mut encoded = encode(value);
1295 encoded.extend_from_slice(suffix);
1296 for config in [
1297 AbiDecoderConfig::new().validate(true),
1298 AbiDecoderConfig::new().validate(true).validate_allow_trailing_bytes(true),
1299 AbiDecoderConfig::new().validate_allow_trailing_bytes(true),
1300 AbiDecoderConfig::new().strict(true).validate_allow_trailing_bytes(true),
1301 AbiDecoderConfig::new().validate_allow_trailing_bytes(true).strict(true),
1302 ] {
1303 assert_eq!(&decode(&encoded, config).unwrap(), value);
1304 }
1305 if !suffix.is_empty() {
1306 assert_eq!(
1307 decode(&encoded, AbiDecoderConfig::new().strict(true)),
1308 Err(Error::ReserMismatch),
1309 );
1310 }
1311 }
1312 }
1313 }
1314
1315 check::<()>(&());
1316 check::<(sol_data::Uint<8>, sol_data::Bool)>(&(42, true));
1317 check::<(sol_data::Bytes, sol_data::Array<sol_data::String>)>(&(
1318 bytes!("1234"),
1319 vec!["hello".into(), alloc::string::String::new()],
1320 ));
1321 check::<(sol_data::Array<sol_data::Bytes>,)>(&(vec![],));
1322 }
1323
1324 #[test]
1325 fn validate_allow_trailing_bytes_keeps_other_checks() {
1326 let config = AbiDecoderConfig::new().strict(true).validate_allow_trailing_bytes(true);
1327 let value = bytes!("1122");
1328 let canonical = sol_data::Bytes::abi_encode(&value);
1329
1330 for len in [canonical.len() - 1, 65] {
1332 assert_eq!(
1333 sol_data::Bytes::abi_decode_with_config(&canonical[..len], config),
1334 Err(Error::Overrun),
1335 );
1336 }
1337 let mut dirty_padding = canonical.clone();
1338 dirty_padding[66] = 1;
1339 dirty_padding.push(0xff);
1340 assert_eq!(
1341 sol_data::Bytes::abi_decode_with_config(&dirty_padding, config),
1342 Err(Error::ReserMismatch),
1343 );
1344
1345 let mut gap = canonical;
1346 gap[31] = 64;
1347 gap.splice(32..32, [0; 32]);
1348 assert_eq!(
1349 sol_data::Bytes::abi_decode_with_config(&gap, config),
1350 Err(Error::ReserMismatch),
1351 );
1352
1353 type Pair = (sol_data::Bytes, sol_data::Bytes);
1354 let mut overlap = Pair::abi_encode_params(&(value.clone(), value));
1355 overlap[63] = overlap[31];
1356 assert_eq!(
1357 Pair::abi_decode_params_with_config(&overlap, config),
1358 Err(Error::ReserMismatch)
1359 );
1360
1361 let mut invalid_bool = Word::with_last_byte(2).to_vec();
1362 invalid_bool.push(0xff);
1363 assert!(sol_data::Bool::abi_decode_with_config(&invalid_bool, config).is_err());
1364
1365 let mut invalid_string = sol_data::Bytes::abi_encode(&bytes!("ff"));
1366 invalid_string.push(0xff);
1367 assert!(sol_data::String::abi_decode_with_config(&invalid_string, config).is_err());
1368 }
1369
1370 #[test]
1371 fn child_drop_keeps_the_furthest_strict_offset() {
1372 let decoder = Decoder::with_config(&[0; 192], AbiDecoderConfig::new().strict(true));
1373 let mut first = decoder.child(64).unwrap();
1374 let mut second = decoder.child(128).unwrap();
1375 first.take_word().unwrap();
1376 second.take_word().unwrap();
1377
1378 drop(second);
1379 drop(first);
1380
1381 assert_eq!(decoder.state.strict_next_offset().get(), 160);
1382 }
1383
1384 #[test]
1385 fn exhausted_decoder_debug_does_not_panic() {
1386 let mut decoder = Decoder::new(&[0; 32]);
1387 decoder.take_word().unwrap();
1388 assert!(!format!("{decoder:?}").is_empty());
1389 }
1390
1391 #[test]
1392 fn configured_decoder_validation() {
1393 let encoded = B256::repeat_byte(0x11);
1394 assert!(
1395 sol_data::Bool::abi_decode_with_config(encoded.as_slice(), AbiDecoderConfig::new())
1396 .is_ok()
1397 );
1398 assert!(
1399 sol_data::Bool::abi_decode_with_config(
1400 encoded.as_slice(),
1401 AbiDecoderConfig::new().validate(true),
1402 )
1403 .is_err()
1404 );
1405 assert!(
1406 sol_data::Bool::abi_decode_with_config(
1407 encoded.as_slice(),
1408 AbiDecoderConfig::new().strict(true),
1409 )
1410 .is_err()
1411 );
1412 }
1413
1414 #[test]
1415 fn strict_decoder_rejects_noncanonical_bool() {
1416 let encoded = Word::with_last_byte(2);
1417
1418 assert_eq!(sol_data::Bool::abi_decode(encoded.as_slice()), Ok(true));
1419 assert!(
1420 sol_data::Bool::abi_decode_with_config(
1421 encoded.as_slice(),
1422 AbiDecoderConfig::new().validate(true),
1423 )
1424 .is_err()
1425 );
1426 assert!(
1427 sol_data::Bool::abi_decode_with_config(
1428 encoded.as_slice(),
1429 AbiDecoderConfig::new().strict(true),
1430 )
1431 .is_err()
1432 );
1433 }
1434
1435 #[test]
1436 fn strict_decoder_rejects_overlapping_nested_offsets() {
1437 type Ty = sol_data::Array<sol_data::Bytes>;
1438
1439 let encoded = hex!(
1440 "0000000000000000000000000000000000000000000000000000000000000020" "0000000000000000000000000000000000000000000000000000000000000002" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000001" "1100000000000000000000000000000000000000000000000000000000000000"
1446 );
1447
1448 assert_eq!(Ty::abi_decode(&encoded).unwrap(), vec![bytes![0x11u8; 1], bytes![0x11u8; 1]]);
1449 assert_eq!(
1450 Ty::abi_decode_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1451 Err(Error::ReserMismatch),
1452 );
1453 }
1454
1455 #[test]
1456 fn strict_decoder_accepts_canonical_offsets() {
1457 type Ty = (sol_data::Bytes, sol_data::Bytes);
1458
1459 let value = (bytes![0x11u8, 0x22], bytes![0x33u8, 0x44]);
1460 let encoded = Ty::abi_encode_params(&value);
1461
1462 assert_eq!(
1463 Ty::abi_decode_params_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1464 Ok(value),
1465 );
1466 }
1467
1468 #[test]
1469 fn strict_decoder_accepts_static_composites_around_dynamic_fields() {
1470 type Uint = sol_data::Uint<256>;
1471 type StaticTuple = (Uint, Uint);
1472 type StaticArray = sol_data::FixedArray<StaticTuple, 2>;
1473 type Ty = (StaticTuple, sol_data::Bytes, StaticArray, sol_data::Bytes);
1474
1475 let value = (
1476 (U256::from(1), U256::from(2)),
1477 bytes![0x11u8; 1],
1478 [(U256::from(3), U256::from(4)), (U256::from(5), U256::from(6))],
1479 bytes![0x22u8; 1],
1480 );
1481 let encoded = Ty::abi_encode_params(&value);
1482
1483 assert_eq!(
1484 Ty::abi_decode_params_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1485 Ok(value),
1486 );
1487 }
1488
1489 #[test]
1490 fn strict_decoder_accepts_dynamic_array_sequence() {
1491 type Ty = sol_data::Array<sol_data::Bytes>;
1492
1493 let value = vec![bytes![0x11u8; 1], bytes!("2233")];
1494 let encoded = Ty::abi_encode(&value);
1495
1496 assert_eq!(
1497 Ty::abi_decode_sequence_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1498 Ok(value),
1499 );
1500 }
1501
1502 #[test]
1503 fn strict_decoder_accepts_dynamic_fixed_array_sequence() {
1504 type Ty = sol_data::FixedArray<sol_data::Bytes, 2>;
1505
1506 let value = [bytes![0x11u8; 1], bytes!("2233")];
1507 let encoded = Ty::abi_encode_sequence(&value);
1508
1509 assert_eq!(
1510 Ty::abi_decode_sequence_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1511 Ok(value),
1512 );
1513 }
1514
1515 #[test]
1516 fn strict_decoder_accepts_empty_dynamic_sequences() {
1517 type Fixed = sol_data::FixedArray<sol_data::Bytes, 0>;
1518
1519 let fixed: [alloy_primitives::Bytes; 0] = [];
1520 let encoded = Fixed::abi_encode(&fixed);
1521 assert_eq!(
1522 Fixed::abi_decode_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1523 Ok(fixed),
1524 );
1525
1526 type Dynamic = sol_data::Array<()>;
1527
1528 let dynamic = vec![];
1529 let encoded = Dynamic::abi_encode(&dynamic);
1530 assert_eq!(
1531 Dynamic::abi_decode_sequence_with_config(
1532 &encoded,
1533 AbiDecoderConfig::new().strict(true)
1534 ),
1535 Ok(dynamic),
1536 );
1537 }
1538
1539 #[test]
1540 fn strict_decoder_rejects_nonempty_zero_sized_dynamic_arrays() {
1541 type Ty = sol_data::Array<()>;
1542
1543 let encoded = hex!(
1544 "0000000000000000000000000000000000000000000000000000000000000020"
1545 "0000000000000000000000000000000000000000000000000000000000000001"
1546 );
1547
1548 assert_eq!(Ty::abi_decode_sequence(&encoded), Ok(vec![()]));
1549 assert_eq!(
1550 Ty::abi_decode_sequence_with_config(&encoded, AbiDecoderConfig::new().memory_limit(0)),
1551 Err(Error::MemoryLimitExceeded(0)),
1552 );
1553 assert_eq!(
1554 Ty::abi_decode_sequence_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1555 Err(Error::ReserMismatch),
1556 );
1557 }
1558
1559 #[test]
1560 fn strict_decoder_checks_dynamic_elements_before_reserving_the_outer_array() {
1561 type Ty = sol_data::Array<sol_data::FixedArray<sol_data::Bytes, 64>>;
1562
1563 let mut encoded = Vec::with_capacity(32 * 66);
1564 encoded.extend_from_slice(pad_usize(32).as_slice());
1565 encoded.extend_from_slice(pad_usize(1).as_slice());
1566 encoded.resize(32 * 66, 0);
1567
1568 assert_eq!(
1569 Ty::abi_decode_sequence_with_config(
1570 &encoded,
1571 AbiDecoderConfig::new().memory_limit(0).strict(true),
1572 ),
1573 Err(Error::ReserMismatch),
1574 );
1575 }
1576
1577 #[test]
1578 fn strict_decoder_rejects_gapped_offsets() {
1579 type Ty = (sol_data::String, sol_data::String);
1580
1581 let value = ("one".to_string(), "two".to_string());
1582 let mut encoded = Ty::abi_encode(&value);
1583 encoded[95] = 0xa0;
1584 encoded.splice(160..160, [0; 32]);
1585
1586 assert_eq!(Ty::abi_decode(&encoded), Ok(value));
1587 assert_eq!(
1588 Ty::abi_decode_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1589 Err(Error::ReserMismatch),
1590 );
1591 }
1592
1593 #[test]
1594 fn strict_decoder_rejects_trailing_data() {
1595 type Ty = (sol_data::Bytes, sol_data::Bytes);
1596
1597 let value = (bytes![0x11u8; 1], bytes![0x22u8; 1]);
1598 let mut encoded = Ty::abi_encode_params(&value);
1599 encoded.extend([0; 32]);
1600
1601 assert_eq!(Ty::abi_decode_params(&encoded), Ok(value));
1602 assert_eq!(
1603 Ty::abi_decode_params_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1604 Err(Error::ReserMismatch),
1605 );
1606 }
1607
1608 #[test]
1609 fn strict_decoder_accepts_nested_encoder_output() {
1610 type Ty = (
1611 sol_data::String,
1612 sol_data::Array<sol_data::Array<sol_data::Address>>,
1613 sol_data::Bytes,
1614 );
1615
1616 let value = (
1617 "strict".to_string(),
1618 vec![vec![Address::repeat_byte(0x11)], vec![Address::repeat_byte(0x22)]],
1619 bytes!("beef"),
1620 );
1621 let encoded = Ty::abi_encode(&value);
1622
1623 assert_eq!(
1624 Ty::abi_decode_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1625 Ok(value),
1626 );
1627 }
1628
1629 #[test]
1630 fn strict_decoder_rejects_nonzero_padding() {
1631 let encoded = hex!(
1632 "0000000000000000000000000000000000000000000000000000000000000020"
1633 "0000000000000000000000000000000000000000000000000000000000000001"
1634 "11ff000000000000000000000000000000000000000000000000000000000000"
1635 );
1636
1637 assert_eq!(sol_data::Bytes::abi_decode(&encoded).unwrap(), bytes![0x11u8; 1]);
1638 assert_eq!(
1639 sol_data::Bytes::abi_decode_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1640 Err(Error::ReserMismatch),
1641 );
1642 }
1643
1644 #[test]
1645 fn strict_decoder_rejects_overlapping_bytes_offsets() {
1646 type Ty = (sol_data::Bytes, sol_data::Bytes);
1647
1648 let encoded = hex!(
1649 "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000003" "1122330000000000000000000000000000000000000000000000000000000000"
1653 );
1654
1655 assert_eq!(
1656 Ty::abi_decode_params(&encoded).unwrap(),
1657 (bytes![0x11u8, 0x22, 0x33], bytes![0x11u8, 0x22, 0x33]),
1658 );
1659 assert_eq!(
1660 Ty::abi_decode_params_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1661 Err(Error::ReserMismatch),
1662 );
1663 }
1664
1665 #[test]
1666 fn strict_decoder_rejects_overlapping_dynamic_array_offsets() {
1667 type Ty = (sol_data::Array<sol_data::Uint<256>>, sol_data::Array<sol_data::Uint<256>>);
1668
1669 let encoded = hex!(
1670 "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000002" "0000000000000000000000000000000000000000000000000000000000000001"
1674 "0000000000000000000000000000000000000000000000000000000000000002"
1675 );
1676
1677 assert_eq!(
1678 Ty::abi_decode_params(&encoded).unwrap(),
1679 (vec![U256::from(1), U256::from(2)], vec![U256::from(1), U256::from(2)]),
1680 );
1681 assert_eq!(
1682 Ty::abi_decode_params_with_config(&encoded, AbiDecoderConfig::new().strict(true)),
1683 Err(Error::ReserMismatch),
1684 );
1685 assert_eq!(
1686 Ty::abi_decode_params_with_config(&encoded, AbiDecoderConfig::new().memory_limit(64)),
1687 Err(Error::MemoryLimitExceeded(64)),
1688 );
1689 assert_eq!(
1690 Ty::abi_decode_params_with_config(
1691 &encoded,
1692 AbiDecoderConfig::new().memory_limit(64).strict(true),
1693 ),
1694 Err(Error::ReserMismatch),
1695 );
1696 }
1697
1698 #[test]
1699 fn configured_decoder_enforces_memory_limit() {
1700 type Ty = sol_data::Array<sol_data::Uint<256>>;
1701
1702 let encoded = Ty::abi_encode(&vec![U256::ZERO]);
1703 let err = decode_sequence_with_config::<<Ty as SolType>::Token<'_>>(
1704 &encoded,
1705 AbiDecoderConfig::new().memory_limit(31),
1706 )
1707 .unwrap_err();
1708 assert_eq!(err, Error::MemoryLimitExceeded(31));
1709 }
1710
1711 #[test]
1712 fn direct_decoder_enforces_memory_limit() {
1713 type Ty = sol_data::Array<sol_data::Uint<256>>;
1714
1715 let encoded = Ty::abi_encode(&vec![U256::ZERO]);
1716 let mut decoder = Decoder::with_config(&encoded, AbiDecoderConfig::new().memory_limit(31));
1717 let err = decoder.decode::<<Ty as SolType>::Token<'_>>().unwrap_err();
1718 assert_eq!(err, Error::MemoryLimitExceeded(31));
1719 }
1720
1721 #[test]
1722 fn child_decoder_borrows_parent_state() {
1723 type Ty = sol_data::Array<sol_data::Uint<256>>;
1724
1725 let encoded = Ty::abi_encode(&vec![U256::ZERO]);
1726 let decoder = Decoder::with_config(&encoded, AbiDecoderConfig::new().memory_limit(31));
1727 let mut child = decoder.child(0).unwrap();
1728 let err = child.decode::<<Ty as SolType>::Token<'_>>().unwrap_err();
1729 assert_eq!(err, Error::MemoryLimitExceeded(31));
1730 }
1731
1732 #[test]
1733 fn configured_decoder_tracks_child_allocations() {
1734 type Ty = sol_data::Array<sol_data::Array<sol_data::Uint<256>>>;
1735
1736 let encoded = Ty::abi_encode(&vec![vec![U256::ZERO], vec![U256::ZERO]]);
1737 let err = decode_sequence_with_config::<<Ty as SolType>::Token<'_>>(
1738 &encoded,
1739 AbiDecoderConfig::new().memory_limit(100),
1740 )
1741 .unwrap_err();
1742 assert_eq!(err, Error::MemoryLimitExceeded(100));
1743 }
1744
1745 #[test]
1746 fn configured_decoder_tracks_recursive_allocations() {
1747 type Uint = sol_data::Uint<256>;
1748 type Inner = sol_data::Array<Uint>;
1749 type Middle = sol_data::Array<Inner>;
1750 type Ty = sol_data::Array<Middle>;
1751
1752 let value = vec![vec![vec![U256::ZERO]], vec![vec![U256::ZERO]]];
1753 let encoded = Ty::abi_encode(&value);
1754 let memory_used = 2 * core::mem::size_of::<<Middle as SolType>::Token<'_>>()
1755 + 2 * core::mem::size_of::<<Inner as SolType>::Token<'_>>()
1756 + 2 * core::mem::size_of::<<Uint as SolType>::Token<'_>>();
1757
1758 decode_sequence_with_config::<<Ty as SolType>::Token<'_>>(
1759 &encoded,
1760 AbiDecoderConfig::new().memory_limit(memory_used),
1761 )
1762 .unwrap();
1763 let err = decode_sequence_with_config::<<Ty as SolType>::Token<'_>>(
1764 &encoded,
1765 AbiDecoderConfig::new().memory_limit(memory_used - 1),
1766 )
1767 .unwrap_err();
1768 assert_eq!(err, Error::MemoryLimitExceeded(memory_used - 1));
1769 }
1770
1771 #[test]
1772 fn configured_decoder_tracks_aliased_tuple_allocations() {
1773 sol! {
1774 struct Rule {
1775 bytes4 selector;
1776 address[] recipients;
1777 }
1778
1779 struct Scope {
1780 address target;
1781 Rule[] rules;
1782 }
1783
1784 function apply(address account, Scope[] scopes);
1785 }
1786
1787 fn word(value: usize) -> [u8; 32] {
1788 let mut out = [0_u8; 32];
1789 out[24..].copy_from_slice(&(value as u64).to_be_bytes());
1790 out
1791 }
1792
1793 fn aliased_call_data(width: usize) -> Vec<u8> {
1794 let mut data = Vec::with_capacity(292 + 96 * width);
1795 data.extend(applyCall::SELECTOR);
1796
1797 data.extend(word(0));
1798 data.extend(word(64));
1799
1800 data.extend(word(width));
1801 for _ in 0..width {
1802 data.extend(word(width * 32));
1803 }
1804
1805 data.extend(word(1));
1806 data.extend(word(64));
1807
1808 data.extend(word(width));
1809 for _ in 0..width {
1810 data.extend(word(width * 32));
1811 }
1812
1813 let mut selector = [0_u8; 32];
1814 selector[..4].copy_from_slice(&[0xde, 0xad, 0xbe, 0xef]);
1815 data.extend(selector);
1816 data.extend(word(64));
1817
1818 data.extend(word(width));
1819 for i in 0..width {
1820 data.extend(word(i + 1));
1821 }
1822
1823 assert_eq!(data.len(), 292 + 96 * width);
1824 data
1825 }
1826
1827 type Address = sol_data::Address;
1828
1829 let width = 2_usize;
1830 let data = aliased_call_data(width);
1831 let memory_used = width * core::mem::size_of::<<Scope as SolType>::Token<'_>>()
1832 + width.pow(2) * core::mem::size_of::<<Rule as SolType>::Token<'_>>()
1833 + width.pow(3) * core::mem::size_of::<<Address as SolType>::Token<'_>>();
1834
1835 applyCall::abi_decode_with_config(&data, AbiDecoderConfig::new().memory_limit(memory_used))
1836 .unwrap();
1837 let err = match applyCall::abi_decode_with_config(
1838 &data,
1839 AbiDecoderConfig::new().memory_limit(memory_used - 1),
1840 ) {
1841 Ok(_) => panic!("decoding should exceed the memory limit"),
1842 Err(err) => err,
1843 };
1844 assert_eq!(err, Error::MemoryLimitExceeded(memory_used - 1));
1845
1846 let strict_memory_used = width
1847 * (core::mem::size_of::<<Scope as SolType>::Token<'_>>()
1848 + core::mem::size_of::<<Rule as SolType>::Token<'_>>()
1849 + core::mem::size_of::<<Address as SolType>::Token<'_>>());
1850 let err = match applyCall::abi_decode_with_config(
1851 &data,
1852 AbiDecoderConfig::new().memory_limit(strict_memory_used).strict(true),
1853 ) {
1854 Ok(_) => panic!("strict decoding should reject aliased offsets"),
1855 Err(err) => err,
1856 };
1857 assert_eq!(err, Error::ReserMismatch);
1858 }
1859
1860 #[test]
1861 fn configured_decoder_enforces_recursion_limit() {
1862 type Ty = sol_data::Array<sol_data::Uint<256>>;
1863
1864 let encoded = Ty::abi_encode(&vec![U256::ZERO]);
1865 let err = decode_sequence_with_config::<<Ty as SolType>::Token<'_>>(
1866 &encoded,
1867 AbiDecoderConfig::new().recursion_limit(0),
1868 )
1869 .unwrap_err();
1870 assert_eq!(err, Error::RecursionLimitExceeded(0));
1871 }
1872}