mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Experimental
This commit is contained in:
parent
12f54b55a2
commit
1735a82199
@ -388,11 +388,14 @@ void ProtoConverter::visit(StructType const&)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x)
|
std::string ProtoConverter::arrayDimInfoAsString(
|
||||||
|
ArrayDimensionInfo const& _x,
|
||||||
|
unsigned _numDimensions
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return Whiskers(R"([<?isStatic><length></isStatic>])")
|
return Whiskers(R"([<?isStatic><length></isStatic>])")
|
||||||
("isStatic", _x.is_static())
|
("isStatic", _x.is_static())
|
||||||
("length", std::to_string(getStaticArrayLengthFromFuzz(_x.length())))
|
("length", std::to_string(getStaticArrayLengthFromFuzz(_x.length(), _numDimensions)))
|
||||||
.render();
|
.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +405,7 @@ void ProtoConverter::arrayDimensionsAsStringVector(
|
|||||||
{
|
{
|
||||||
solAssert(_x.info_size() > 0, "Proto ABIv2 Fuzzer: Array dimensions empty.");
|
solAssert(_x.info_size() > 0, "Proto ABIv2 Fuzzer: Array dimensions empty.");
|
||||||
for (auto const& dim: _x.info())
|
for (auto const& dim: _x.info())
|
||||||
_vecOfStr.push_back(arrayDimInfoAsString(dim));
|
_vecOfStr.push_back(arrayDimInfoAsString(dim, _x.info_size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtoConverter::VecOfBoolUnsigned ProtoConverter::arrayDimensionsAsPairVector(
|
ProtoConverter::VecOfBoolUnsigned ProtoConverter::arrayDimensionsAsPairVector(
|
||||||
@ -411,7 +414,7 @@ ProtoConverter::VecOfBoolUnsigned ProtoConverter::arrayDimensionsAsPairVector(
|
|||||||
{
|
{
|
||||||
VecOfBoolUnsigned arrayDimsPairVector = {};
|
VecOfBoolUnsigned arrayDimsPairVector = {};
|
||||||
for (auto const& dim: _x.info())
|
for (auto const& dim: _x.info())
|
||||||
arrayDimsPairVector.push_back(arrayDimInfoAsPair(dim));
|
arrayDimsPairVector.push_back(arrayDimInfoAsPair(dim, _x.info_size()));
|
||||||
solAssert(!arrayDimsPairVector.empty(), "Proto ABIv2 Fuzzer: Array dimensions empty.");
|
solAssert(!arrayDimsPairVector.empty(), "Proto ABIv2 Fuzzer: Array dimensions empty.");
|
||||||
return arrayDimsPairVector;
|
return arrayDimsPairVector;
|
||||||
}
|
}
|
||||||
@ -467,7 +470,8 @@ unsigned ProtoConverter::resizeDimension(
|
|||||||
unsigned _arrayLen,
|
unsigned _arrayLen,
|
||||||
std::string const& _var,
|
std::string const& _var,
|
||||||
std::string const& _param,
|
std::string const& _param,
|
||||||
std::string const& _type
|
std::string const& _type,
|
||||||
|
unsigned _numDimensions
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned length;
|
unsigned length;
|
||||||
@ -475,7 +479,7 @@ unsigned ProtoConverter::resizeDimension(
|
|||||||
length = _arrayLen;
|
length = _arrayLen;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
length = getDynArrayLengthFromFuzz(_arrayLen, getNextCounter());
|
length = getDynArrayLengthFromFuzz(_arrayLen, getNextCounter(), _numDimensions);
|
||||||
|
|
||||||
// If local var, new T(l);
|
// If local var, new T(l);
|
||||||
// Else, l;
|
// Else, l;
|
||||||
@ -501,7 +505,7 @@ unsigned ProtoConverter::resizeDimension(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add checks on array length pseudo randomly
|
// Add checks on array length pseudo randomly
|
||||||
if (addCheck(getNextCounter()))
|
if (addCheck(getNextCounter(), _numDimensions))
|
||||||
// if (c.length != l)
|
// if (c.length != l)
|
||||||
checkResizeOp(_param, length);
|
checkResizeOp(_param, length);
|
||||||
return length;
|
return length;
|
||||||
@ -512,7 +516,8 @@ void ProtoConverter::resizeHelper(
|
|||||||
std::vector<std::string> _arrStrVec,
|
std::vector<std::string> _arrStrVec,
|
||||||
VecOfBoolUnsigned _arrInfoVec,
|
VecOfBoolUnsigned _arrInfoVec,
|
||||||
std::string const& _varName,
|
std::string const& _varName,
|
||||||
std::string const& _paramName
|
std::string const& _paramName,
|
||||||
|
unsigned _numDimensions
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Initialize value expressions if we have arrived at leaf node,
|
// Initialize value expressions if we have arrived at leaf node,
|
||||||
@ -523,7 +528,7 @@ void ProtoConverter::resizeHelper(
|
|||||||
// To ensure we do not create a very large test case
|
// To ensure we do not create a very large test case
|
||||||
// especially for multidimensional dynamic arrays,
|
// especially for multidimensional dynamic arrays,
|
||||||
// we create a checked assignment pseudo randomly.
|
// we create a checked assignment pseudo randomly.
|
||||||
if (addCheck(getNextCounter()))
|
if (addCheck(getNextCounter(), _numDimensions))
|
||||||
{
|
{
|
||||||
// expression name is _var
|
// expression name is _var
|
||||||
// value is a value of base type
|
// value is a value of base type
|
||||||
@ -542,7 +547,7 @@ void ProtoConverter::resizeHelper(
|
|||||||
_arrStrVec.end(),
|
_arrStrVec.end(),
|
||||||
std::string("")
|
std::string("")
|
||||||
);
|
);
|
||||||
unsigned length = resizeDimension(dim.first, dim.second, _varName, _paramName, type);
|
unsigned length = resizeDimension(dim.first, dim.second, _varName, _paramName, type, _numDimensions);
|
||||||
// Recurse one level dimension down.
|
// Recurse one level dimension down.
|
||||||
_arrStrVec.pop_back();
|
_arrStrVec.pop_back();
|
||||||
_arrInfoVec.pop_back();
|
_arrInfoVec.pop_back();
|
||||||
@ -552,7 +557,8 @@ void ProtoConverter::resizeHelper(
|
|||||||
_arrStrVec,
|
_arrStrVec,
|
||||||
_arrInfoVec,
|
_arrInfoVec,
|
||||||
_varName + "[" + std::to_string(i) + "]",
|
_varName + "[" + std::to_string(i) + "]",
|
||||||
_paramName + "[" + std::to_string(i) + "]"
|
_paramName + "[" + std::to_string(i) + "]",
|
||||||
|
_numDimensions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,7 +575,7 @@ void ProtoConverter::resizeInitArray(
|
|||||||
VecOfBoolUnsigned arrInfoVec = arrayDimensionsAsPairVector(_x);
|
VecOfBoolUnsigned arrInfoVec = arrayDimensionsAsPairVector(_x);
|
||||||
std::vector<std::string> arrStrVec = {_baseType};
|
std::vector<std::string> arrStrVec = {_baseType};
|
||||||
arrayDimensionsAsStringVector(_x, arrStrVec);
|
arrayDimensionsAsStringVector(_x, arrStrVec);
|
||||||
resizeHelper(_x, arrStrVec, arrInfoVec, _varName, _paramName);
|
resizeHelper(_x, arrStrVec, arrInfoVec, _varName, _paramName, arrInfoVec.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns array type from it's base type (e.g., int8) and array dimensions info contained in
|
// Returns array type from it's base type (e.g., int8) and array dimensions info contained in
|
||||||
|
@ -174,7 +174,8 @@ private:
|
|||||||
unsigned _arrayLen,
|
unsigned _arrayLen,
|
||||||
std::string const& _var,
|
std::string const& _var,
|
||||||
std::string const& _param,
|
std::string const& _param,
|
||||||
std::string const& _type
|
std::string const& _type,
|
||||||
|
unsigned _numDimensions
|
||||||
);
|
);
|
||||||
|
|
||||||
void resizeHelper(
|
void resizeHelper(
|
||||||
@ -182,7 +183,8 @@ private:
|
|||||||
std::vector<std::string> _arrStrVec,
|
std::vector<std::string> _arrStrVec,
|
||||||
VecOfBoolUnsigned _arrInfoVec,
|
VecOfBoolUnsigned _arrInfoVec,
|
||||||
std::string const& _varName,
|
std::string const& _varName,
|
||||||
std::string const& _paramName
|
std::string const& _paramName,
|
||||||
|
unsigned _numDimensions
|
||||||
);
|
);
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
@ -293,7 +295,7 @@ private:
|
|||||||
bool _isHexLiteral
|
bool _isHexLiteral
|
||||||
);
|
);
|
||||||
static std::vector<std::pair<bool, unsigned>> arrayDimensionsAsPairVector(ArrayType const& _x);
|
static std::vector<std::pair<bool, unsigned>> arrayDimensionsAsPairVector(ArrayType const& _x);
|
||||||
static std::string arrayDimInfoAsString(ArrayDimensionInfo const& _x);
|
static std::string arrayDimInfoAsString(ArrayDimensionInfo const& _x, unsigned _numDimensions);
|
||||||
static void arrayDimensionsAsStringVector(
|
static void arrayDimensionsAsStringVector(
|
||||||
ArrayType const& _x,
|
ArrayType const& _x,
|
||||||
std::vector<std::string>&
|
std::vector<std::string>&
|
||||||
@ -371,25 +373,40 @@ private:
|
|||||||
|
|
||||||
/// Dynamically sized arrays can have a length of at least zero
|
/// Dynamically sized arrays can have a length of at least zero
|
||||||
/// and at most s_maxArrayLength.
|
/// and at most s_maxArrayLength.
|
||||||
static unsigned getDynArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter)
|
static unsigned getDynArrayLengthFromFuzz(
|
||||||
|
unsigned _fuzz,
|
||||||
|
unsigned _counter,
|
||||||
|
unsigned _numDimensions
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// Increment modulo value by one in order to meet upper bound
|
// Zero length dimension is more likely when the total
|
||||||
return (_fuzz + _counter) % (s_maxArrayLength + 1);
|
// number of dimensions is high.
|
||||||
|
return (
|
||||||
|
_fuzz % _numDimensions != 0 ?
|
||||||
|
0 :
|
||||||
|
// Increment modulo value by one in order to meet upper bound
|
||||||
|
(_fuzz + _counter) % (s_maxArrayLength + 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Statically sized arrays must have a length of at least one
|
/// Statically sized arrays must have a length of at least one
|
||||||
/// and at most s_maxArrayLength.
|
/// and at most s_maxArrayLength.
|
||||||
static unsigned getStaticArrayLengthFromFuzz(unsigned _fuzz)
|
static unsigned getStaticArrayLengthFromFuzz(unsigned _fuzz, unsigned _numDimensions)
|
||||||
{
|
{
|
||||||
return _fuzz % s_maxArrayLength + 1;
|
// Unit length dimension is more likely when the total
|
||||||
|
// number of dimensions is high.
|
||||||
|
return (_fuzz % _numDimensions != 0 ? 1 : _fuzz % s_maxArrayLength + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::pair<bool, unsigned> arrayDimInfoAsPair(ArrayDimensionInfo const& _x)
|
static std::pair<bool, unsigned> arrayDimInfoAsPair(
|
||||||
|
ArrayDimensionInfo const& _x,
|
||||||
|
unsigned _numDimensions
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
_x.is_static() ?
|
_x.is_static() ?
|
||||||
std::make_pair(true, getStaticArrayLengthFromFuzz(_x.length())) :
|
std::make_pair(true, getStaticArrayLengthFromFuzz(_x.length(), _numDimensions)) :
|
||||||
std::make_pair(false, getDynArrayLengthFromFuzz(_x.length(), 0))
|
std::make_pair(false, getDynArrayLengthFromFuzz(_x.length(), 0, _numDimensions))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,10 +430,12 @@ private:
|
|||||||
_counter,
|
_counter,
|
||||||
_isHexLiteral
|
_isHexLiteral
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static bool addCheck(unsigned _counter)
|
/// Checks are less likely for higher dimensional arrays
|
||||||
|
static bool addCheck(unsigned _counter, unsigned _numDimensions)
|
||||||
{
|
{
|
||||||
return _counter % s_arrayCheckFrequency == 0;
|
return _counter % _numDimensions == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains the test program
|
/// Contains the test program
|
||||||
@ -438,9 +457,6 @@ private:
|
|||||||
static unsigned constexpr s_maxArrayLength = 4;
|
static unsigned constexpr s_maxArrayLength = 4;
|
||||||
static unsigned constexpr s_maxArrayDimensions = 4;
|
static unsigned constexpr s_maxArrayDimensions = 4;
|
||||||
static unsigned constexpr s_maxDynArrayLength = 256;
|
static unsigned constexpr s_maxDynArrayLength = 256;
|
||||||
/// Add check only if counter returned by getNextCounter()
|
|
||||||
/// is divisible by s_arrayCheckFrequency
|
|
||||||
static unsigned constexpr s_arrayCheckFrequency = 11;
|
|
||||||
/// Prefixes for declared and parameterized variable names
|
/// Prefixes for declared and parameterized variable names
|
||||||
static auto constexpr s_varNamePrefix = "x_";
|
static auto constexpr s_varNamePrefix = "x_";
|
||||||
static auto constexpr s_paramNamePrefix = "c_";
|
static auto constexpr s_paramNamePrefix = "c_";
|
||||||
|
Loading…
Reference in New Issue
Block a user