From b7485f11ab3a0f1860b261f222362af3301e0781 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 5 Oct 2023 12:29:22 -0400 Subject: [PATCH] descriptors: Check result of InferPubkey InferPubkey can return a nullptr, so check it's result before continuing with creating the inferred descriptor. --- src/script/descriptor.cpp | 46 +++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index ba2334df497..720541c67f8 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -1491,14 +1491,18 @@ struct KeyParser { if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) { XOnlyPubKey pubkey; std::copy(begin, end, pubkey.begin()); - m_keys.push_back(InferPubkey(pubkey.GetEvenCorrespondingCPubKey(), ParseContext(), *m_in)); - return key; - } else if (!miniscript::IsTapscript(m_script_ctx)) { - CPubKey pubkey{begin, end}; - if (pubkey.IsValidNonHybrid()) { - m_keys.push_back(InferPubkey(pubkey, ParseContext(), *m_in)); + if (auto pubkey_provider = InferPubkey(pubkey.GetEvenCorrespondingCPubKey(), ParseContext(), *m_in)) { + m_keys.push_back(std::move(pubkey_provider)); return key; } + } else if (!miniscript::IsTapscript(m_script_ctx)) { + CPubKey pubkey(begin, end); + if (pubkey.IsValidNonHybrid()) { + if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) { + m_keys.push_back(std::move(pubkey_provider)); + return key; + } + } } return {}; } @@ -1512,9 +1516,11 @@ struct KeyParser { CKeyID keyid(hash); CPubKey pubkey; if (m_in->GetPubKey(keyid, pubkey)) { - Key key = m_keys.size(); - m_keys.push_back(InferPubkey(pubkey, ParseContext(), *m_in)); - return key; + if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) { + Key key = m_keys.size(); + m_keys.push_back(std::move(pubkey_provider)); + return key; + } } return {}; } @@ -1850,7 +1856,9 @@ std::unique_ptr InferScript(const CScript& script, ParseScriptCo if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { CPubKey pubkey(data[0]); if (pubkey.IsValidNonHybrid()) { - return std::make_unique(InferPubkey(pubkey, ctx, provider)); + if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { + return std::make_unique(std::move(pubkey_provider)); + } } } if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { @@ -1858,7 +1866,9 @@ std::unique_ptr InferScript(const CScript& script, ParseScriptCo CKeyID keyid(hash); CPubKey pubkey; if (provider.GetPubKey(keyid, pubkey)) { - return std::make_unique(InferPubkey(pubkey, ctx, provider)); + if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { + return std::make_unique(std::move(pubkey_provider)); + } } } if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) { @@ -1866,16 +1876,24 @@ std::unique_ptr InferScript(const CScript& script, ParseScriptCo CKeyID keyid(hash); CPubKey pubkey; if (provider.GetPubKey(keyid, pubkey)) { - return std::make_unique(InferPubkey(pubkey, ctx, provider)); + if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { + return std::make_unique(std::move(pubkey_provider)); + } } } if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { + bool ok = true; std::vector> providers; for (size_t i = 1; i + 1 < data.size(); ++i) { CPubKey pubkey(data[i]); - providers.push_back(InferPubkey(pubkey, ctx, provider)); + if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) { + providers.push_back(std::move(pubkey_provider)); + } else { + ok = false; + break; + } } - return std::make_unique((int)data[0][0], std::move(providers)); + if (ok) return std::make_unique((int)data[0][0], std::move(providers)); } if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) { uint160 hash(data[0]);