/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_fuzzing_FuzzingTraits_h #define mozilla_fuzzing_FuzzingTraits_h #include "mozilla/Assertions.h" #include "mozilla/TypeTraits.h" #include namespace mozilla { namespace fuzzing { /** * RandomNumericLimit returns either the min or max limit of an arithmetic * data type. */ template T RandomNumericLimit() { static_assert(mozilla::IsArithmetic::value == true, "T must be an arithmetic type"); return random() % 2 == 0 ? std::numeric_limits::min() : std::numeric_limits::max(); } /** * RandomInteger generates negative and positive integers in 2**n increments. */ template T RandomInteger() { static_assert(mozilla::IsIntegral::value == true, "T must be an integral type"); double r = static_cast(random() % ((sizeof(T) * CHAR_BIT) + 1)); T x = static_cast(pow(2.0, r)) - 1; if (std::numeric_limits::is_signed && random() % 2 == 0) { return (x * -1) - 1; } return x; } /** * RandomIntegerRange returns a random integral within a [min, max] range. */ template T RandomIntegerRange(T min, T max) { static_assert(mozilla::IsIntegral::value == true, "T must be an integral type"); MOZ_ASSERT(min < max); return static_cast(random() % (max - min) + min); } /** * RandomFloatingPointRange returns a random floating-point number within a * [min, max] range. */ template T RandomFloatingPointRange(T min, T max) { static_assert(mozilla::IsFloatingPoint::value == true, "T must be a floating point type"); MOZ_ASSERT(min < max); T x = static_cast(random()) / static_cast(RAND_MAX); return min + x * (max - min); } /** * RandomFloatingPoint returns a random floating-point number in 2**n * increments. */ template T RandomFloatingPoint() { static_assert(mozilla::IsFloatingPoint::value == true, "T must be a floating point type"); int radix = RandomIntegerRange(std::numeric_limits::min_exponent, std::numeric_limits::max_exponent); T x = static_cast(pow(2.0, static_cast(radix))); return x * RandomFloatingPointRange(-1.0, 1.0); } class FuzzingTraits { public: static unsigned int Random(unsigned int aMax); static bool Sometimes(unsigned int aProbability); /** * Frequency() defines how many mutations of a kind shall be applied to a * target buffer by using a user definable factor. The higher the factor, * the less mutations are being made. */ static size_t Frequency(const size_t aSize, const uint64_t aFactor); }; } // namespace fuzzing } // namespace mozilla #endif