2020-02-24 17:35:10 -03:00
|
|
|
// Copyright (c) 2009-2019 The Bitcoin Core developers
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
#ifndef BITCOIN_TEST_FUZZ_UTIL_H
|
|
|
|
#define BITCOIN_TEST_FUZZ_UTIL_H
|
|
|
|
|
2020-03-14 23:24:38 -03:00
|
|
|
#include <amount.h>
|
2020-02-24 17:35:10 -03:00
|
|
|
#include <attributes.h>
|
|
|
|
#include <optional.h>
|
2020-02-19 13:42:42 -03:00
|
|
|
#include <script/script.h>
|
2020-02-24 17:35:10 -03:00
|
|
|
#include <serialize.h>
|
|
|
|
#include <streams.h>
|
|
|
|
#include <test/fuzz/FuzzedDataProvider.h>
|
2020-02-19 13:42:42 -03:00
|
|
|
#include <test/fuzz/fuzz.h>
|
2020-02-24 17:35:10 -03:00
|
|
|
#include <version.h>
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, size_t max_length = 4096) noexcept
|
|
|
|
{
|
|
|
|
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(max_length);
|
|
|
|
return {s.begin(), s.end()};
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
NODISCARD inline Optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, size_t max_length = 4096) noexcept
|
|
|
|
{
|
2020-02-26 17:04:23 -03:00
|
|
|
const std::vector<uint8_t> buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
|
2020-02-24 17:35:10 -03:00
|
|
|
CDataStream ds{buffer, SER_NETWORK, INIT_PROTO_VERSION};
|
|
|
|
T obj;
|
|
|
|
try {
|
|
|
|
ds >> obj;
|
|
|
|
} catch (const std::ios_base::failure&) {
|
|
|
|
return nullopt;
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2020-02-19 13:42:42 -03:00
|
|
|
NODISCARD inline opcodetype ConsumeOpcodeType(FuzzedDataProvider& fuzzed_data_provider) noexcept
|
|
|
|
{
|
|
|
|
return static_cast<opcodetype>(fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE));
|
|
|
|
}
|
|
|
|
|
2020-03-14 23:24:38 -03:00
|
|
|
NODISCARD inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept
|
|
|
|
{
|
|
|
|
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
|
|
|
|
}
|
|
|
|
|
2020-02-19 13:42:42 -03:00
|
|
|
NODISCARD inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
|
|
|
|
{
|
|
|
|
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
|
|
|
return {b.begin(), b.end()};
|
|
|
|
}
|
|
|
|
|
|
|
|
NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_provider) noexcept
|
|
|
|
{
|
|
|
|
return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
|
|
|
|
}
|
|
|
|
|
2020-03-14 23:24:38 -03:00
|
|
|
template <typename T>
|
|
|
|
bool MultiplicationOverflow(T i, T j)
|
|
|
|
{
|
|
|
|
static_assert(std::is_integral<T>::value, "Integral required.");
|
|
|
|
if (std::numeric_limits<T>::is_signed) {
|
|
|
|
if (i > 0) {
|
|
|
|
if (j > 0) {
|
|
|
|
return i > (std::numeric_limits<T>::max() / j);
|
|
|
|
} else {
|
|
|
|
return j < (std::numeric_limits<T>::min() / i);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (j > 0) {
|
|
|
|
return i < (std::numeric_limits<T>::min() / j);
|
|
|
|
} else {
|
|
|
|
return i != 0 && (j < (std::numeric_limits<T>::max() / i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return j != 0 && i > std::numeric_limits<T>::max() / j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-24 17:35:10 -03:00
|
|
|
#endif // BITCOIN_TEST_FUZZ_UTIL_H
|