diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2019-05-08 14:01:35 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2019-08-06 17:11:12 -0700 |
commit | 104b3a5069c937383e6f88f2f3fb804ef61b208f (patch) | |
tree | b4a8ba700758401d545b9a9e75211cd6685f83a1 /src/script | |
parent | e5fdda68c6d2313edb74443f0d1e6d2ce2d97f5e (diff) |
Factor out checksum checking from descriptor parsing
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/descriptor.cpp | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 50119ba184..95b949e9c2 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -910,22 +910,29 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo } // namespace -std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, bool require_checksum) +/** Check a descriptor checksum, and update desc to be the checksum-less part. */ +bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string* out_checksum = nullptr) { - Span<const char> sp(descriptor.data(), descriptor.size()); - - // Checksum checks auto check_split = Split(sp, '#'); - if (check_split.size() > 2) return nullptr; // Multiple '#' symbols - if (check_split.size() == 1 && require_checksum) return nullptr; // Missing checksum + if (check_split.size() > 2) return false; // Multiple '#' symbols + if (check_split.size() == 1 && require_checksum) return false; // Missing checksum + if (check_split.size() == 2) { + if (check_split[1].size() != 8) return false; // Unexpected length for checksum + } + auto checksum = DescriptorChecksum(check_split[0]); + if (checksum.empty()) return false; // Invalid characters in payload if (check_split.size() == 2) { - if (check_split[1].size() != 8) return nullptr; // Unexpected length for checksum - auto checksum = DescriptorChecksum(check_split[0]); - if (checksum.empty()) return nullptr; // Invalid characters in payload - if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) return nullptr; // Checksum mismatch + if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) return false; // Checksum mismatch } + if (out_checksum) *out_checksum = std::move(checksum); sp = check_split[0]; + return true; +} +std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, bool require_checksum) +{ + Span<const char> sp(descriptor.data(), descriptor.size()); + if (!CheckChecksum(sp, require_checksum)) return nullptr; auto ret = ParseScript(sp, ParseScriptContext::TOP, out); if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret)); return nullptr; |