Merge pull request #6911 from ethereum/asmCallTrailingComma

AsmParser: Disallow trailing commas in function call arguments.
This commit is contained in:
Mathias L. Baumann 2019-06-06 14:05:11 +02:00 committed by GitHub
commit 44c774af4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 8 deletions

View File

@ -9,6 +9,7 @@ Compiler Features:
Bugfixes: Bugfixes:
* Yul / Inline Assembly Parser: Disallow trailing commas in function call arguments.
Build System: Build System:

View File

@ -550,13 +550,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(arguments.size() > 0, "Expected at least one parameter for require/assert"); solAssert(arguments.size() > 0, "Expected at least one parameter for require/assert");
solAssert(arguments.size() <= 2, "Expected no more than two parameters for require/assert"); solAssert(arguments.size() <= 2, "Expected no more than two parameters for require/assert");
Type const* messageArgumentType = arguments.size() > 1 ? arguments[1]->annotation().type : nullptr;
string requireOrAssertFunction = m_utils.requireOrAssertFunction( string requireOrAssertFunction = m_utils.requireOrAssertFunction(
functionType->kind() == FunctionType::Kind::Assert, functionType->kind() == FunctionType::Kind::Assert,
arguments.size() > 1 ? arguments[1]->annotation().type : nullptr messageArgumentType
); );
m_code << move(requireOrAssertFunction) << "(" << m_context.variable(*arguments[0]); m_code << move(requireOrAssertFunction) << "(" << m_context.variable(*arguments[0]);
if (arguments.size() > 1) if (messageArgumentType && messageArgumentType->sizeOnStack() > 0)
m_code << ", " << m_context.variable(*arguments[1]); m_code << ", " << m_context.variable(*arguments[1]);
m_code << ")\n"; m_code << ")\n";

View File

@ -609,12 +609,14 @@ Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
else else
ret = std::move(boost::get<FunctionCall>(_initialOp)); ret = std::move(boost::get<FunctionCall>(_initialOp));
expectToken(Token::LParen); expectToken(Token::LParen);
while (currentToken() != Token::RParen) if (currentToken() != Token::RParen)
{ {
ret.arguments.emplace_back(parseExpression()); ret.arguments.emplace_back(parseExpression());
if (currentToken() == Token::RParen) while (currentToken() != Token::RParen)
break; {
expectToken(Token::Comma); expectToken(Token::Comma);
ret.arguments.emplace_back(parseExpression());
}
} }
ret.location.end = endPosition(); ret.location.end = endPosition();
expectToken(Token::RParen); expectToken(Token::RParen);

View File

@ -3,10 +3,9 @@ contract C {
assembly { assembly {
function f(a, b) {} function f(a, b) {}
f() f()
f(1,)
f(,1) f(,1)
} }
} }
} }
// ---- // ----
// ParserError: (113-114): Literal, identifier or instruction expected. // ParserError: (101-102): Literal, identifier or instruction expected.

View File

@ -0,0 +1,11 @@
contract C {
function f() public pure {
assembly {
function f(a, b) {}
f()
f(1,)
}
}
}
// ----
// ParserError: (103-104): Literal, identifier or instruction expected.

View File

@ -0,0 +1,10 @@
contract C {
function f() public pure {
assembly {
function f(a, b, c) {}
f(1,,1)
}
}
}
// ----
// ParserError: (96-97): Literal, identifier or instruction expected.