bt_fuzzer.cpp
Go to the documentation of this file.
1 #include <fuzzer/FuzzedDataProvider.h>
4 #include <string>
5 
6 // List of valid node types we can use to construct valid-ish XML
7 constexpr const char* NODE_TYPES[] = {
8  "Sequence", "Fallback", "ParallelAll",
9  "ReactiveSequence", "ReactiveFallback", "IfThenElse",
10  "WhileDoElse", "Inverter", "RetryUntilSuccessful",
11  "Repeat", "Timeout", "Delay",
12  "ForceSuccess", "ForceFailure", "AlwaysSuccess",
13  "AlwaysFailure", "SetBlackboard", "SubTree"
14 };
15 
16 // Attributes that can be added to nodes
17 constexpr const char* NODE_ATTRIBUTES[] = { "name", "ID", "port_1",
18  "port_2", "timeout_ms", "delay_ms",
19  "threshold", "max_repeats" };
20 
21 std::string generateFuzzedNodeXML(FuzzedDataProvider& fdp, int depth = 0)
22 {
23  // Prevent stack overflow with max depth
24  if(depth > 6)
25  { // Reasonable limit for XML tree depth
26  return "<AlwaysSuccess/>";
27  }
28 
29  std::string xml;
30  const std::string node_type = fdp.PickValueInArray(NODE_TYPES);
31 
32  xml += "<" + node_type;
33 
34  size_t num_attributes = fdp.ConsumeIntegralInRange<size_t>(0, 3);
35  for(size_t i = 0; i < num_attributes; i++)
36  {
37  const std::string attr = fdp.PickValueInArray(NODE_ATTRIBUTES);
38  std::string value = fdp.ConsumeRandomLengthString(10);
39  xml += " " + attr + "=\"" + value + "\"";
40  }
41 
42  if(depth > 3 || fdp.ConsumeBool())
43  {
44  xml += "/>";
45  }
46  else
47  {
48  xml += ">";
49  // Add some child nodes recursively with depth limit
50  size_t num_children = fdp.ConsumeIntegralInRange<size_t>(0, 2);
51  for(size_t i = 0; i < num_children; i++)
52  {
53  xml += generateFuzzedNodeXML(fdp, depth + 1);
54  }
55  xml += "</" + node_type + ">";
56  }
57 
58  return xml;
59 }
60 
61 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
62 {
63  if(size < 4)
64  {
65  return 0;
66  }
67 
68  FuzzedDataProvider fdp(data, size);
70 
71  try
72  {
73  // Strategy 1: Test with completely random data
74  if(fdp.ConsumeBool())
75  {
76  std::string random_xml = fdp.ConsumeRandomLengthString(size - 1);
77  try
78  {
79  factory.createTreeFromText(random_xml);
80  }
81  catch(const std::exception&)
82  {}
83  }
84  // Strategy 2: Generate semi-valid XML
85  else
86  {
87  std::string xml = R"(
88  <root BTCPP_format="4">
89  <BehaviorTree ID="MainTree">)";
90 
91  size_t num_nodes = fdp.ConsumeIntegralInRange<size_t>(1, 5);
92  for(size_t i = 0; i < num_nodes; i++)
93  {
94  xml += generateFuzzedNodeXML(fdp);
95  }
96 
97  xml += R"(
98  </BehaviorTree>
99  </root>)";
100 
101  auto blackboard = BT::Blackboard::create();
102 
103  switch(fdp.ConsumeIntegralInRange<int>(0, 2))
104  {
105  case 0:
106  factory.createTreeFromText(xml, blackboard);
107  break;
108  case 1:
109  BT::VerifyXML(xml, {});
110  break;
111  case 2:
112  factory.registerBehaviorTreeFromText(xml);
113  if(!factory.registeredBehaviorTrees().empty())
114  {
115  factory.createTree(factory.registeredBehaviorTrees().front(), blackboard);
116  }
117  break;
118  }
119  }
120  }
121  catch(const std::exception&)
122  {}
123 
124  return 0;
125 }
cx::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: wildcards.hpp:636
NODE_TYPES
constexpr const char * NODE_TYPES[]
Definition: bt_fuzzer.cpp:7
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition: bt_fuzzer.cpp:61
BT::BehaviorTreeFactory::registeredBehaviorTrees
std::vector< std::string > registeredBehaviorTrees() const
Definition: bt_factory.cpp:271
BT::BehaviorTreeFactory::createTree
Tree createTree(const std::string &tree_name, Blackboard::Ptr blackboard=Blackboard::create())
Definition: bt_factory.cpp:421
bt_factory.h
magic_enum::detail::value
constexpr E value(std::size_t i) noexcept
Definition: magic_enum.hpp:664
BT::BehaviorTreeFactory::createTreeFromText
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
createTreeFromText will parse the XML directly from string. The XML needs to contain either a single ...
Definition: bt_factory.cpp:384
xml_parsing.h
NODE_ATTRIBUTES
constexpr const char * NODE_ATTRIBUTES[]
Definition: bt_fuzzer.cpp:17
BT::BehaviorTreeFactory
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:209
BT::Blackboard::create
static Blackboard::Ptr create(Blackboard::Ptr parent={})
Definition: blackboard.h:63
BT::BehaviorTreeFactory::registerBehaviorTreeFromText
void registerBehaviorTreeFromText(const std::string &xml_text)
Definition: bt_factory.cpp:266
generateFuzzedNodeXML
std::string generateFuzzedNodeXML(FuzzedDataProvider &fdp, int depth=0)
Definition: bt_fuzzer.cpp:21
BT::VerifyXML
void VerifyXML(const std::string &xml_text, const std::unordered_map< std::string, NodeType > &registered_nodes)


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Wed Apr 16 2025 02:20:55