@@ -76,6 +76,40 @@ void incompleteHookScenario()
7676 std::exit (EXIT_SUCCESS );
7777}
7878
79+ void deeplyNestedHookScenario ()
80+ {
81+ BT ::BehaviorTreeFactory factory;
82+ auto tree = factory.createTreeFromText (R"(
83+ <root BTCPP_format="4">
84+ <BehaviorTree ID="MainTree">
85+ <AlwaysSuccess/>
86+ </BehaviorTree>
87+ </root>
88+ )" );
89+ auto [publisher, port] = Groot2Test::makePublisher (tree);
90+ // Under the sanitizers, parsing the request below takes a few seconds.
91+ Groot2Test::Client client (port, 30000 );
92+
93+ // The error for a "uid" that isn't an integer used to dump() the value, which
94+ // recurses once per nesting level and overflowed the stack of the server thread.
95+ constexpr size_t depth = 100000 ;
96+ const std::string nested = std::string (depth, ' [' ) + std::string (depth, ' ]' );
97+ auto error_reply = client.rawRequest (BT ::Monitor::RequestType::HOOK_INSERT ,
98+ R"( {"uid":)" + nested + R"( ,"position":0})" );
99+ if (error_reply.size () != 2 || error_reply[0 ].to_string () != " error" )
100+ {
101+ std::exit (EXIT_FAILURE );
102+ }
103+
104+ // The server thread must remain usable after rejecting the nested request.
105+ auto valid_reply = client.request (BT ::Monitor::RequestType::FULLTREE );
106+ if (valid_reply.size () != 2 )
107+ {
108+ std::exit (EXIT_FAILURE );
109+ }
110+ std::exit (EXIT_SUCCESS );
111+ }
112+
79113BT ::Tree createTreeWithNamedSubtrees (BT ::BehaviorTreeFactory& factory,
80114 const BT ::Blackboard::Ptr& main_blackboard)
81115{
@@ -207,6 +241,12 @@ TEST(Groot2PublisherIntegration, IncompleteHookRequestDoesNotTerminateServer)
207241 EXPECT_EXIT (incompleteHookScenario (), ::testing::ExitedWithCode (EXIT_SUCCESS ), " .*" );
208242}
209243
244+ TEST (Groot2PublisherIntegration, DeeplyNestedHookRequestDoesNotTerminateServer)
245+ {
246+ ::testing::FLAGS_gtest_death_test_style = " threadsafe" ;
247+ EXPECT_EXIT (deeplyNestedHookScenario (), ::testing::ExitedWithCode (EXIT_SUCCESS ), " .*" );
248+ }
249+
210250TEST (Groot2PublisherIntegration, BindToLoopbackAddress)
211251{
212252 BT ::BehaviorTreeFactory factory;
0 commit comments