Skip to content

Commit 7909f9f

Browse files
hodlinatorl0rinc
andcommitted
test(miniscript): Prove avoidance of stack overflow
Can be tested through emptying the function body of ~Node() or replacing Clone() implementation with naive version: ```C++ Node<Key> Clone() const { std::vector<Node> new_subs; new_subs.reserve(subs.size()); for (const Node& child : subs) { new_subs.push_back(child.Clone()); } return Node{internal::NoDupCheck{}, m_script_ctx, fragment, std::move(new_subs), keys, data, k}; } ``` Co-authored-by: Lőrinc <[email protected]>
1 parent dfd85b0 commit 7909f9f

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

src/test/miniscript_tests.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,4 +727,25 @@ BOOST_AUTO_TEST_CASE(fixed_tests)
727727
g_testdata.reset();
728728
}
729729

730+
// Confirm that ~Node(), Node::Clone() and operator=(Node&&) are stack-safe.
731+
BOOST_AUTO_TEST_CASE(node_deep_destruct)
732+
{
733+
using miniscript::internal::NoDupCheck;
734+
using miniscript::Fragment;
735+
using NodeU32 = miniscript::Node<uint32_t>;
736+
737+
constexpr auto ctx{miniscript::MiniscriptContext::P2WSH};
738+
739+
NodeU32 root{NoDupCheck{}, ctx, Fragment::JUST_1};
740+
for (uint32_t i{0}; i < 200'000; ++i) {
741+
root = NodeU32{NoDupCheck{}, ctx, Fragment::WRAP_S, Vector(std::move(root))};
742+
}
743+
BOOST_CHECK_EQUAL(root.ScriptSize(), 200'001);
744+
745+
auto clone{root.Clone()};
746+
BOOST_CHECK_EQUAL(clone.ScriptSize(), root.ScriptSize());
747+
748+
clone = std::move(root);
749+
}
750+
730751
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)