Skip to content

Commit 33c3673

Browse files
range-check uint16_t in the Any string to number fallback (#1242)
1 parent a7a0014 commit 33c3673

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

‎include/behaviortree_cpp/utils/safe_any.hpp‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,12 +453,10 @@ inline nonstd::expected<T, std::string> Any::stringToNumber() const
453453
#else
454454
try
455455
{
456-
if constexpr(std::is_same_v<T, uint16_t>)
457-
{
458-
return std::stoul(str.toStdString());
459-
}
460456
if constexpr(std::is_integral_v<T>)
461457
{
458+
// convert<T>() rejects values that don't fit in T, matching the
459+
// std::from_chars branch above.
462460
const int64_t val = std::stol(str.toStdString());
463461
Any temp_any(val);
464462
return temp_any.convert<T>();

‎tests/gtest_any.cpp‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,16 @@ TEST(Any, StringToNumberIgnoresLocale)
269269
EXPECT_EQ(Any(std::string("42")).cast<int>(), 42);
270270
EXPECT_ANY_THROW(auto res = Any(std::string("fifty")).cast<double>());
271271
}
272+
273+
TEST(Any, StringToUint16IsRangeChecked)
274+
{
275+
// A string that doesn't fit in uint16_t must be rejected, not wrapped.
276+
EXPECT_EQ(Any(std::string("65535")).cast<uint16_t>(), 65535);
277+
EXPECT_ANY_THROW(auto res = Any(std::string("65536")).cast<uint16_t>());
278+
EXPECT_ANY_THROW(auto res = Any(std::string("70000")).cast<uint16_t>());
279+
EXPECT_ANY_THROW(auto res = Any(std::string("-1")).cast<uint16_t>());
280+
281+
auto bb = Blackboard::create();
282+
bb->set("value", std::string("70000"));
283+
EXPECT_ANY_THROW(auto res = bb->get<uint16_t>("value"));
284+
}

0 commit comments

Comments
 (0)