Skip to content

Commit d7130f2

Browse files
committed
Add check for whitespace when parsing TreeNodesModel
1 parent e71f68d commit d7130f2

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

src/xml_parsing.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@
1010
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1111
*/
1212

13+
#include <algorithm>
14+
#include <cctype>
1315
#include <cstdio>
1416
#include <cstring>
1517
#include <functional>
1618
#include <iostream>
1719
#include <list>
1820
#include <sstream>
1921
#include <string>
22+
#include <string_view>
2023
#include <typeindex>
24+
2125
#include "behaviortree_cpp/basic_types.h"
2226
#include "behaviortree_cpp/utils/strcat.hpp"
2327

@@ -214,6 +218,13 @@ void BT::XMLParser::PImpl::loadSubtreeModel(const XMLElement* xml_root)
214218
{
215219
throw RuntimeError("Missing attribute [name] in port (SubTree model)");
216220
}
221+
std::string_view sname(name);
222+
if(std::any_of(sname.begin(), sname.end(),
223+
[](unsigned char c) { return std::isspace(c); }))
224+
{
225+
throw RuntimeError(
226+
StrCat("The name of a port must not contain whitespace: '", sname, "'"));
227+
}
217228
if(auto default_value = port_node->Attribute("default"))
218229
{
219230
port.setDefaultValue(default_value);

tests/gtest_subtree.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,50 @@ TEST(SubTree, SubtreeModels)
620620
tree.tickWhileRunning();
621621
}
622622

623+
TEST(SubTree, WhiteSpaceInSubtreeModel)
624+
{
625+
// clang-format off
626+
627+
static const char* xml_text = R"(
628+
<root main_tree_to_execute = "MainTree" BTCPP_format="4">
629+
<TreeNodesModel>
630+
<SubTree ID="MySub">
631+
<input_port name="port with space" default="42"/>
632+
</SubTree>
633+
</TreeNodesModel>
634+
635+
<BehaviorTree ID="MainTree">
636+
<Sequence>
637+
<Script code="my_name:= 'john' "/>
638+
<SubTree ID="MySub" />
639+
<ScriptCondition code=" output==69 && my_state=='ACTIVE' " />
640+
</Sequence>
641+
</BehaviorTree>
642+
643+
<BehaviorTree ID="MySub">
644+
<Sequence>
645+
<AlwaysSuccess />
646+
</Sequence>
647+
</BehaviorTree>
648+
</root>
649+
)";
650+
651+
// clang-format on
652+
653+
BehaviorTreeFactory factory;
654+
try
655+
{
656+
auto _ = factory.createTreeFromText(xml_text);
657+
}
658+
catch(RuntimeError e)
659+
{
660+
EXPECT_NE(std::string_view(e.what()).find("not contain whitespace"),
661+
std::string_view::npos);
662+
return;
663+
}
664+
FAIL() << "Exception was not thrown.";
665+
}
666+
623667
class PrintToConsole : public BT::SyncActionNode
624668
{
625669
public:

0 commit comments

Comments
 (0)