Skip to content

Commit 967ee94

Browse files
authored
Merge pull request #7161 from ethereum/permit-zerolength-dyn-array-dimensions
Dynamically sized array dimensions can be zero sized
2 parents 7421d85 + e018d62 commit 967ee94

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

test/tools/ossfuzz/protoToAbiV2.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,10 @@ void ProtoConverter::visit(StructType const&)
328328

329329
std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x)
330330
{
331-
unsigned arrLength = getArrayLengthFromFuzz(_x.length());
332-
if (_x.is_static())
333-
return Whiskers(R"([<length>])")
334-
("length", std::to_string(arrLength))
331+
return Whiskers(R"([<?isStatic><length></isStatic>])")
332+
("isStatic", _x.is_static())
333+
("length", std::to_string(getStaticArrayLengthFromFuzz(_x.length())))
335334
.render();
336-
else
337-
return R"([])";
338335
}
339336

340337
void ProtoConverter::arrayDimensionsAsStringVector(
@@ -398,7 +395,7 @@ ProtoConverter::DataType ProtoConverter::getDataTypeByBaseType(ArrayType const&
398395
// Adds a resize operation for a given dimension of type `_type` and expression referenced
399396
// by `_var`. `_isStatic` is true for statically sized dimensions, false otherwise.
400397
// `_arrayLen` is equal to length of statically sized array dimension. For dynamically
401-
// sized dimension, we use `getArrayLengthFromFuzz()` and a monotonically increasing
398+
// sized dimension, we use `getDynArrayLengthFromFuzz()` and a monotonically increasing
402399
// counter to obtain actual length. Function returns dimension length.
403400
unsigned ProtoConverter::resizeDimension(
404401
bool _isStatic,
@@ -413,7 +410,7 @@ unsigned ProtoConverter::resizeDimension(
413410
length = _arrayLen;
414411
else
415412
{
416-
length = getArrayLengthFromFuzz(_arrayLen, getNextCounter());
413+
length = getDynArrayLengthFromFuzz(_arrayLen, getNextCounter());
417414

418415
// If local var, new T(l);
419416
// Else, l;

test/tools/ossfuzz/protoToAbiV2.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,28 @@ class ProtoConverter
334334
return toHex(maskUnsignedInt(_counter, _numMaskNibbles), HexPrefix::Add);
335335
}
336336

337-
static unsigned getArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter = 0)
337+
/// Dynamically sized arrays can have a length of at least zero
338+
/// and at most s_maxArrayLength.
339+
static unsigned getDynArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter)
338340
{
339-
return ((_fuzz + _counter) % s_maxArrayLength) + 1;
341+
// Increment modulo value by one in order to meet upper bound
342+
return (_fuzz + _counter) % (s_maxArrayLength + 1);
343+
}
344+
345+
/// Statically sized arrays must have a length of at least one
346+
/// and at most s_maxArrayLength.
347+
static unsigned getStaticArrayLengthFromFuzz(unsigned _fuzz)
348+
{
349+
return _fuzz % s_maxArrayLength + 1;
340350
}
341351

342352
static std::pair<bool, unsigned> arrayDimInfoAsPair(ArrayDimensionInfo const& _x)
343353
{
344-
return std::make_pair(_x.is_static(), getArrayLengthFromFuzz(_x.length()));
354+
return (
355+
_x.is_static() ?
356+
std::make_pair(true, getStaticArrayLengthFromFuzz(_x.length())) :
357+
std::make_pair(false, getDynArrayLengthFromFuzz(_x.length(), 0))
358+
);
345359
}
346360

347361
/// Contains the test program
@@ -360,7 +374,7 @@ class ProtoConverter
360374
unsigned m_varCounter;
361375
/// Monotonically increasing return value for error reporting
362376
unsigned m_returnValue;
363-
static unsigned constexpr s_maxArrayLength = 2;
377+
static unsigned constexpr s_maxArrayLength = 4;
364378
static unsigned constexpr s_maxArrayDimensions = 10;
365379
/// Prefixes for declared and parameterized variable names
366380
static auto constexpr s_varNamePrefix = "x_";

0 commit comments

Comments
 (0)