Skip to content

Commit

Permalink
Add node name and namespace validation to graph functions (#499)
Browse files Browse the repository at this point in the history
Signed-off-by: ivanpauno <ivanpauno@ekumenlabs.com>
  • Loading branch information
ivanpauno authored Sep 13, 2019
1 parent 0ddc17a commit 17598ff
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 22 deletions.
10 changes: 10 additions & 0 deletions rcl/include/rcl/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ typedef rmw_names_and_types_t rcl_names_and_types_t;
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
* \return `RCL_RET_NODE_INVALID_NAME` if the node name is invalid, or
* \return `RCL_RET_NODE_INVALID_NAMESPACE` if the node namespace is invalid, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
Expand Down Expand Up @@ -122,6 +124,8 @@ rcl_get_publisher_names_and_types_by_node(
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
* \return `RCL_RET_NODE_INVALID_NAME` if the node name is invalid, or
* \return `RCL_RET_NODE_INVALID_NAMESPACE` if the node namespace is invalid, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
Expand Down Expand Up @@ -168,6 +172,8 @@ rcl_get_subscriber_names_and_types_by_node(
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
* \return `RCL_RET_NODE_INVALID_NAME` if the node name is invalid, or
* \return `RCL_RET_NODE_INVALID_NAMESPACE` if the node namespace is invalid, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
Expand Down Expand Up @@ -213,6 +219,8 @@ rcl_get_service_names_and_types_by_node(
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
* \return `RCL_RET_NODE_INVALID_NAME` if the node name is invalid, or
* \return `RCL_RET_NODE_INVALID_NAMESPACE` if the node namespace is invalid, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
Expand Down Expand Up @@ -257,6 +265,8 @@ rcl_get_client_names_and_types_by_node(
* \return `RCL_RET_OK` if the query was successful, or
* \return `RCL_RET_NODE_INVALID` if the node is invalid, or
* \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
* \return `RCL_RET_NODE_INVALID_NAME` if the node name is invalid, or
* \return `RCL_RET_NODE_INVALID_NAMESPACE` if the node namespace is invalid, or
* \return `RCL_RET_ERROR` if an unspecified error occurs.
*/
RCL_PUBLIC
Expand Down
57 changes: 54 additions & 3 deletions rcl/src/rcl/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,50 @@ extern "C"
#include "rcl/error_handling.h"
#include "rcutils/allocator.h"
#include "rcutils/types.h"
#include "rmw/error_handling.h"
#include "rmw/get_node_info_and_types.h"
#include "rmw/get_service_names_and_types.h"
#include "rmw/get_topic_names_and_types.h"
#include "rmw/names_and_types.h"
#include "rmw/rmw.h"
#include "rmw/validate_namespace.h"
#include "rmw/validate_node_name.h"

#include "./common.h"

rcl_ret_t
__validate_node_name_and_namespace(
const char * node_name,
const char * node_namespace)
{
int validation_result = 0;
rmw_ret_t rmw_ret = rmw_validate_namespace(node_namespace, &validation_result, NULL);

if (RMW_RET_OK != rmw_ret) {
RCL_SET_ERROR_MSG(rmw_get_error_string().str);
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}
if (validation_result != RMW_NAMESPACE_VALID) {
const char * msg = rmw_namespace_validation_result_string(validation_result);
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING("%s, result: %d", msg, validation_result);
return RCL_RET_NODE_INVALID_NAMESPACE;
}

validation_result = 0;
rmw_ret = rmw_validate_node_name(node_name, &validation_result, NULL);
if (RMW_RET_OK != rmw_ret) {
RCL_SET_ERROR_MSG(rmw_get_error_string().str);
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}
if (RMW_NODE_NAME_VALID != validation_result) {
const char * msg = rmw_node_name_validation_result_string(validation_result);
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING("%s, result: %d", msg, validation_result);
return RCL_RET_NODE_INVALID_NAME;
}

return RCL_RET_OK;
}

rcl_ret_t
rcl_get_publisher_names_and_types_by_node(
const rcl_node_t * node,
Expand All @@ -51,11 +87,14 @@ rcl_get_publisher_names_and_types_by_node(
if (strlen(node_namespace) > 0) {
valid_namespace = node_namespace;
}
rmw_ret_t rmw_ret;
rmw_ret = rmw_names_and_types_check_zero(topic_names_and_types);
if (rmw_ret != RMW_RET_OK) {
rmw_ret_t rmw_ret = rmw_names_and_types_check_zero(topic_names_and_types);
if (RMW_RET_OK != rmw_ret) {
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}
rcl_ret_t rcl_ret = __validate_node_name_and_namespace(node_name, valid_namespace);
if (RCL_RET_OK != rcl_ret) {
return rcl_ret;
}
rcutils_allocator_t rcutils_allocator = *allocator;
rmw_ret = rmw_get_publisher_names_and_types_by_node(
rcl_node_get_rmw_handle(node),
Expand Down Expand Up @@ -95,6 +134,10 @@ rcl_get_subscriber_names_and_types_by_node(
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}
rcutils_allocator_t rcutils_allocator = *allocator;
rcl_ret_t rcl_ret = __validate_node_name_and_namespace(node_name, valid_namespace);
if (RCL_RET_OK != rcl_ret) {
return rcl_ret;
}
rmw_ret = rmw_get_subscriber_names_and_types_by_node(
rcl_node_get_rmw_handle(node),
&rcutils_allocator,
Expand Down Expand Up @@ -131,6 +174,10 @@ rcl_get_service_names_and_types_by_node(
if (rmw_ret != RMW_RET_OK) {
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}
rcl_ret_t rcl_ret = __validate_node_name_and_namespace(node_name, valid_namespace);
if (RCL_RET_OK != rcl_ret) {
return rcl_ret;
}
rcutils_allocator_t rcutils_allocator = *allocator;
rmw_ret = rmw_get_service_names_and_types_by_node(
rcl_node_get_rmw_handle(node),
Expand Down Expand Up @@ -167,6 +214,10 @@ rcl_get_client_names_and_types_by_node(
if (rmw_ret != RMW_RET_OK) {
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
}
rcl_ret_t rcl_ret = __validate_node_name_and_namespace(node_name, valid_namespace);
if (RCL_RET_OK != rcl_ret) {
return rcl_ret;
}
rcutils_allocator_t rcutils_allocator = *allocator;
rmw_ret = rmw_get_client_names_and_types_by_node(
rcl_node_get_rmw_handle(node),
Expand Down
48 changes: 29 additions & 19 deletions rcl/test/rcl/test_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ TEST_F(
rcl_allocator_t zero_allocator = static_cast<rcl_allocator_t>(
rcutils_get_zero_initialized_allocator());
rcl_node_t zero_node = rcl_get_zero_initialized_node();
const char * unknown_node_name = "/test_rcl_get_publisher_names_and_types_by_node";
const char * unknown_node_name = "test_rcl_get_publisher_names_and_types_by_node";
const char * unknown_node_ns = "/test/namespace";
rcl_names_and_types_t nat = rcl_get_zero_initialized_names_and_types();
// invalid node
Expand Down Expand Up @@ -311,15 +311,15 @@ TEST_F(
// test valid strings with invalid node names
ret = rcl_get_publisher_names_and_types_by_node(
this->node_ptr, &allocator, false, "", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_publisher_names_and_types_by_node(
this->node_ptr, &allocator, false, "_InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
this->node_ptr, &allocator, false, "_!InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_publisher_names_and_types_by_node(
this->node_ptr, &allocator, false, this->test_graph_node_name, "_!invalidNs", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret) << rcl_get_error_string().str;
rcl_reset_error();
// invalid names and types
ret = rcl_get_publisher_names_and_types_by_node(
Expand Down Expand Up @@ -359,7 +359,7 @@ TEST_F(
rcl_allocator_t zero_allocator = static_cast<rcl_allocator_t>(
rcutils_get_zero_initialized_allocator());
rcl_node_t zero_node = rcl_get_zero_initialized_node();
const char * unknown_node_name = "/test_rcl_get_subscriber_names_and_types_by_node";
const char * unknown_node_name = "test_rcl_get_subscriber_names_and_types_by_node";
const char * unknown_node_ns = "/test/namespace";
rcl_names_and_types_t nat = rcl_get_zero_initialized_names_and_types();
// invalid node
Expand Down Expand Up @@ -396,15 +396,15 @@ TEST_F(
// test valid strings with invalid node names
ret = rcl_get_subscriber_names_and_types_by_node(
this->node_ptr, &allocator, false, "", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_subscriber_names_and_types_by_node(
this->node_ptr, &allocator, false, "_InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
this->node_ptr, &allocator, false, "_!InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_subscriber_names_and_types_by_node(
this->node_ptr, &allocator, false, this->test_graph_node_name, "_!invalidNs", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret) << rcl_get_error_string().str;
rcl_reset_error();
// invalid names and types
ret = rcl_get_subscriber_names_and_types_by_node(
Expand Down Expand Up @@ -441,7 +441,7 @@ TEST_F(
rcl_allocator_t zero_allocator = static_cast<rcl_allocator_t>(
rcutils_get_zero_initialized_allocator());
rcl_node_t zero_node = rcl_get_zero_initialized_node();
const char * unknown_node_name = "/test_rcl_get_service_names_and_types_by_node";
const char * unknown_node_name = "test_rcl_get_service_names_and_types_by_node";
const char * unknown_node_ns = "/test/namespace";
rcl_names_and_types_t nat = rcl_get_zero_initialized_names_and_types();
// invalid node
Expand Down Expand Up @@ -478,15 +478,15 @@ TEST_F(
// test valid strings with invalid node names
ret = rcl_get_service_names_and_types_by_node(
this->node_ptr, &allocator, "", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_service_names_and_types_by_node(
this->node_ptr, &allocator, "_InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
this->node_ptr, &allocator, "_!InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_service_names_and_types_by_node(
this->node_ptr, &allocator, this->test_graph_node_name, "_!invalidNs", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret) << rcl_get_error_string().str;
rcl_reset_error();
// invalid names and types
ret = rcl_get_service_names_and_types_by_node(
Expand Down Expand Up @@ -523,7 +523,8 @@ TEST_F(
rcl_allocator_t zero_allocator = static_cast<rcl_allocator_t>(
rcutils_get_zero_initialized_allocator());
rcl_node_t zero_node = rcl_get_zero_initialized_node();
const char * unknown_node_name = "/test_rcl_get_client_names_and_types_by_node";
const char * unknown_node_name = "test_rcl_get_client_names_and_types_by_node";
const char * unknown_node_ns = "/test/namespace";
rcl_names_and_types_t nat = rcl_get_zero_initialized_names_and_types();
// invalid node
ret = rcl_get_client_names_and_types_by_node(
Expand Down Expand Up @@ -559,11 +560,15 @@ TEST_F(
// test valid strings with invalid node names
ret = rcl_get_client_names_and_types_by_node(
this->node_ptr, &allocator, "", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_client_names_and_types_by_node(
this->node_ptr, &allocator, "_InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
this->node_ptr, &allocator, "_!InvalidNodeName", "", &nat);
EXPECT_EQ(RCL_RET_NODE_INVALID_NAME, ret) << rcl_get_error_string().str;
rcl_reset_error();
ret = rcl_get_client_names_and_types_by_node(
this->node_ptr, &allocator, this->test_graph_node_name, "_!invalidNs", &nat);
EXPECT_EQ(RCL_RET_NODE_INVALID_NAMESPACE, ret) << rcl_get_error_string().str;
rcl_reset_error();
// invalid names and types
ret = rcl_get_client_names_and_types_by_node(
Expand All @@ -575,6 +580,11 @@ TEST_F(
this->node_ptr, &allocator, unknown_node_name, "", &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
rcl_reset_error();
// unknown node namespace
ret = rcl_get_client_names_and_types_by_node(
this->node_ptr, &allocator, this->test_graph_node_name, unknown_node_ns, &nat);
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
rcl_reset_error();
// valid call
ret = rcl_get_client_names_and_types_by_node(
this->node_ptr, &allocator, this->test_graph_node_name, "", &nat);
Expand Down

0 comments on commit 17598ff

Please sign in to comment.