@@ -914,27 +914,42 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
914
914
915
915
} // namespace
916
916
917
- std::unique_ptr<Descriptor> Parse (const std::string& descriptor, FlatSigningProvider& out, bool require_checksum)
917
+ /* * Check a descriptor checksum, and update desc to be the checksum-less part. */
918
+ bool CheckChecksum (Span<const char >& sp, bool require_checksum, std::string* out_checksum = nullptr )
918
919
{
919
- Span<const char > sp (descriptor.data (), descriptor.size ());
920
-
921
- // Checksum checks
922
920
auto check_split = Split (sp, ' #' );
923
- if (check_split.size () > 2 ) return nullptr ; // Multiple '#' symbols
924
- if (check_split.size () == 1 && require_checksum) return nullptr ; // Missing checksum
921
+ if (check_split.size () > 2 ) return false ; // Multiple '#' symbols
922
+ if (check_split.size () == 1 && require_checksum) return false ; // Missing checksum
923
+ if (check_split.size () == 2 ) {
924
+ if (check_split[1 ].size () != 8 ) return false ; // Unexpected length for checksum
925
+ }
926
+ auto checksum = DescriptorChecksum (check_split[0 ]);
927
+ if (checksum.empty ()) return false ; // Invalid characters in payload
925
928
if (check_split.size () == 2 ) {
926
- if (check_split[1 ].size () != 8 ) return nullptr ; // Unexpected length for checksum
927
- auto checksum = DescriptorChecksum (check_split[0 ]);
928
- if (checksum.empty ()) return nullptr ; // Invalid characters in payload
929
- if (!std::equal (checksum.begin (), checksum.end (), check_split[1 ].begin ())) return nullptr ; // Checksum mismatch
929
+ if (!std::equal (checksum.begin (), checksum.end (), check_split[1 ].begin ())) return false ; // Checksum mismatch
930
930
}
931
+ if (out_checksum) *out_checksum = std::move (checksum);
931
932
sp = check_split[0 ];
933
+ return true ;
934
+ }
932
935
936
+ std::unique_ptr<Descriptor> Parse (const std::string& descriptor, FlatSigningProvider& out, bool require_checksum)
937
+ {
938
+ Span<const char > sp (descriptor.data (), descriptor.size ());
939
+ if (!CheckChecksum (sp, require_checksum)) return nullptr ;
933
940
auto ret = ParseScript (sp, ParseScriptContext::TOP, out);
934
941
if (sp.size () == 0 && ret) return std::unique_ptr<Descriptor>(std::move (ret));
935
942
return nullptr ;
936
943
}
937
944
945
+ std::string GetDescriptorChecksum (const std::string& descriptor)
946
+ {
947
+ std::string ret;
948
+ Span<const char > sp (descriptor.data (), descriptor.size ());
949
+ if (!CheckChecksum (sp, false , &ret)) return " " ;
950
+ return ret;
951
+ }
952
+
938
953
std::unique_ptr<Descriptor> InferDescriptor (const CScript& script, const SigningProvider& provider)
939
954
{
940
955
return InferScript (script, ParseScriptContext::TOP, provider);
0 commit comments