From b33feb1006a428b9ee35f71e4d5f73d3b9891174 Mon Sep 17 00:00:00 2001 From: Jacob Perron Date: Fri, 26 Mar 2021 09:27:28 -0700 Subject: [PATCH] Guard against returning NULL or empty node names (#570) Return an error instead. Signed-off-by: Jacob Perron * Update documentation Signed-off-by: Jacob Perron * Separate error messages for null vs empty Signed-off-by: Jacob Perron * Guard against null namespaces Signed-off-by: Jacob Perron * Use more specific error codes Signed-off-by: Jacob Perron --- rcl/include/rcl/graph.h | 3 ++- rcl/src/rcl/graph.c | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rcl/include/rcl/graph.h b/rcl/include/rcl/graph.h index 9392573e1..50d6fb526 100644 --- a/rcl/include/rcl/graph.h +++ b/rcl/include/rcl/graph.h @@ -406,7 +406,6 @@ rcl_names_and_types_fini(rcl_names_and_types_t * names_and_types); * * The `node_names` parameter must be allocated and zero initialized. * `node_names` is the output for this function, and contains allocated memory. - * Note that entries in the array might contain `NULL` values. * Use rcutils_get_zero_initialized_string_array() for initializing an empty * rcutils_string_array_t struct. * This `node_names` struct should therefore be passed to rcutils_string_array_fini() @@ -445,6 +444,8 @@ rcl_names_and_types_fini(rcl_names_and_types_t * names_and_types); * \return #RCL_RET_OK if the query was successful, or * \return #RCL_RET_BAD_ALLOC if an error occurred while allocating memory, or * \return #RCL_RET_INVALID_ARGUMENT if any arguments are invalid, or + * \return #RCL_RET_NODE_INVALID_NAME if a node with an invalid name is detected, or + * \return #RCL_RET_NODE_INVALID_NAMESPACE if a node with an invalid namespace is detected, or * \return #RCL_RET_ERROR if an unspecified error occurs. */ RCL_PUBLIC diff --git a/rcl/src/rcl/graph.c b/rcl/src/rcl/graph.c index 6712da10b..225b938d6 100644 --- a/rcl/src/rcl/graph.c +++ b/rcl/src/rcl/graph.c @@ -341,7 +341,30 @@ rcl_get_node_names( rcl_node_get_rmw_handle(node), node_names, node_namespaces); - return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret); + + if (RMW_RET_OK != rmw_ret) { + return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret); + } + + // Check that none of the node names are NULL or empty + for (size_t i = 0u; i < node_names->size; ++i) { + if (!node_names->data[i]) { + RCL_SET_ERROR_MSG("NULL node name returned by the RMW layer"); + return RCL_RET_NODE_INVALID_NAME; + } + if (!strcmp(node_names->data[i], "")) { + RCL_SET_ERROR_MSG("empty node name returned by the RMW layer"); + return RCL_RET_NODE_INVALID_NAME; + } + } + // Check that none of the node namespaces are NULL + for (size_t i = 0u; i < node_namespaces->size; ++i) { + if (!node_namespaces->data[i]) { + RCL_SET_ERROR_MSG("NULL node namespace returned by the RMW layer"); + return RCL_RET_NODE_INVALID_NAMESPACE; + } + } + return RCL_RET_OK; } rcl_ret_t