diff --git a/tests/abi_types/test_invalid_abi_types.py b/tests/abi_types/test_invalid_abi_types.py new file mode 100644 index 0000000000..c8566e066f --- /dev/null +++ b/tests/abi_types/test_invalid_abi_types.py @@ -0,0 +1,26 @@ +import pytest + +from vyper.abi_types import ( + ABI_Bytes, + ABI_BytesM, + ABI_DynamicArray, + ABI_FixedMxN, + ABI_GIntM, + ABI_String, +) +from vyper.exceptions import InvalidABIType + +cases_invalid_types = [ + (ABI_GIntM, ((0, False), (7, False), (300, True), (300, False))), + (ABI_FixedMxN, ((0, 0, False), (8, 0, False), (256, 81, True), (300, 80, False))), + (ABI_BytesM, ((0,), (33,), (-10,))), + (ABI_Bytes, ((-1,), (-69,))), + (ABI_DynamicArray, ((ABI_GIntM(256, False), -1), (ABI_String(256), -10))), +] + + +@pytest.mark.parametrize("typ,params_variants", cases_invalid_types) +def test_invalid_abi_types(assert_compile_failed, typ, params_variants): + # double parametrization cannot work because the 2nd dimension is variable + for params in params_variants: + assert_compile_failed(lambda: typ(*params), InvalidABIType) diff --git a/vyper/abi_types.py b/vyper/abi_types.py index b272996aed..051f8db19f 100644 --- a/vyper/abi_types.py +++ b/vyper/abi_types.py @@ -1,4 +1,4 @@ -from vyper.exceptions import CompilerPanic +from vyper.exceptions import InvalidABIType from vyper.utils import ceil32 @@ -69,7 +69,7 @@ def __repr__(self): class ABI_GIntM(ABIType): def __init__(self, m_bits, signed): if not (0 < m_bits <= 256 and 0 == m_bits % 8): - raise CompilerPanic("Invalid M provided for GIntM") + raise InvalidABIType("Invalid M provided for GIntM") self.m_bits = m_bits self.signed = signed @@ -117,9 +117,9 @@ def selector_name(self): class ABI_FixedMxN(ABIType): def __init__(self, m_bits, n_places, signed): if not (0 < m_bits <= 256 and 0 == m_bits % 8): - raise CompilerPanic("Invalid M for FixedMxN") + raise InvalidABIType("Invalid M for FixedMxN") if not (0 < n_places and n_places <= 80): - raise CompilerPanic("Invalid N for FixedMxN") + raise InvalidABIType("Invalid N for FixedMxN") self.m_bits = m_bits self.n_places = n_places @@ -142,7 +142,7 @@ def is_complex_type(self): class ABI_BytesM(ABIType): def __init__(self, m_bytes): if not 0 < m_bytes <= 32: - raise CompilerPanic("Invalid M for BytesM") + raise InvalidABIType("Invalid M for BytesM") self.m_bytes = m_bytes @@ -173,7 +173,7 @@ def selector_name(self): class ABI_StaticArray(ABIType): def __init__(self, subtyp, m_elems): if not m_elems >= 0: - raise CompilerPanic("Invalid M") + raise InvalidABIType("Invalid M") self.subtyp = subtyp self.m_elems = m_elems @@ -200,7 +200,7 @@ def is_complex_type(self): class ABI_Bytes(ABIType): def __init__(self, bytes_bound): if not bytes_bound >= 0: - raise CompilerPanic("Negative bytes_bound provided to ABI_Bytes") + raise InvalidABIType("Negative bytes_bound provided to ABI_Bytes") self.bytes_bound = bytes_bound @@ -234,7 +234,7 @@ def selector_name(self): class ABI_DynamicArray(ABIType): def __init__(self, subtyp, elems_bound): if not elems_bound >= 0: - raise CompilerPanic("Negative bound provided to DynamicArray") + raise InvalidABIType("Negative bound provided to DynamicArray") self.subtyp = subtyp self.elems_bound = elems_bound diff --git a/vyper/exceptions.py b/vyper/exceptions.py index 8b2020285a..3bde20356e 100644 --- a/vyper/exceptions.py +++ b/vyper/exceptions.py @@ -336,3 +336,7 @@ class UnfoldableNode(VyperInternalException): class TypeCheckFailure(VyperInternalException): """An issue was not caught during type checking that should have been.""" + + +class InvalidABIType(VyperInternalException): + """An internal routine constructed an invalid ABI type"""