Skip to content

Commit

Permalink
Do not crash on invalid indexed access
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Sep 26, 2018
1 parent 4d3cf0a commit e298c8e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 15 deletions.
34 changes: 21 additions & 13 deletions libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2280,15 +2280,17 @@ bool TypeChecker::visit(IndexAccess const& _access)
resultType = make_shared<TypeType>(make_shared<ArrayType>(DataLocation::Memory, typeType.actualType()));
else
{
expectType(*index, IntegerType(256));
if (auto length = dynamic_cast<RationalNumberType const*>(type(*index).get()))
resultType = make_shared<TypeType>(make_shared<ArrayType>(
DataLocation::Memory,
typeType.actualType(),
length->literalValue(nullptr)
));
else
if (!expectType(*index, IntegerType(256)))
m_errorReporter.fatalTypeError(index->location(), "Integer constant expected.");

auto length = dynamic_cast<RationalNumberType const*>(type(*index).get());
solAssert(length, "");

resultType = make_shared<TypeType>(make_shared<ArrayType>(
DataLocation::Memory,
typeType.actualType(),
length->literalValue(nullptr)
));
}
break;
}
Expand All @@ -2299,10 +2301,14 @@ bool TypeChecker::visit(IndexAccess const& _access)
m_errorReporter.typeError(_access.location(), "Index expression cannot be omitted.");
else
{
expectType(*index, IntegerType(256));
if (auto integerType = dynamic_cast<RationalNumberType const*>(type(*index).get()))
if (bytesType.numBytes() <= integerType->literalValue(nullptr))
m_errorReporter.typeError(_access.location(), "Out of bounds array access.");
if (!expectType(*index, IntegerType(256)))
m_errorReporter.fatalTypeError(_access.location(), "Integer constant expected.");

auto integerType = dynamic_cast<RationalNumberType const*>(type(*index).get());
solAssert(integerType, "");

if (bytesType.numBytes() <= integerType->literalValue(nullptr))
m_errorReporter.typeError(_access.location(), "Out of bounds array access.");
}
resultType = make_shared<FixedBytesType>(1);
isLValue = false; // @todo this heavily depends on how it is embedded
Expand Down Expand Up @@ -2470,7 +2476,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))
Expand Down Expand Up @@ -2499,7 +2505,9 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte
_expectedType.toString() +
"."
);
return false;
}
return true;
}

void TypeChecker::requireLValue(Expression const& _expression)
Expand Down
2 changes: 1 addition & 1 deletion libsolidity/analysis/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class TypeChecker: private ASTConstVisitor

/// 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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ contract C {
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): Integer constant expected.
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ contract C {
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): Integer constant expected.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ contract C {
}
// ----
// TypeError: (58-60): Type int_const -1 is not implicitly convertible to expected type uint256.
// TypeError: (56-61): Out of bounds array access.
// TypeError: (56-61): Integer constant expected.
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ contract C {
b[888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888];
}
}
// ----
// TypeError: (58-169): Type int_const 8888...(103 digits omitted)...8888 is not implicitly convertible to expected type uint256.
// TypeError: (56-170): Integer constant expected.

0 comments on commit e298c8e

Please sign in to comment.