Skip to content

Commit 1bfb759

Browse files
committed
Merge branch 'master' into fuzzing
2 parents cc4cc9b + aa085b7 commit 1bfb759

File tree

15 files changed

+162
-38
lines changed

15 files changed

+162
-38
lines changed

.github/workflows/sonarcube.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Sonarcube Scan
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
types: [opened, synchronize, reopened]
8+
jobs:
9+
build:
10+
name: Build
11+
runs-on: ubuntu-latest
12+
env:
13+
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
18+
- name: Install Build Wrapper
19+
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v4
20+
21+
- name: Install Dependencies
22+
run: |
23+
sudo apt-get update
24+
sudo apt-get install -y libzmq3-dev libsqlite3-dev
25+
26+
- name: Install googletest
27+
uses: Bacondish2023/setup-googletest@v1
28+
29+
- name: Run Build Wrapper
30+
run: |
31+
mkdir build
32+
cmake -S . -B build
33+
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ --config Release
34+
- name: SonarQube Scan
35+
uses: SonarSource/sonarqube-scan-action@v4
36+
env:
37+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Put the name of your token here
38+
with:
39+
args: >
40+
--define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.16.3) # version on Ubuntu Focal
22

33
project(behaviortree_cpp VERSION 4.6.2 LANGUAGES C CXX)
44

5+
# create compile_commands.json
6+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
7+
58
#---- project configuration ----
69
option(BTCPP_SHARED_LIBS "Build shared libraries" ON)
710
option(BTCPP_BUILD_TOOLS "Build commandline tools" ON)

cmake/ament_build.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ endif()
1212

1313
find_package(ament_index_cpp REQUIRED)
1414

15+
set(BTCPP_EXTRA_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIRS}
16+
${SQLite3_INCLUDE_DIRS})
17+
1518
set( BTCPP_EXTRA_LIBRARIES
1619
$<BUILD_INTERFACE:ament_index_cpp::ament_index_cpp>
1720
$<BUILD_INTERFACE:${ZeroMQ_LIBRARIES}>
@@ -26,6 +29,7 @@ set( BTCPP_BIN_DESTINATION bin )
2629

2730
mark_as_advanced(
2831
BTCPP_EXTRA_LIBRARIES
32+
BTCPP_EXTRA_INCLUDE_DIRS
2933
BTCPP_LIB_DESTINATION
3034
BTCPP_INCLUDE_DESTINATION
3135
BTCPP_BIN_DESTINATION )

include/behaviortree_cpp/bt_factory.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ class Tree
109109
Tree(const Tree&) = delete;
110110
Tree& operator=(const Tree&) = delete;
111111

112-
Tree(Tree&& other);
113-
Tree& operator=(Tree&& other);
112+
Tree(Tree&& other) = default;
113+
Tree& operator=(Tree&& other) = default;
114114

115115
void initialize();
116116

@@ -149,7 +149,7 @@ class Tree
149149
[[nodiscard]] Blackboard::Ptr rootBlackboard();
150150

151151
//Call the visitor for each node of the tree.
152-
void applyVisitor(const std::function<void(const TreeNode*)>& visitor);
152+
void applyVisitor(const std::function<void(const TreeNode*)>& visitor) const;
153153

154154
//Call the visitor for each node of the tree.
155155
void applyVisitor(const std::function<void(TreeNode*)>& visitor);
@@ -215,8 +215,8 @@ class BehaviorTreeFactory
215215
BehaviorTreeFactory(const BehaviorTreeFactory& other) = delete;
216216
BehaviorTreeFactory& operator=(const BehaviorTreeFactory& other) = delete;
217217

218-
BehaviorTreeFactory(BehaviorTreeFactory&& other) noexcept;
219-
BehaviorTreeFactory& operator=(BehaviorTreeFactory&& other) noexcept;
218+
BehaviorTreeFactory(BehaviorTreeFactory&& other) noexcept = default;
219+
BehaviorTreeFactory& operator=(BehaviorTreeFactory&& other) noexcept = default;
220220

221221
/// Remove a registered ID.
222222
bool unregisterBuilder(const std::string& ID);

include/behaviortree_cpp/decorators/loop_node.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ class LoopNode : public DecoratorNode
6060
// special case: the port contains a string that was converted to SharedQueue<T>
6161
if(static_queue_)
6262
{
63-
current_queue_ = static_queue_;
63+
current_queue_ = std::make_shared<std::deque<T>>();
64+
*current_queue_ = *static_queue_;
6465
}
6566
}
6667

include/behaviortree_cpp/json_export.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,12 @@ inline Expected<T> JsonExporter::fromJson(const nlohmann::json& source) const
114114
auto res = fromJson(source);
115115
if(!res)
116116
{
117-
return nonstd::expected_lite::make_unexpected(res.error());
117+
return nonstd::make_unexpected(res.error());
118118
}
119119
auto casted = res->first.tryCast<T>();
120120
if(!casted)
121121
{
122-
return nonstd::expected_lite::make_unexpected(casted.error());
122+
return nonstd::make_unexpected(casted.error());
123123
}
124124
return *casted;
125125
}

