From 3a6f28589ecebbf3482e6d78f498de7f6ea76523 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Mon, 29 Jul 2019 16:38:24 +0200 Subject: [PATCH] Pseudo randomly add checks --- test/tools/ossfuzz/protoToAbiV2.cpp | 59 +++++++++++++++++------------ test/tools/ossfuzz/protoToAbiV2.h | 27 ++++++++++--- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/test/tools/ossfuzz/protoToAbiV2.cpp b/test/tools/ossfuzz/protoToAbiV2.cpp index fa5785287..f961c45ac 100644 --- a/test/tools/ossfuzz/protoToAbiV2.cpp +++ b/test/tools/ossfuzz/protoToAbiV2.cpp @@ -295,20 +295,20 @@ void ProtoConverter::visit(ValueType const& _x) { switch (_x.value_type_oneof_case()) { - case ValueType::kInty: - visit(_x.inty()); - break; - case ValueType::kByty: - visit(_x.byty()); - break; - case ValueType::kAdty: - visit(_x.adty()); - break; - case ValueType::kBoolty: - visit(_x.boolty()); - break; - case ValueType::VALUE_TYPE_ONEOF_NOT_SET: - break; + case ValueType::kInty: + visit(_x.inty()); + break; + case ValueType::kByty: + visit(_x.byty()); + break; + case ValueType::kAdty: + visit(_x.adty()); + break; + case ValueType::kBoolty: + visit(_x.boolty()); + break; + case ValueType::VALUE_TYPE_ONEOF_NOT_SET: + break; } } @@ -328,7 +328,7 @@ void ProtoConverter::visit(StructType const&) std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x) { - unsigned arrLength = getArrayLengthFromFuzz(_x.length()); + unsigned arrLength = getStaticArrayLengthFromFuzz(_x.length()); if (_x.is_static()) return Whiskers(R"([])") ("length", std::to_string(arrLength)) @@ -398,7 +398,7 @@ ProtoConverter::DataType ProtoConverter::getDataTypeByBaseType(ArrayType const& // Adds a resize operation for a given dimension of type `_type` and expression referenced // by `_var`. `_isStatic` is true for statically sized dimensions, false otherwise. // `_arrayLen` is equal to length of statically sized array dimension. For dynamically -// sized dimension, we use `getArrayLengthFromFuzz()` and a monotonically increasing +// sized dimension, we use `getDynArrayLengthFromFuzz()` and a monotonically increasing // counter to obtain actual length. Function returns dimension length. unsigned ProtoConverter::resizeDimension( bool _isStatic, @@ -413,7 +413,7 @@ unsigned ProtoConverter::resizeDimension( length = _arrayLen; else { - length = getArrayLengthFromFuzz(_arrayLen, getNextCounter()); + length = getDynArrayLengthFromFuzz(_arrayLen, getNextCounter()); // If local var, new T(l); // Else, l; @@ -438,8 +438,10 @@ unsigned ProtoConverter::resizeDimension( addVarDef(lhs, rhs); } - // if (c.length != l) - checkResizeOp(_param, length); + // Add checks on array length pseudo randomly + if (addCheck(getNextCounter())) + // if (c.length != l) + checkResizeOp(_param, length); return length; } @@ -455,12 +457,19 @@ void ProtoConverter::resizeHelper( // (depth-first) recurse otherwise. if (_arrInfoVec.empty()) { - // expression name is _var - // value is a value of base type - std::string value = getValueByBaseType(_x); - // add assignment and check - DataType dataType = getDataTypeByBaseType(_x); - addCheckedVarDef(dataType, _varName, _paramName, value); + // We are at the leaf node now. + // To ensure we do not create a very large test case + // especially for multidimensional dynamic arrays, + // we create a checked assignment pseudo randomly. + if (addCheck(getNextCounter())) + { + // expression name is _var + // value is a value of base type + std::string value = getValueByBaseType(_x); + // add assignment and check + DataType dataType = getDataTypeByBaseType(_x); + addCheckedVarDef(dataType, _varName, _paramName, value); + } } else { diff --git a/test/tools/ossfuzz/protoToAbiV2.h b/test/tools/ossfuzz/protoToAbiV2.h index edef94c3e..59ecbee9f 100644 --- a/test/tools/ossfuzz/protoToAbiV2.h +++ b/test/tools/ossfuzz/protoToAbiV2.h @@ -334,14 +334,27 @@ private: return toHex(maskUnsignedInt(_counter, _numMaskNibbles), HexPrefix::Add); } - static unsigned getArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter = 0) + static unsigned getDynArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter) { - return ((_fuzz + _counter) % s_maxArrayLength) + 1; + return ((_fuzz + _counter) % s_maxDynamicArrayLength) + 1; + } + + static unsigned getStaticArrayLengthFromFuzz(unsigned _fuzz) + { + return (_fuzz % s_maxStaticArrayLength) + 1; } static std::pair arrayDimInfoAsPair(ArrayDimensionInfo const& _x) { - return std::make_pair(_x.is_static(), getArrayLengthFromFuzz(_x.length())); + return std::make_pair( + _x.is_static(), + getStaticArrayLengthFromFuzz(_x.length()) + ); + } + + static bool addCheck(unsigned _counter) + { + return (_counter % s_arrayCheckFrequency == 0); } /// Contains the test program @@ -360,8 +373,12 @@ private: unsigned m_varCounter; /// Monotonically increasing return value for error reporting unsigned m_returnValue; - static unsigned constexpr s_maxArrayLength = 2; - static unsigned constexpr s_maxArrayDimensions = 10; + static unsigned constexpr s_maxStaticArrayLength = 7; + static unsigned constexpr s_maxDynamicArrayLength = 5; + static unsigned constexpr s_maxArrayDimensions = 21; + /// 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 static auto constexpr s_varNamePrefix = "x_"; static auto constexpr s_paramNamePrefix = "c_";