Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BT::BehaviorTreeFactory does not fail when decorators have 0 children #423

Closed
@asasine

Description

@asasine

The following tree is successfully parsed by BT::BehaviorTreeFactory::createTreeFromText when I would have expected parsing to fail.

<root main_tree_to_execute="MainTree">
  <BehaviorTree ID="MainTree">
    <ForceSuccess>
    </ForceSuccess>
  </BehaviorTree>
</root>

Below is a test that verifies it's parsing incorrectly.

TEST(BehaviorTreeFactory, DecoratorWithoutChildThrows)
{
    BehaviorTreeFactory factory;
    const std::string tree_xml = R"(
<root>
    <BehaviorTree ID="Main">
        <ForceSuccess>
        </ForceSuccess>
    </BehaviorTree>
</root>
)";

    ASSERT_THROW(factory.createTreeFromText(tree_xml), BehaviorTreeException);
}

Output:

[ RUN      ] BehaviorTreeFactory.DecoratorWithoutChildThrows
/home/adam/src/BehaviorTree.CPP/tests/gtest_factory.cpp:375: Failure
Expected: factory.createTreeFromText(tree_xml) throws an exception of type BehaviorTreeException.
  Actual: it throws nothing.
[  FAILED  ] BehaviorTreeFactory.DecoratorWithoutChildThrows (2 ms)

Notes:

This caused a segmentation fault in our system as the returned BT::Tree has a decorator node with a nullptr child by default, so a tree.rootNode()->executeTick() crashes

: TreeNode::TreeNode(name, config), child_node_(nullptr)

The XML parsing logic has a validity check, but the decorator check for 1 child only works if the XML element's name "Decorator". When writing a tree like above, the XML element's name is "ForceSuccess"

if (StrEqual(name, "Decorator"))
{
if (children_count != 1)
{
ThrowError(node->GetLineNum(),
"The node <Decorator> must have exactly 1 child");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions