From 3b75c5b45fdb1bfb49b4e157e031154c57b475f3 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 25 May 2017 00:27:48 +0100 Subject: [PATCH] Validate that only basic types are used in Julia --- libsolidity/inlineasm/AsmAnalysis.cpp | 20 ++++++++++++++++++++ libsolidity/inlineasm/AsmAnalysis.h | 1 + test/libjulia/Parser.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 742d2c1a2..ca50fdbeb 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -62,6 +62,7 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) bool AsmAnalyzer::operator()(assembly::Literal const& _literal) { + expectValidType(_literal.type, _literal.location); ++m_stackHeight; if (_literal.kind == assembly::LiteralKind::String && _literal.value.size() > 32) { @@ -186,7 +187,10 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl) } for (auto const& variable: _varDecl.variables) + { + expectValidType(variable.type, variable.location); boost::get(m_currentScope->identifiers.at(variable.name)).active = true; + } m_info.stackHeightInfo[&_varDecl] = m_stackHeight; return success; } @@ -195,7 +199,10 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) { Scope& bodyScope = scope(&_funDef.body); for (auto const& var: _funDef.arguments + _funDef.returns) + { + expectValidType(var.type, var.location); boost::get(bodyScope.identifiers.at(var.name)).active = true; + } int const stackHeight = m_stackHeight; m_stackHeight = _funDef.arguments.size() + _funDef.returns.size(); @@ -444,3 +451,16 @@ Scope& AsmAnalyzer::scope(Block const* _block) solAssert(scopePtr, "Scope requested but not present."); return *scopePtr; } + +void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _location) +{ +// if (!m_julia) +// return; + + if (!(set{"bool", "u8", "s8", "u32", "s32", "u64", "s64", "u128", "s128", "u256", "s256"}).count(type)) + m_errors.push_back(make_shared( + Error::Type::TypeError, + "User defined types (\"" + type + "\") are not supported yet.", + _location + )); +} diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index da4b76084..8244df845 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -88,6 +88,7 @@ private: bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1)); bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location); Scope& scope(assembly::Block const* _block); + void expectValidType(std::string const& type, SourceLocation const& _location); /// This is used when we enter the body of a function definition. There, the parameters /// and return parameters appear as variables which are already on the stack before diff --git a/test/libjulia/Parser.cpp b/test/libjulia/Parser.cpp index 31dbd2787..71b5bb068 100644 --- a/test/libjulia/Parser.cpp +++ b/test/libjulia/Parser.cpp @@ -110,7 +110,6 @@ do \ BOOST_CHECK(searchErrorMessage(err, (substring))); \ } while(0) - BOOST_AUTO_TEST_SUITE(JuliaParser) BOOST_AUTO_TEST_CASE(smoke_test) @@ -197,6 +196,31 @@ BOOST_AUTO_TEST_CASE(lacking_types) CHECK_ERROR("{ function f(a:u256) -> b {} }", ParserError, "Expected token Colon got 'LBrace'"); } +BOOST_AUTO_TEST_CASE(invalid_types) +{ + /// testing invalid literal + /// NOTE: these will need to change when types are compared + CHECK_ERROR("{ let x:bool := 1:invalid }", TypeError, "User defined types (\"invalid\") are not supported yet."); + /// testing invalid variable declaration + CHECK_ERROR("{ let x:invalid := 1:bool }", TypeError, "User defined types (\"invalid\") are not supported yet."); + CHECK_ERROR("{ function f(a:invalid) {} }", TypeError, "User defined types (\"invalid\") are not supported yet."); +} + +BOOST_AUTO_TEST_CASE(builtin_types) +{ + BOOST_CHECK(successParse("{ let x:bool := true:bool }")); + BOOST_CHECK(successParse("{ let x:u8 := 1:u8 }")); + BOOST_CHECK(successParse("{ let x:s8 := 1:u8 }")); + BOOST_CHECK(successParse("{ let x:u32 := 1:u32 }")); + BOOST_CHECK(successParse("{ let x:s32 := 1:s32 }")); + BOOST_CHECK(successParse("{ let x:u64 := 1:u64 }")); + BOOST_CHECK(successParse("{ let x:s64 := 1:s64 }")); + BOOST_CHECK(successParse("{ let x:u128 := 1:u128 }")); + BOOST_CHECK(successParse("{ let x:s128 := 1:s128 }")); + BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }")); + BOOST_CHECK(successParse("{ let x:s256 := 1:s256 }")); +} + BOOST_AUTO_TEST_SUITE_END() }