From 763ae300233adb6650b6bc6d34c765f853960cd1 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 10 Oct 2018 19:33:45 +0200 Subject: [PATCH] Fixes crash on non-unsigned array index. --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 7 +++++-- libsolidity/analysis/TypeChecker.h | 2 +- .../syntaxTests/indexing/array_multidim_rational.sol | 11 +++++++++++ .../indexing/array_multim_overflow_index.sol | 11 +++++++++++ .../indexing/fixedbytes_negative_index.sol | 9 +++++++++ .../indexing/fixedbytes_noninteger_index.sol | 9 +++++++++ 7 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/syntaxTests/indexing/array_multidim_rational.sol create mode 100644 test/libsolidity/syntaxTests/indexing/array_multim_overflow_index.sol create mode 100644 test/libsolidity/syntaxTests/indexing/fixedbytes_negative_index.sol create mode 100644 test/libsolidity/syntaxTests/indexing/fixedbytes_noninteger_index.sol diff --git a/Changelog.md b/Changelog.md index 2d6f518c4..753d8f71f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -125,6 +125,7 @@ Bugfixes: * Type Checker: Dynamic types as key for public mappings return error instead of assertion fail. * Type Checker: Fix internal error when array index value is too large. * Type Checker: Fix internal error for array type conversions. + * Type Checker: Fix internal error when array index is not an unsigned. * Type System: Allow arbitrary exponents for literals with a mantissa of zero. * Parser: Fix incorrect source location for nameless parameters. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 39ea494d5..1c4064496 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2299,7 +2299,8 @@ bool TypeChecker::visit(IndexAccess const& _access) m_errorReporter.typeError(_access.location(), "Index expression cannot be omitted."); else { - expectType(*index, IntegerType(256)); + if (!expectType(*index, IntegerType(256))) + m_errorReporter.fatalTypeError(_access.location(), "Index expression cannot be represented as an unsigned integer."); if (auto integerType = dynamic_cast(type(*index).get())) if (bytesType.numBytes() <= integerType->literalValue(nullptr)) m_errorReporter.typeError(_access.location(), "Out of bounds array access."); @@ -2470,7 +2471,7 @@ Declaration const& TypeChecker::dereference(UserDefinedTypeName const& _typeName return *_typeName.annotation().referencedDeclaration; } -void TypeChecker::expectType(Expression const& _expression, Type const& _expectedType) +bool TypeChecker::expectType(Expression const& _expression, Type const& _expectedType) { _expression.accept(*this); if (!type(_expression)->isImplicitlyConvertibleTo(_expectedType)) @@ -2499,7 +2500,9 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte _expectedType.toString() + "." ); + return false; } + return true; } void TypeChecker::requireLValue(Expression const& _expression) diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 8d25a88ea..6ea99ca20 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -143,7 +143,7 @@ private: /// Runs type checks on @a _expression to infer its type and then checks that it is implicitly /// convertible to @a _expectedType. - void expectType(Expression const& _expression, Type const& _expectedType); + bool expectType(Expression const& _expression, Type const& _expectedType); /// Runs type checks on @a _expression to infer its type and then checks that it is an LValue. void requireLValue(Expression const& _expression); diff --git a/test/libsolidity/syntaxTests/indexing/array_multidim_rational.sol b/test/libsolidity/syntaxTests/indexing/array_multidim_rational.sol new file mode 100644 index 000000000..df9f8223b --- /dev/null +++ b/test/libsolidity/syntaxTests/indexing/array_multidim_rational.sol @@ -0,0 +1,11 @@ +contract C { + function f() public { + bytes[32] memory a; + a[8**90][8**90][8**90*0.1]; + } +} +// ---- +// TypeError: (67-72): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. +// TypeError: (74-79): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. +// TypeError: (81-90): Type rational_const 9485...(73 digits omitted)...5712 / 5 is not implicitly convertible to expected type uint256. +// TypeError: (65-91): Index expression cannot be represented as an unsigned integer. diff --git a/test/libsolidity/syntaxTests/indexing/array_multim_overflow_index.sol b/test/libsolidity/syntaxTests/indexing/array_multim_overflow_index.sol new file mode 100644 index 000000000..9c98ad451 --- /dev/null +++ b/test/libsolidity/syntaxTests/indexing/array_multim_overflow_index.sol @@ -0,0 +1,11 @@ +contract C { + function f() public { + bytes[32] memory a; + a[8**90][8**90][1 - 8**90]; + } +} +// ---- +// TypeError: (67-72): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. +// TypeError: (74-79): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. +// TypeError: (81-90): Type int_const -189...(75 digits omitted)...1423 is not implicitly convertible to expected type uint256. +// TypeError: (65-91): Index expression cannot be represented as an unsigned integer. diff --git a/test/libsolidity/syntaxTests/indexing/fixedbytes_negative_index.sol b/test/libsolidity/syntaxTests/indexing/fixedbytes_negative_index.sol new file mode 100644 index 000000000..123993178 --- /dev/null +++ b/test/libsolidity/syntaxTests/indexing/fixedbytes_negative_index.sol @@ -0,0 +1,9 @@ +contract C { + function f() public { + bytes32 b; + b[-1]; + } +} +// ---- +// TypeError: (58-60): Type int_const -1 is not implicitly convertible to expected type uint256. +// TypeError: (56-61): Index expression cannot be represented as an unsigned integer. diff --git a/test/libsolidity/syntaxTests/indexing/fixedbytes_noninteger_index.sol b/test/libsolidity/syntaxTests/indexing/fixedbytes_noninteger_index.sol new file mode 100644 index 000000000..adf7db61b --- /dev/null +++ b/test/libsolidity/syntaxTests/indexing/fixedbytes_noninteger_index.sol @@ -0,0 +1,9 @@ +contract C { + function f() public { + bytes32 b; + b[888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888]; + } +} +// ---- +// TypeError: (58-169): Type int_const 8888...(103 digits omitted)...8888 is not implicitly convertible to expected type uint256. +// TypeError: (56-170): Index expression cannot be represented as an unsigned integer.