Skip to content

Commit 2740a43

Browse files
authored
Enforce -r/--remap flags. (ros2#491)
* Enforce -r/--remap flags. Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com> * Cast size_t to int explicitly. Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
1 parent 6f98943 commit 2740a43

File tree

5 files changed

+148
-141
lines changed

5 files changed

+148
-141
lines changed

rcl/include/rcl/arguments.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,38 @@ rcl_get_zero_initialized_arguments(void);
5757

5858
/// Parse command line arguments into a structure usable by code.
5959
/**
60-
* If an argument does not appear to be a valid ROS argument then it is skipped
61-
* and parsing continues with the next argument in `argv`.
62-
*
6360
* \sa rcl_get_zero_initialized_arguments()
64-
* \sa rcl_arguments_get_count_unparsed()
65-
* \sa rcl_arguments_get_unparsed()
6661
*
62+
* ROS arguments are expected to be scoped by a leading `--ros-args` flag and a trailing double
63+
* dash token `--` which may be elided if no non-ROS arguments follow after the last `--ros-args`.
64+
*
65+
* Remap rule parsing is supported via `-r/--remap` flags e.g. `--remap from:=to` or `-r from:=to`.
6766
* Successfully parsed remap rules are stored in the order they were given in `argv`.
6867
* If given arguments `{"__ns:=/foo", "__ns:=/bar"}` then the namespace used by nodes in this
6968
* process will be `/foo` and not `/bar`.
7069
*
70+
* \sa rcl_remap_topic_name()
71+
* \sa rcl_remap_service_name()
72+
* \sa rcl_remap_node_name()
73+
* \sa rcl_remap_node_namespace()
74+
*
75+
* Parameter override rule parsing is supported via `-p/--param` flags e.g. `--param name:=value`
76+
* or `-p name:=value`.
77+
*
7178
* The default log level will be parsed as `__log_level:=level`, where `level` is a name
7279
* representing one of the log levels in the `RCUTILS_LOG_SEVERITY` enum, e.g. `info`, `debug`,
7380
* `warn`, not case sensitive.
7481
* If multiple of these rules are found, the last one parsed will be used.
7582
*
76-
* \sa rcl_remap_topic_name()
77-
* \sa rcl_remap_service_name()
78-
* \sa rcl_remap_node_name()
79-
* \sa rcl_remap_node_namespace()
83+
* If an argument does not appear to be a known ROS argument, then it is skipped and left unparsed.
84+
*
85+
* \sa rcl_arguments_get_count_unparsed_ros()
86+
* \sa rcl_arguments_get_unparsed_ros()
87+
*
88+
* All arguments found outside a `--ros-args ... --` scope are skipped and left unparsed.
89+
*
90+
* \sa rcl_arguments_get_count_unparsed()
91+
* \sa rcl_arguments_get_unparsed()
8092
*
8193
* <hr>
8294
* Attribute | Adherence

rcl/src/rcl/arguments.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -364,18 +364,6 @@ rcl_parse_arguments(
364364
rcl_get_error_string().str);
365365
rcl_reset_error();
366366

367-
// Attempt to parse argument as remap rule
368-
rcl_remap_t * rule = &(args_impl->remap_rules[args_impl->num_remap_rules]);
369-
*rule = rcl_get_zero_initialized_remap();
370-
if (RCL_RET_OK == _rcl_parse_remap_rule(argv[i], allocator, rule)) {
371-
++(args_impl->num_remap_rules);
372-
continue;
373-
}
374-
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME,
375-
"Couldn't parse arg %d (%s) as remap rule. Error: %s", i, argv[i],
376-
rcl_get_error_string().str);
377-
rcl_reset_error();
378-
379367
// Attempt to parse argument as log level configuration
380368
int log_level;
381369
if (RCL_RET_OK == _rcl_parse_log_level_rule(argv[i], allocator, &log_level)) {

rcl/test/rcl/test_arguments.cpp

Lines changed: 74 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ class CLASSNAME (TestArgumentsFixture, RMW_IMPLEMENTATION) : public ::testing::T
104104
} while (0)
105105

106106
bool
107-
are_valid_ros_args(int argc, std::vector<const char *> argv)
107+
are_known_ros_args(std::vector<const char *> argv)
108108
{
109+
const int argc = static_cast<int>(argv.size());
109110
rcl_arguments_t parsed_args = rcl_get_zero_initialized_arguments();
110111
rcl_ret_t ret = rcl_parse_arguments(
111112
argc, argv.data(), rcl_get_default_allocator(), &parsed_args);
@@ -117,74 +118,80 @@ are_valid_ros_args(int argc, std::vector<const char *> argv)
117118
return is_valid;
118119
}
119120

120-
TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), check_valid_vs_invalid_args) {
121-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "__node:=node_name"}));
122-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "old_name:__node:=node_name"}));
123-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "old_name:__node:=nodename123"}));
124-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "__node:=nodename123"}));
125-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "__ns:=/foo/bar"}));
126-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "__ns:=/"}));
127-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "_:=kq"}));
128-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "nodename:__ns:=/foobar"}));
129-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "foo:=bar"}));
130-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "~/foo:=~/bar"}));
131-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "/foo/bar:=bar"}));
132-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "foo:=/bar"}));
133-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "/foo123:=/bar123"}));
134-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "node:/foo123:=/bar123"}));
135-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "rostopic:=/foo/bar"}));
136-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "rosservice:=baz"}));
137-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "rostopic://rostopic:=rosservice"}));
138-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "rostopic:///rosservice:=rostopic"}));
139-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-r", "rostopic:///foo/bar:=baz"}));
140-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-p", "foo:=bar"}));
141-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-p", "~/foo:=~/bar"}));
142-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-p", "/foo/bar:=bar"}));
143-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-p", "foo:=/bar"}));
144-
EXPECT_TRUE(are_valid_ros_args(3, {"--ros-args", "-p", "/foo123:=/bar123"}));
145-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__params:=file_name.yaml"}));
146-
147-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", ":="}));
148-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "foo:="}));
149-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", ":=bar"}));
150-
151-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-p", ":="}));
152-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-p", "foo:="}));
153-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-p", ":=bar"}));
154-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "__ns:="}));
155-
156-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "__node:="}));
157-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "__node:=/foo/bar"}));
158-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "__ns:=foo"}));
159-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", ":__node:=nodename"}));
160-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "~:__node:=nodename"}));
161-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "}foo:=/bar"}));
162-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "f oo:=/bar"}));
163-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "foo:=/b ar"}));
164-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "f{oo:=/bar"}));
165-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "foo:=/b}ar"}));
166-
167-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-p", "}foo:=/bar"}));
168-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-p", "f oo:=/bar"}));
169-
170-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "rostopic://:=rosservice"}));
171-
EXPECT_FALSE(are_valid_ros_args(3, {"--ros-args", "-r", "rostopic::=rosservice"}));
172-
EXPECT_FALSE(are_valid_ros_args(2, {"--ros-args", "__param:=file_name.yaml"}));
121+
TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), check_known_vs_unknown_args) {
122+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "__node:=node_name"}));
123+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "old_name:__node:=node_name"}));
124+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "old_name:__node:=nodename123"}));
125+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "__node:=nodename123"}));
126+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "__ns:=/foo/bar"}));
127+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "__ns:=/"}));
128+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "_:=kq"}));
129+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "nodename:__ns:=/foobar"}));
130+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "foo:=bar"}));
131+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "~/foo:=~/bar"}));
132+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "/foo/bar:=bar"}));
133+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "foo:=/bar"}));
134+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "/foo123:=/bar123"}));
135+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "node:/foo123:=/bar123"}));
136+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:=/foo/bar"}));
137+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rosservice:=baz"}));
138+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic://rostopic:=rosservice"}));
139+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:///rosservice:=rostopic"}));
140+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-r", "rostopic:///foo/bar:=baz"}));
141+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo:=bar"}));
142+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "~/foo:=~/bar"}));
143+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "/foo/bar:=bar"}));
144+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "foo:=/bar"}));
145+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "-p", "/foo123:=/bar123"}));
146+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__params:=file_name.yaml"}));
147+
148+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r"}));
149+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "--remap"}));
150+
151+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", ":="}));
152+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "foo:="}));
153+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", ":=bar"}));
154+
155+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-p"}));
156+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "--param"}));
157+
158+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-p", ":="}));
159+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-p", "foo:="}));
160+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-p", ":=bar"}));
161+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "__ns:="}));
162+
163+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "__node:="}));
164+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "__node:=/foo/bar"}));
165+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "__ns:=foo"}));
166+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", ":__node:=nodename"}));
167+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "~:__node:=nodename"}));
168+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "}foo:=/bar"}));
169+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "f oo:=/bar"}));
170+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "foo:=/b ar"}));
171+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "f{oo:=/bar"}));
172+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "foo:=/b}ar"}));
173+
174+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-p", "}foo:=/bar"}));
175+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-p", "f oo:=/bar"}));
176+
177+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "rostopic://:=rosservice"}));
178+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "-r", "rostopic::=rosservice"}));
179+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "__param:=file_name.yaml"}));
173180

174181
// Setting logger level
175-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=UNSET"}));
176-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=DEBUG"}));
177-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=INFO"}));
178-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=WARN"}));
179-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=ERROR"}));
180-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=FATAL"}));
181-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=debug"}));
182-
EXPECT_TRUE(are_valid_ros_args(2, {"--ros-args", "__log_level:=Info"}));
183-
184-
EXPECT_FALSE(are_valid_ros_args(2, {"--ros-args", "__log:=foo"}));
185-
EXPECT_FALSE(are_valid_ros_args(2, {"--ros-args", "__loglevel:=foo"}));
186-
EXPECT_FALSE(are_valid_ros_args(2, {"--ros-args", "__log_level:="}));
187-
EXPECT_FALSE(are_valid_ros_args(2, {"--ros-args", "__log_level:=foo"}));
182+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=UNSET"}));
183+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=DEBUG"}));
184+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=INFO"}));
185+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=WARN"}));
186+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=ERROR"}));
187+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=FATAL"}));
188+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=debug"}));
189+
EXPECT_TRUE(are_known_ros_args({"--ros-args", "__log_level:=Info"}));
190+
191+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "__log:=foo"}));
192+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "__loglevel:=foo"}));
193+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "__log_level:="}));
194+
EXPECT_FALSE(are_known_ros_args({"--ros-args", "__log_level:=foo"}));
188195
}
189196

190197
TEST_F(CLASSNAME(TestArgumentsFixture, RMW_IMPLEMENTATION), test_no_args) {

0 commit comments

Comments
 (0)