Steps to reproduce:

* Build with `integer` sanitizer
* Start: `UBSAN_OPTIONS="suppressions=$(pwd)/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" ./src/qt/bitcoin-qt -chain=main`
* Enter `getdescriptorinfo "sh(multi(1,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/5/5/5/2/8/5/8/8/8/2/2/5/8/5/2/5/85/58/5/2/5/5/5/5/2/58/2/5/8/0000/00/8/5/2/001/1/246/8/501/46/8/5/8/5/000/8/52/5/8/5/2/8/2/5/8/5/246/8/5/2/8/2/5/8/5/2/5/8/8/2/5/5/5/58/88/2/6/8/5/2/8/2/5/8/2/588/5/2/5/8/5/2/8/5/1/5/4/5/5/5/2/6/8/5/2/8/2/5/8/5/2/5/58/58/2/5/8/58/588/2/52/5/5/5/58/8/2/6/8/5/2/8/2/5/8/2/588/5/2/5/8/5/2/8/5/15/58/58/2/6/8/5/2/8/2/5/8/5/2/5/8/58/2/5/58/58/588/2/5/2/8/5/8/5/4/5/58/588/2/6/8/5/2/8/2/5/8/2/8/5/2/8/2/5/8/5/2/5/58/58/2/5/5/5/58/588/2/6/8/5/2/8/2/5/8/2/8/588/2/6/8/5/2/8/2/5/5/8/5/2/0/8/5/2/00/4/5/5/588/2/6/8/5/2/8/25/5/8/2/5/58/58/8/4/1,[00000000]xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/58)0)"` into the console
KeyPath path;
    DeriveType type = DeriveType::NO;
    if (split.back() == Span{"*"}.first(1)) {
        split.pop_back();
        type = DeriveType::UNHARDENED;
    } else if (split.back() == Span{"*'"}.first(2) || split.back() == Span{"*h"}.first(2)) {
        split.pop_back();
        type = DeriveType::HARDENED;
    }
    if (!ParseKeyPath(split, path, error)) return nullptr;
    if (extkey.key.IsValid()) {
        extpubkey = extkey.Neuter();
        out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
    }
    return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type);
}
std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
{
    using namespace spanparsing;
    auto origin_split = Split(sp, ']');
    if (origin_split.size() > 2) {
        error = "Multiple ']' characters found for a single pubkey";
        return nullptr;
    }
    if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, error);
    if (origin_split[0].empty() || origin_split[0][0] != '[') {
        error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
                          origin_split[0].empty() ?  ']' : origin_split[0][0]);
        return nullptr;
    }