Skip to content

Commit 38c8474

Browse files
committed
Merge bitcoin#33914: Change Parse descriptor argument to string_view
c0bfe72 Change Parse descriptor argument to string_view (Sjors Provoost) Pull request description: While investigating a silent merge conflict in bitcoin#33135 I noticed that bitcoin#32983 changed the descriptor `Parse` function signature from `const std::string& descriptor` to `std::span<const char> descriptor`. Calling that new version of `Parse` with a string literal will trigger a confusing "Invalid characters in payload" due to the trailing "\0". It can be worked around by having (the test) wrap string literals in `std::string()`, but that's easy to forget. Using `string_view` is easier and more compact than (as a previous version of this PR did) checking for trailing `\0`. Also add a test. ACKs for top commit: maflcko: review ACK c0bfe72 🍨 enirox001: tACK c0bfe72 stickies-v: ACK c0bfe72 rkrux: crACK c0bfe72 Tree-SHA512: 6b20307f834dae66826c8763f6c2ba0071f4e369375184cb5ff8543b85220fcaf33a47ddb065e418d1af3ed9a3fac401a7854f8924f52aab2b000b1f65328f2c
2 parents 4b25b27 + c0bfe72 commit 38c8474

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

src/script/descriptor.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,12 +2743,13 @@ bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string
27432743
return true;
27442744
}
27452745

2746-
std::vector<std::unique_ptr<Descriptor>> Parse(std::span<const char> descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
2746+
std::vector<std::unique_ptr<Descriptor>> Parse(std::string_view descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
27472747
{
2748-
if (!CheckChecksum(descriptor, require_checksum, error)) return {};
2748+
std::span<const char> sp{descriptor};
2749+
if (!CheckChecksum(sp, require_checksum, error)) return {};
27492750
uint32_t key_exp_index = 0;
2750-
auto ret = ParseScript(key_exp_index, descriptor, ParseScriptContext::TOP, out, error);
2751-
if (descriptor.empty() && !ret.empty()) {
2751+
auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
2752+
if (sp.empty() && !ret.empty()) {
27522753
std::vector<std::unique_ptr<Descriptor>> descs;
27532754
descs.reserve(ret.size());
27542755
for (auto& r : ret) {

src/script/descriptor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ struct Descriptor {
175175
* If a parse error occurs, or the checksum is missing/invalid, or anything
176176
* else is wrong, an empty vector is returned.
177177
*/
178-
std::vector<std::unique_ptr<Descriptor>> Parse(std::span<const char> descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false);
178+
std::vector<std::unique_ptr<Descriptor>> Parse(std::string_view descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum = false);
179179

180180
/** Get the checksum for a `descriptor`.
181181
*

src/test/descriptor_tests.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,4 +1262,13 @@ BOOST_AUTO_TEST_CASE(descriptor_test)
12621262
CheckUnparsable("tr(musig(tuus(oldepk(gg)ggggfgg)<,z(((((((((((((((((((((st)", "tr(musig(tuus(oldepk(gg)ggggfgg)<,z(((((((((((((((((((((st)","tr(): Too many ')' in musig() expression");
12631263
}
12641264

1265+
BOOST_AUTO_TEST_CASE(descriptor_literal_null_byte)
1266+
{
1267+
// Trailing '\0' string literal should be ignored.
1268+
FlatSigningProvider keys;
1269+
std::string err;
1270+
auto descs = Parse("pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)", keys, err, /*require_checksum=*/false);
1271+
BOOST_REQUIRE_MESSAGE(!descs.empty(), err);
1272+
}
1273+
12651274
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)