|
| 1 | +// Copyright (c) 2022 The Bitcoin Core developers |
| 2 | +// Distributed under the MIT software license, see the accompanying |
| 3 | +// file COPYING or http://www.opensource.org/licenses/mit-license.php. |
| 4 | + |
| 5 | +#include <core_io.h> |
| 6 | +#include <hash.h> |
| 7 | +#include <key.h> |
| 8 | +#include <script/miniscript.h> |
| 9 | +#include <script/script.h> |
| 10 | +#include <span.h> |
| 11 | +#include <test/fuzz/FuzzedDataProvider.h> |
| 12 | +#include <test/fuzz/fuzz.h> |
| 13 | +#include <test/fuzz/util.h> |
| 14 | +#include <util/strencodings.h> |
| 15 | + |
| 16 | +#include <optional> |
| 17 | + |
| 18 | +using miniscript::operator""_mst; |
| 19 | + |
| 20 | + |
| 21 | +struct Converter { |
| 22 | + typedef CPubKey Key; |
| 23 | + |
| 24 | + bool ToString(const Key& key, std::string& ret) const { |
| 25 | + ret = HexStr(key); |
| 26 | + return true; |
| 27 | + } |
| 28 | + const std::vector<unsigned char> ToPKBytes(const Key& key) const { |
| 29 | + return {key.begin(), key.end()}; |
| 30 | + } |
| 31 | + const std::vector<unsigned char> ToPKHBytes(const Key& key) const { |
| 32 | + const auto h = Hash160(key); |
| 33 | + return {h.begin(), h.end()}; |
| 34 | + } |
| 35 | + |
| 36 | + template<typename I> |
| 37 | + bool FromString(I first, I last, Key& key) const { |
| 38 | + const auto bytes = ParseHex(std::string(first, last)); |
| 39 | + key.Set(bytes.begin(), bytes.end()); |
| 40 | + return key.IsValid(); |
| 41 | + } |
| 42 | + template<typename I> |
| 43 | + bool FromPKBytes(I first, I last, CPubKey& key) const { |
| 44 | + key.Set(first, last); |
| 45 | + return key.IsValid(); |
| 46 | + } |
| 47 | + template<typename I> |
| 48 | + bool FromPKHBytes(I first, I last, CPubKey& key) const { |
| 49 | + assert(last - first == 20); |
| 50 | + return false; |
| 51 | + } |
| 52 | +}; |
| 53 | + |
| 54 | +const Converter CONVERTER; |
| 55 | + |
| 56 | +FUZZ_TARGET(miniscript_decode) |
| 57 | +{ |
| 58 | + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
| 59 | + const std::optional<CScript> script = ConsumeDeserializable<CScript>(fuzzed_data_provider); |
| 60 | + if (!script) return; |
| 61 | + |
| 62 | + const auto ms = miniscript::FromScript(*script, CONVERTER); |
| 63 | + if (!ms) return; |
| 64 | + |
| 65 | + // We can roundtrip it to its string representation. |
| 66 | + std::string ms_str; |
| 67 | + assert(ms->ToString(CONVERTER, ms_str)); |
| 68 | + assert(*miniscript::FromString(ms_str, CONVERTER) == *ms); |
| 69 | + // The Script representation must roundtrip since we parsed it this way the first time. |
| 70 | + const CScript ms_script = ms->ToScript(CONVERTER); |
| 71 | + assert(ms_script == *script); |
| 72 | +} |
0 commit comments