diff --git a/rclcpp/src/rclcpp/typesupport_helpers.cpp b/rclcpp/src/rclcpp/typesupport_helpers.cpp index 98fe703a55..22e3cebea6 100644 --- a/rclcpp/src/rclcpp/typesupport_helpers.cpp +++ b/rclcpp/src/rclcpp/typesupport_helpers.cpp @@ -15,6 +15,7 @@ #include "rclcpp/typesupport_helpers.hpp" +#include #include #include #include @@ -73,6 +74,21 @@ const void * get_typesupport_handle_impl( } } +// Trim leading and trailing whitespace from the string. +std::string string_trim(std::string_view str_v) +{ + auto begin = std::find_if_not(str_v.begin(), str_v.end(), [](unsigned char ch) { + return std::isspace(ch); + }); + auto end = std::find_if_not(str_v.rbegin(), str_v.rend(), [](unsigned char ch) { + return std::isspace(ch); + }).base(); + if (begin >= end) { + return {}; + } + return std::string(begin, end); +} + } // anonymous namespace std::tuple @@ -82,6 +98,7 @@ extract_type_identifier(const std::string & full_type) auto sep_position_back = full_type.find_last_of(type_separator); auto sep_position_front = full_type.find_first_of(type_separator); if (sep_position_back == std::string::npos || + sep_position_front == 0 || sep_position_back == 0 || sep_position_back == full_type.length() - 1) { @@ -97,7 +114,8 @@ extract_type_identifier(const std::string & full_type) } std::string type_name = full_type.substr(sep_position_back + 1); - return std::make_tuple(package_name, middle_module, type_name); + return std::make_tuple( + string_trim(package_name), string_trim(middle_module), string_trim(type_name)); } std::string get_typesupport_library_path( diff --git a/rclcpp/test/rclcpp/test_typesupport_helpers.cpp b/rclcpp/test/rclcpp/test_typesupport_helpers.cpp index bbd45772f7..4b7c77a4fa 100644 --- a/rclcpp/test/rclcpp/test_typesupport_helpers.cpp +++ b/rclcpp/test/rclcpp/test_typesupport_helpers.cpp @@ -158,3 +158,15 @@ TEST(TypesupportHelpersTest, test_throw_exception_with_invalid_type) { rclcpp::get_action_typesupport_handle(invalid_type, "rosidl_typesupport_cpp", *library), std::runtime_error); } + +TEST(TypesupportHelpersTest, throws_exception_if_filetype_has_multiple_slashes_at_start) { + EXPECT_ANY_THROW(rclcpp::extract_type_identifier("//name_with_slashes_at_start")); +} + +TEST(TypesupportHelpersTestV3, ProcessesValidTypeWithWhitespace) { + std::string package, middle, name; + std::tie(package, middle, name) = rclcpp::extract_type_identifier(" package/ name "); + EXPECT_EQ(package, "package"); + EXPECT_TRUE(middle.empty()); + EXPECT_EQ(name, "name"); +}