ApeWorX / ApeWorX/eth-abi

Confusing OverflowError when decoding a value with the incorrect ABI

Open
#142 0 comments 0 reactions 0 assignees View on GitHub
p2
Dominant language
Python
Stars
256
Forks
117
Avg merge
4m
Merged PRs (30d)
1

Description

_If this is a bug report, please fill in the following sections.
If this is a feature request, delete and describe what you would like with examples._

## What was wrong?

The following code attempts to decode data using an ABI that is not *quite* correct. The correct ABI should be `['uint256', 'int128[7]', 'bytes', 'int128[3][3]', 'uint256', 'uint256']`. When executed, it results in an `OverflowError` instead of a helpful exception message.

```python
>>> data = HexBytes('0x000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005686f727365000000000000000000000000000000000000000000000000000000')
>>> decode_abi(['(uint256,int128[7],bytes,int128[3][3],uint256,uint256)'], data)
---------------------------------------------------------------------------
OverflowError Traceback (most recent call last)
in
----> 1 w3.codec.decode_abi(ot, data)

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/codec.py in decode_abi(self, types, data)
179 stream = self.stream_class(data)
180
--> 181 return decoder(stream)
182
183

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in __call__(self, stream)
125
126 def __call__(self, stream: ContextFramesBytesIO) -> Any:
--> 127 return self.decode(stream)
128
129

~/python-environments/web3/lib/python3.7/site-packages/eth_utils/functional.py in inner(*args, **kwargs)
43 @functools.wraps(fn)
44 def inner(*args, **kwargs) -> T: # type: ignore
---> 45 return callback(fn(*args, **kwargs))
46
47 return inner

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in decode(self, stream)
171 def decode(self, stream):
172 for decoder in self.decoders:
--> 173 yield decoder(stream)
174
175 @parse_tuple_type_str

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in __call__(self, stream)
125
126 def __call__(self, stream: ContextFramesBytesIO) -> Any:
--> 127 return self.decode(stream)
128
129

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in decode(self, stream)
143
144 stream.push_frame(start_pos)
--> 145 value = self.tail_decoder(stream)
146 stream.pop_frame()
147

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in __call__(self, stream)
125
126 def __call__(self, stream: ContextFramesBytesIO) -> Any:
--> 127 return self.decode(stream)
128
129

~/python-environments/web3/lib/python3.7/site-packages/eth_utils/functional.py in inner(*args, **kwargs)
43 @functools.wraps(fn)
44 def inner(*args, **kwargs) -> T: # type: ignore
---> 45 return callback(fn(*args, **kwargs))
46
47 return inner

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in decode(self, stream)
171 def decode(self, stream):
172 for decoder in self.decoders:
--> 173 yield decoder(stream)
174
175 @parse_tuple_type_str

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in __call__(self, stream)
125
126 def __call__(self, stream: ContextFramesBytesIO) -> Any:
--> 127 return self.decode(stream)
128
129

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in decode(self, stream)
142 start_pos = decode_uint_256(stream)
143
--> 144 stream.push_frame(start_pos)
145 value = self.tail_decoder(stream)
146 stream.pop_frame()

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in push_frame(self, offset)
93 self._total_offset += offset
94
---> 95 self.seek_in_frame(0)
96
97 def pop_frame(self):

~/python-environments/web3/lib/python3.7/site-packages/eth_abi/decoding.py in seek_in_frame(self, pos, *args, **kwargs)
82 Seeks relative to the total offset of the current contextual frames.
83 """
---> 84 self.seek(self._total_offset + pos, *args, **kwargs)
85
86 def push_frame(self, offset):

OverflowError: Python int too large to convert to C ssize_t
```

## How can it be fixed?

When we are about to push a new frame onto the decoding stream we should first sanity check the value, and if the value is beyond the end of the stream, we should raise a more intelligent error message.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.