From d5b65fbf5b3ba9f0b4d55da656db012dc264e176 Mon Sep 17 00:00:00 2001 From: hydai Date: Wed, 17 Apr 2019 21:05:44 +0800 Subject: [PATCH] [Yul] Output an error of a switch case which contains string literals longer than 32 chars --- libyul/AsmAnalysis.cpp | 8 +++++++- test/libyul/Parser.cpp | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 8cd11ba62..f8135dd38 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -442,15 +442,21 @@ bool AsmAnalyzer::operator()(Switch const& _switch) if (_case.value) { int const initialStackHeight = m_stackHeight; + bool isCaseValueValid = true; // We cannot use "expectExpression" here because *_case.value is not a // Statement and would be converted to a Statement otherwise. if (!(*this)(*_case.value)) + { + isCaseValueValid = false; success = false; + } expectDeposit(1, initialStackHeight, _case.value->location); m_stackHeight--; + // If the case value is not valid, we should not insert it into cases. + yulAssert(isCaseValueValid || m_errorReporter.hasErrors(), "Invalid case value."); /// Note: the parser ensures there is only one default case - if (!cases.insert(valueOfLiteral(*_case.value)).second) + if (isCaseValueValid && !cases.insert(valueOfLiteral(*_case.value)).second) { m_errorReporter.declarationError( _case.location, diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index da07544b9..6b09cc178 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -390,6 +390,12 @@ BOOST_AUTO_TEST_CASE(switch_duplicate_case_different_literal) BOOST_CHECK(successParse("{ switch 1:u256 case \"1\":u256 {} case \"2\":u256 {} }")); } +BOOST_AUTO_TEST_CASE(switch_case_string_literal_too_long) +{ + BOOST_CHECK(successParse("{let x:u256 switch x case \"01234567890123456789012345678901\":u256 {}}")); + CHECK_ERROR("{let x:u256 switch x case \"012345678901234567890123456789012\":u256 {}}", TypeError, "String literal too long (33 > 32)"); +} + BOOST_AUTO_TEST_CASE(function_shadowing_outside_vars) { CHECK_ERROR("{ let x:u256 function f() -> x:u256 {} }", DeclarationError, "already taken in this scope");