aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Poinsot <darosior@protonmail.com>2023-03-16 10:03:45 +0100
committerAntoine Poinsot <darosior@protonmail.com>2023-10-08 02:43:26 +0200
commit117927bd5f30c8bf09aaf91e62f5244990788084 (patch)
tree834c8d9dbf8609767e4710d3c45c5e556e727712
parentb917c715ace19fb23661b4b245039da48cefc6bf (diff)
miniscript: have a custom Node destructor
To avoid recursive calls in shared_ptr's destructor that could lead to a stack overflow.
-rw-r--r--src/script/miniscript.h15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/script/miniscript.h b/src/script/miniscript.h
index 7585168ec2..48f39262cc 100644
--- a/src/script/miniscript.h
+++ b/src/script/miniscript.h
@@ -506,10 +506,23 @@ struct Node {
//! The data bytes in this expression (only for HASH160/HASH256/SHA256/RIPEMD10).
const std::vector<unsigned char> data;
//! Subexpressions (for WRAP_*/AND_*/OR_*/ANDOR/THRESH)
- const std::vector<NodeRef<Key>> subs;
+ mutable std::vector<NodeRef<Key>> subs;
//! The Script context for this node. Either P2WSH or Tapscript.
const MiniscriptContext m_script_ctx;
+ /* Destroy the shared pointers iteratively to avoid a stack-overflow due to recursive calls
+ * to the subs' destructors. */
+ ~Node() {
+ while (!subs.empty()) {
+ auto node = std::move(subs.back());
+ subs.pop_back();
+ while (!node->subs.empty()) {
+ subs.push_back(std::move(node->subs.back()));
+ node->subs.pop_back();
+ }
+ }
+ }
+
private:
//! Cached ops counts.
const internal::Ops ops;