Disallow leading zeroes in sized-types

Also avoid using boost::lexical_cast for parseSize.
This commit is contained in:
Alex Beregszaszi 2020-12-11 17:00:28 +00:00
parent 4bffd040e2
commit aa042ccb87
3 changed files with 27 additions and 18 deletions

View File

@ -26,6 +26,7 @@ Bugfixes:
* SMTChecker: Fix internal error when trying to generate counterexamples with old z3.
* SMTChecker: Fix segmentation fault that could occur on certain SMT-enabled sources when no SMT solver was available.
* Type Checker: ``super`` is not available in libraries.
* Type Checker: Disallow leading zeroes in sized-types (e.g. ``bytes000032``), but allow them to be treated as identifiers.
* Yul Optimizer: Fix a bug in NameSimplifier where a new name created by NameSimplifier could also be created by NameDispenser.
* Yul Optimizer: Removed NameSimplifier from optimization steps available to users.

View File

@ -41,7 +41,6 @@
// along with solidity. If not, see <http://www.gnu.org/licenses/>.
#include <liblangutil/Token.h>
#include <boost/range/iterator_range.hpp>
#include <map>
using namespace std;
@ -126,22 +125,6 @@ int precedence(Token tok)
}
#undef T
namespace
{
int parseSize(string::const_iterator _begin, string::const_iterator _end)
{
try
{
int m = boost::lexical_cast<int>(boost::make_iterator_range(_begin, _end));
return m;
}
catch(boost::bad_lexical_cast const&)
{
return -1;
}
}
}
static Token keywordByName(string const& _name)
{
// The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored
@ -162,6 +145,32 @@ bool isYulKeyword(string const& _literal)
tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _literal)
{
// Used for `bytesM`, `uintM`, `intM`, `fixedMxN`, `ufixedMxN`.
// M/N must be shortest representation. M can never be 0. N can be zero.
auto parseSize = [](string::const_iterator _begin, string::const_iterator _end) -> int
{
// No number.
if (distance(_begin, _end) == 0)
return -1;
// Disallow leading zero.
if (distance(_begin, _end) > 1 && *_begin == '0')
return -1;
int ret = 0;
for (auto it = _begin; it != _end; it++)
{
if (*it < '0' || *it > '9')
return -1;
// Overflow check. The largest acceptable value is 256 in the callers.
if (ret >= 256)
return -1;
ret *= 10;
ret += *it - '0';
}
return ret;
};
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
if (positionM != _literal.end())
{

View File

@ -40,4 +40,3 @@ contract C {
uint uint300 = 0;
}
// ----
// ParserError 2314: (22-29): Expected identifier but got 'bytes1'