From 3643ca473d894490c6a416b4baf1e7d600648a6f Mon Sep 17 00:00:00 2001 From: Aysha Afrah Ziya Date: Mon, 26 Oct 2026 20:55:22 +0530 Subject: [PATCH] use the locked entry in script assignment string conversion --- .../behaviortree_cpp/scripting/operators.hpp | 6 +++--- tests/script_parser_test.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/behaviortree_cpp/scripting/operators.hpp b/include/behaviortree_cpp/scripting/operators.hpp index 6cc38412f..b71df07e5 100644 --- a/include/behaviortree_cpp/scripting/operators.hpp +++ b/include/behaviortree_cpp/scripting/operators.hpp @@ -622,9 +622,9 @@ struct ExprAssignment : ExprBase // special case: string to other type. // Check if we can use the StringConverter auto const str = value.cast(); - const auto* entry_info = env.vars->entryInfo(key); - - if(auto converter = entry_info->converter()) + // Use the entry locked above. Looking the key up again could return + // nullptr, or a different entry, if it was unset in the meantime. + if(auto converter = entry->info.converter()) { *dst_ptr = converter(str); } diff --git a/tests/script_parser_test.cpp b/tests/script_parser_test.cpp index 9a4360eff..64f5bba7a 100644 --- a/tests/script_parser_test.cpp +++ b/tests/script_parser_test.cpp @@ -721,6 +721,25 @@ TEST(ParserTest, BitwiseComplementRejectsNonIntegers) static_cast(~std::numeric_limits::min())); } +TEST(ParserTest, AssignStringWhileEntryIsUnset) +{ + auto bb = BT::Blackboard::create(); + bb->set("x", 1); + bb->set("y", ""); + BT::Ast::Environment env = { bb, {} }; + + // Writing y unsets x, after the assignment to x has already resolved its + // entry. The string to int conversion then used to look x up again and + // dereference the nullptr returned for the missing entry. Another thread + // calling unset() at the wrong time has the same effect. + auto subscriber = bb->subscribeToEntry("y", [&bb]() { bb->unset("x"); }); + + auto result = BT::ParseScriptAndExecute(env, "x = (y = '42')"); + ASSERT_TRUE(result.has_value()) << result.error(); + EXPECT_EQ(result.value().cast(), 42); + EXPECT_EQ(bb->getEntry("x"), nullptr); +} + TEST(ParserTest, TernaryExpressions) { BT::Ast::Environment env = { BT::Blackboard::create(), {} };