Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions src/controls/switch_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ bool CheckStringEquality(const std::string& v1, const std::string& v2,
}
}
#if __cpp_lib_to_chars >= 201611L
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
return (ec == std::errc());
const char* end = str.data() + str.size();
auto [ptr, ec] = std::from_chars(str.data(), end, result);
return ec == std::errc() && ptr == end;
#else
try
{
result = std::stoi(str);
return true;
std::size_t pos = 0;
result = std::stoi(str, &pos);
return pos == str.size();
}
catch(...)
{
Expand All @@ -60,15 +62,26 @@ bool CheckStringEquality(const std::string& v1, const std::string& v2,
return true;
}
// compare as real numbers next
auto ToReal = [](const std::string& str, auto& result) -> bool {
auto ToReal = [enums](const std::string& str, auto& result) -> bool {
if(enums)
{
auto it = enums->find(str);
if(it != enums->end())
{
result = it->second;
return true;
}
}
#if __cpp_lib_to_chars >= 201611L
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
return (ec == std::errc());
const char* end = str.data() + str.size();
auto [ptr, ec] = std::from_chars(str.data(), end, result);
return ec == std::errc() && ptr == end;
#else
try
{
result = std::stod(str);
return true;
std::size_t pos = 0;
result = std::stod(str, &pos);
return pos == str.size();
}
catch(...)
{
Expand Down
19 changes: 19 additions & 0 deletions tests/gtest_switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "behaviortree_cpp/behavior_tree.h"
#include "behaviortree_cpp/bt_factory.h"
#include "behaviortree_cpp/controls/switch_node.h"
#include "behaviortree_cpp/tree_node.h"

#include <gtest/gtest.h>
Expand Down Expand Up @@ -245,3 +246,21 @@ TEST_F(SwitchTest, ActionFailure)
ASSERT_EQ(NodeStatus::IDLE, action_42.status());
ASSERT_EQ(NodeStatus::IDLE, action_def.status());
}

TEST(SwitchStringEquality, RejectsTrailingCharacters)
{
using BT::details::CheckStringEquality;

// legitimate matches must keep working
EXPECT_TRUE(CheckStringEquality("5", "5", nullptr));
EXPECT_TRUE(CheckStringEquality("5", "5.0", nullptr));
EXPECT_TRUE(CheckStringEquality("42", "42", nullptr));
EXPECT_TRUE(CheckStringEquality("-7", "-7", nullptr));

// a selector with trailing bytes must not match a numeric case
EXPECT_FALSE(CheckStringEquality("5abc", "5", nullptr));
EXPECT_FALSE(CheckStringEquality("42xxxx", "42", nullptr));
EXPECT_FALSE(CheckStringEquality("1.0junk", "1.0", nullptr));
EXPECT_FALSE(CheckStringEquality("5 ", "5", nullptr));
EXPECT_FALSE(CheckStringEquality("none", "1", nullptr));
}
Loading