From ffbd5f7aee3280e92cdb6a9eb7c709e6c243c0a9 Mon Sep 17 00:00:00 2001 From: Davide Faconti Date: Sun, 1 Feb 2026 18:38:42 +0100 Subject: [PATCH] Fix #974: numeric comparison for string-valued blackboard entries in scripts --- .../behaviortree_cpp/scripting/operators.hpp | 30 +++++++++++++++--- tests/gtest_blackboard.cpp | 31 +++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/include/behaviortree_cpp/scripting/operators.hpp b/include/behaviortree_cpp/scripting/operators.hpp index bd6bfc863..cb61ce631 100644 --- a/include/behaviortree_cpp/scripting/operators.hpp +++ b/include/behaviortree_cpp/scripting/operators.hpp @@ -16,6 +16,7 @@ #include "behaviortree_cpp/scripting/script_parser.hpp" #include +#include #include #include #include @@ -407,11 +408,32 @@ struct ExprComparison : ExprBase } else if(lhs_v.isString() && rhs_v.isString()) { - auto lv = lhs_v.cast(); - auto rv = rhs_v.cast(); - if(!SwitchImpl(lv, rv, ops[i])) + // Try numeric comparison when both strings are parseable as numbers. + // This handles values set via blackboard->set(key, "42"). Issue #974. + auto ls = lhs_v.cast(); + auto rs = rhs_v.cast(); + char* lend = nullptr; + char* rend = nullptr; + double ld = std::strtod(ls.c_str(), &lend); + double rd = std::strtod(rs.c_str(), &rend); + bool l_numeric = (lend == ls.c_str() + ls.size()) && !ls.empty(); + bool r_numeric = (rend == rs.c_str() + rs.size()) && !rs.empty(); + + if(l_numeric && r_numeric) { - return False; + if(!SwitchImpl(ld, rd, ops[i])) + { + return False; + } + } + else + { + auto lv = lhs_v.cast(); + auto rv = rhs_v.cast(); + if(!SwitchImpl(lv, rv, ops[i])) + { + return False; + } } } else if(lhs_v.isString() && rhs_v.isNumber()) diff --git a/tests/gtest_blackboard.cpp b/tests/gtest_blackboard.cpp index 2c10e78d8..41f6008c9 100644 --- a/tests/gtest_blackboard.cpp +++ b/tests/gtest_blackboard.cpp @@ -745,3 +745,34 @@ TEST(BlackboardTest, SetBlackboard_WithPortRemapping) // Tick till the end with no crashes ASSERT_NO_THROW(tree.tickWhileRunning();); } + +// Issue #974: blackboard->set(key, "42") stores a string. +// When two string-valued blackboard entries are compared in a script, +// numeric comparison should be used if both strings are parseable as numbers. +// "9" < "10" is false lexicographically but true numerically. +TEST(BlackboardTest, StringSetNumericScriptComparison_Issue974) +{ + auto bb = Blackboard::create(); + bb->set("a", std::string("9")); + bb->set("b", std::string("10")); + + BehaviorTreeFactory factory; + + std::string xml_txt = R"( + + + +