aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/fuzz/descriptor_parse.cpp8
-rw-r--r--src/test/fuzz/util/descriptor.cpp14
-rw-r--r--src/test/fuzz/util/descriptor.h10
3 files changed, 32 insertions, 0 deletions
diff --git a/src/test/fuzz/descriptor_parse.cpp b/src/test/fuzz/descriptor_parse.cpp
index 5474b38204..6ea315d4e2 100644
--- a/src/test/fuzz/descriptor_parse.cpp
+++ b/src/test/fuzz/descriptor_parse.cpp
@@ -67,6 +67,11 @@ void initialize_mocked_descriptor_parse()
FUZZ_TARGET(mocked_descriptor_parse, .init = initialize_mocked_descriptor_parse)
{
+ // Key derivation is expensive. Deriving deep derivation paths take a lot of compute and we'd
+ // rather spend time elsewhere in this target, like on the actual descriptor syntax. So rule
+ // out strings which could correspond to a descriptor containing a too large derivation path.
+ if (HasDeepDerivPath(buffer)) return;
+
const std::string mocked_descriptor{buffer.begin(), buffer.end()};
if (const auto descriptor = MOCKED_DESC_CONVERTER.GetDescriptor(mocked_descriptor)) {
FlatSigningProvider signing_provider;
@@ -78,6 +83,9 @@ FUZZ_TARGET(mocked_descriptor_parse, .init = initialize_mocked_descriptor_parse)
FUZZ_TARGET(descriptor_parse, .init = initialize_descriptor_parse)
{
+ // See comment above for rationale.
+ if (HasDeepDerivPath(buffer)) return;
+
const std::string descriptor(buffer.begin(), buffer.end());
FlatSigningProvider signing_provider;
std::string error;
diff --git a/src/test/fuzz/util/descriptor.cpp b/src/test/fuzz/util/descriptor.cpp
index 5bfd2721ce..df78bdf314 100644
--- a/src/test/fuzz/util/descriptor.cpp
+++ b/src/test/fuzz/util/descriptor.cpp
@@ -70,3 +70,17 @@ std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_
return desc;
}
+
+bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth)
+{
+ auto depth{0};
+ for (const auto& ch: buff) {
+ if (ch == ',') {
+ // A comma is always present between two key expressions, so we use that as a delimiter.
+ depth = 0;
+ } else if (ch == '/') {
+ if (++depth > max_depth) return true;
+ }
+ }
+ return false;
+}
diff --git a/src/test/fuzz/util/descriptor.h b/src/test/fuzz/util/descriptor.h
index 6289b91b07..cd41dbafa3 100644
--- a/src/test/fuzz/util/descriptor.h
+++ b/src/test/fuzz/util/descriptor.h
@@ -8,6 +8,7 @@
#include <key_io.h>
#include <util/strencodings.h>
#include <script/descriptor.h>
+#include <test/fuzz/fuzz.h>
#include <functional>
@@ -45,4 +46,13 @@ public:
std::optional<std::string> GetDescriptor(std::string_view mocked_desc) const;
};
+//! Default maximum number of derivation indexes in a single derivation path when limiting its depth.
+constexpr int MAX_DEPTH{2};
+
+/**
+ * Whether the buffer, if it represents a valid descriptor, contains a derivation path deeper than
+ * a given maximum depth. Note this may also be hit for deriv paths in origins.
+ */
+bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth = MAX_DEPTH);
+
#endif // BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H