From c0bfe72f6e1f63e05772eda959137b3d0bbbf6c3 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Thu, 20 Nov 2025 13:44:30 +0100 Subject: [PATCH] Change Parse descriptor argument to string_view Commit b3bf18f0bac0ffe18206ee20642e11264ba0c99d changed the function signature from Parse(const std::string& descriptor,...) to Parse(std::span descriptor,...). Calling this new version of Parse with a string literal will trigger a confusing "Invalid characters in payload" due to the trailing "\0". Switch to string_view and add a test. Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> --- src/script/descriptor.cpp | 9 +++++---- src/script/descriptor.h | 2 +- src/test/descriptor_tests.cpp | 9 +++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index a42943318d6..6363d176433 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -2743,12 +2743,13 @@ bool CheckChecksum(std::span& sp, bool require_checksum, std::string return true; } -std::vector> Parse(std::span descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum) +std::vector> Parse(std::string_view descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum) { - if (!CheckChecksum(descriptor, require_checksum, error)) return {}; + std::span sp{descriptor}; + if (!CheckChecksum(sp, require_checksum, error)) return {}; uint32_t key_exp_index = 0; - auto ret = ParseScript(key_exp_index, descriptor, ParseScriptContext::TOP, out, error); - if (descriptor.empty() && !ret.empty()) { + auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error); + if (sp.empty() && !ret.empty()) { std::vector> descs; descs.reserve(ret.size()); for (auto& r : ret) { diff --git a/src/script/descriptor.h b/src/script/descriptor.h index 9a018300ebe..a6744b92b71 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -175,7 +175,7 @@ struct Descriptor { * If a parse error occurs, or the checksum is missing/invalid, or anything * else is wrong, an empty vector is returned. */ -std::vector> Parse(std::span descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false); +std::vector> Parse(std::string_view descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false); /** Get the checksum for a `descriptor`. * diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp index 098007c4cf9..97f416dd7aa 100644 --- a/src/test/descriptor_tests.cpp +++ b/src/test/descriptor_tests.cpp @@ -1262,4 +1262,13 @@ BOOST_AUTO_TEST_CASE(descriptor_test) CheckUnparsable("tr(musig(tuus(oldepk(gg)ggggfgg)<,z(((((((((((((((((((((st)", "tr(musig(tuus(oldepk(gg)ggggfgg)<,z(((((((((((((((((((((st)","tr(): Too many ')' in musig() expression"); } +BOOST_AUTO_TEST_CASE(descriptor_literal_null_byte) +{ + // Trailing '\0' string literal should be ignored. + FlatSigningProvider keys; + std::string err; + auto descs = Parse("pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", keys, err, /*require_checksum=*/false); + BOOST_REQUIRE_MESSAGE(!descs.empty(), err); +} + BOOST_AUTO_TEST_SUITE_END()