Skip to content

Commit 2da94a4

Browse files
committed
fuzz: add a fuzz target for Miniscript decoding from Script
1 parent f836999 commit 2da94a4

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ test_fuzz_fuzz_SOURCES = \
264264
test/fuzz/locale.cpp \
265265
test/fuzz/merkleblock.cpp \
266266
test/fuzz/message.cpp \
267+
test/fuzz/miniscript_decode.cpp \
267268
test/fuzz/minisketch.cpp \
268269
test/fuzz/muhash.cpp \
269270
test/fuzz/multiplication_overflow.cpp \

src/test/fuzz/miniscript_decode.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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

Comments
 (0)