Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusing OverflowError when decoding a value with the incorrect ABI #142

Open
pipermerriam opened this issue Jul 25, 2020 · 0 comments
Open
Labels

Comments

@pipermerriam
Copy link
Member

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.

>>> data = HexBytes('0x000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005686f727365000000000000000000000000000000000000000000000000000000')
>>> decode_abi(['(uint256,int128[7],bytes,int128[3][3],uint256,uint256)'], data)
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-63-b16dfb7b0383> in <module>
----> 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants