diff options
-rw-r--r-- | src/Makefile.test.include | 2 | ||||
-rw-r--r-- | src/test/fuzz/miniscript.cpp | 70 | ||||
-rw-r--r-- | src/test/fuzz/miniscript_decode.cpp | 71 |
3 files changed, 71 insertions, 72 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 02a3f9ae7d..781313e42d 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -269,7 +269,7 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/locale.cpp \ test/fuzz/merkleblock.cpp \ test/fuzz/message.cpp \ - test/fuzz/miniscript_decode.cpp \ + test/fuzz/miniscript.cpp \ test/fuzz/minisketch.cpp \ test/fuzz/muhash.cpp \ test/fuzz/multiplication_overflow.cpp \ diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp new file mode 100644 index 0000000000..0788f37e55 --- /dev/null +++ b/src/test/fuzz/miniscript.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <core_io.h> +#include <hash.h> +#include <key.h> +#include <script/miniscript.h> +#include <script/script.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <util/strencodings.h> + +namespace { + +//! Context that implements naive conversion from/to script only, for roundtrip testing. +struct ScriptParserContext { + //! For Script roundtrip we never need the key from a key hash. + struct Key { + bool is_hash; + std::vector<unsigned char> data; + }; + + const std::vector<unsigned char>& ToPKBytes(const Key& key) const + { + assert(!key.is_hash); + return key.data; + } + + const std::vector<unsigned char> ToPKHBytes(const Key& key) const + { + if (key.is_hash) return key.data; + const auto h = Hash160(key.data); + return {h.begin(), h.end()}; + } + + template<typename I> + std::optional<Key> FromPKBytes(I first, I last) const + { + Key key; + key.data.assign(first, last); + key.is_hash = false; + return key; + } + + template<typename I> + std::optional<Key> FromPKHBytes(I first, I last) const + { + Key key; + key.data.assign(first, last); + key.is_hash = true; + return key; + } +} SCRIPT_PARSER_CONTEXT; + +} + +/* Fuzz tests that test parsing from a script, and roundtripping via script. */ +FUZZ_TARGET(miniscript_script) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const std::optional<CScript> script = ConsumeDeserializable<CScript>(fuzzed_data_provider); + if (!script) return; + + const auto ms = miniscript::FromScript(*script, SCRIPT_PARSER_CONTEXT); + if (!ms) return; + + assert(ms->ToScript(SCRIPT_PARSER_CONTEXT) == *script); +} diff --git a/src/test/fuzz/miniscript_decode.cpp b/src/test/fuzz/miniscript_decode.cpp deleted file mode 100644 index 1e2378cb17..0000000000 --- a/src/test/fuzz/miniscript_decode.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <core_io.h> -#include <hash.h> -#include <key.h> -#include <script/miniscript.h> -#include <script/script.h> -#include <span.h> -#include <test/fuzz/FuzzedDataProvider.h> -#include <test/fuzz/fuzz.h> -#include <test/fuzz/util.h> -#include <util/strencodings.h> - -#include <optional> - -using miniscript::operator""_mst; - - -struct Converter { - typedef CPubKey Key; - - std::optional<std::string> ToString(const Key& key) const { - return HexStr(key); - } - const std::vector<unsigned char> ToPKBytes(const Key& key) const { - return {key.begin(), key.end()}; - } - const std::vector<unsigned char> ToPKHBytes(const Key& key) const { - const auto h = Hash160(key); - return {h.begin(), h.end()}; - } - - template<typename I> - std::optional<Key> FromString(I first, I last) const { - const auto bytes = ParseHex(std::string(first, last)); - Key key{bytes.begin(), bytes.end()}; - if (key.IsValid()) return key; - return {}; - } - template<typename I> - std::optional<Key> FromPKBytes(I first, I last) const { - Key key{first, last}; - if (key.IsValid()) return key; - return {}; - } - template<typename I> - std::optional<Key> FromPKHBytes(I first, I last) const { - return {}; - } -}; - -const Converter CONVERTER; - -FUZZ_TARGET(miniscript_decode) -{ - FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); - const std::optional<CScript> script = ConsumeDeserializable<CScript>(fuzzed_data_provider); - if (!script) return; - - const auto ms = miniscript::FromScript(*script, CONVERTER); - if (!ms) return; - - // We can roundtrip it to its string representation. - std::string ms_str = *ms->ToString(CONVERTER); - assert(*miniscript::FromString(ms_str, CONVERTER) == *ms); - // The Script representation must roundtrip since we parsed it this way the first time. - const CScript ms_script = ms->ToScript(CONVERTER); - assert(ms_script == *script); -} |