include/behaviortree_cpp/scripting/operators.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ struct ExprUnaryArithmetic : ExprBase
129129
case negate:
130130
return Any(-rv);
131131
case complement:
132+
if(rv > static_cast<double>(std::numeric_limits<int64_t>::max()) ||
133+
rv < static_cast<double>(std::numeric_limits<int64_t>::min()))
134+
{
135+
throw RuntimeError("Number out of range for bitwise operation");
136+
}
132137
return Any(static_cast<double>(~static_cast<int64_t>(rv)));
133138
case logical_not:
134139
return Any(static_cast<double>(!static_cast<bool>(rv)));

include/behaviortree_cpp/tree_node.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,8 @@ inline Result TreeNode::setOutput(const std::string& key, const T& value)
598598

599599
if constexpr(std::is_same_v<BT::Any, T>)
600600
{
601-
if(config().manifest->ports.at(key).type() != typeid(BT::Any))
601+
auto port_type = config().manifest->ports.at(key).type();
602+
if(port_type != typeid(BT::Any) && port_type != typeid(BT::AnyTypeAllowed))
602603
{
603604
throw LogicError("setOutput<Any> is not allowed, unless the port "
604605
"was declared using OutputPort<Any>");

include/behaviortree_cpp/utils/convert_impl.hpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#pragma once
1414

1515
#include <type_traits>
16+
#include <cmath>
1617
#include "simple_string.hpp"
1718

1819
#undef max
@@ -88,9 +89,42 @@ inline void checkLowerLimit(const From& from)
8889
template <typename From, typename To>
8990
inline void checkTruncation(const From& from)
9091
{
91-
if(from != static_cast<From>(static_cast<To>(from)))
92+
// Handle integer to floating point
93+
if constexpr(std::is_integral_v<From> && std::is_floating_point_v<To>)
9294
{
93-
throw std::runtime_error("Floating point truncated");
95+
// Check if value can be represented exactly in the target type
96+
constexpr auto max_exact = (1LL << std::numeric_limits<double>::digits) - 1;
97+
if(from > max_exact || from < -max_exact)
98+
{
99+
throw std::runtime_error("Loss of precision when converting a large integer number "
100+
"to floating point:" +
101+
std::to_string(from));
102+
}
103+
}
104+
// Handle floating point to integer
105+
else if constexpr(std::is_floating_point_v<From> && std::is_integral_v<To>)
106+
{
107+
if(from > static_cast<From>(std::numeric_limits<To>::max()) ||
108+
from < static_cast<From>(std::numeric_limits<To>::lowest()) ||
109+
from != std::nearbyint(from))
110+
{
111+
throw std::runtime_error("Invalid floating point to integer conversion");
112+
}
113+
}
114+
// Handle other conversions
115+
else
116+
{
117+
if(from > static_cast<From>(std::numeric_limits<To>::max()) ||
118+
from < static_cast<From>(std::numeric_limits<To>::lowest()))
119+
{
120+
throw std::runtime_error("Value outside numeric limits");
121+
}
122+
To as_target = static_cast<To>(from);
123+
From back_to_source = static_cast<From>(as_target);
124+
if(from != back_to_source)
125+
{
126+
throw std::runtime_error("Value truncated in conversion");
127+
}
94128
}
95129
}
96130

include/behaviortree_cpp/utils/safe_any.hpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,34 @@ class Any
245245
template <typename SRC, typename TO>
246246
inline bool ValidCast(const SRC& val)
247247
{
248-
return (val == static_cast<SRC>(static_cast<TO>(val)));
248+
// First check numeric limits
249+
if constexpr(std::is_arithmetic_v<SRC> && std::is_arithmetic_v<TO>)
250+
{
251+
// Handle conversion to floating point
252+
if constexpr(std::is_floating_point_v<TO>)
253+
{
254+
if constexpr(std::is_integral_v<SRC>)
255+
{
256+
// For integral to float, check if we can represent the value exactly
257+
TO as_float = static_cast<TO>(val);
258+
SRC back_conv = static_cast<SRC>(as_float);
259+
return back_conv == val;
260+
}
261+
}
262+
// Handle conversion to integral
263+
else if constexpr(std::is_integral_v<TO>)
264+
{
265+
if(val > static_cast<SRC>(std::numeric_limits<TO>::max()) ||
266+
val < static_cast<SRC>(std::numeric_limits<TO>::lowest()))
267+
{
268+
return false;
269+
}
270+
}
271+
}
272+
273+
TO as_target = static_cast<TO>(val);
274+
SRC back_to_source = static_cast<SRC>(as_target);
275+
return val == back_to_source;
249276
}
250277

251278
template <typename T>

0 commit comments

Comments
 (0)