Skip to content

Commit 04d16f2

Browse files
Merge pull request #61 from benaliabderrahmane/fix/event-init-reject-unsupported
fix(rmw_event): reject unsupported event types in *_event_init
2 parents db652db + 7e39aa3 commit 04d16f2

3 files changed

Lines changed: 99 additions & 0 deletions

File tree

‎rmw_unix_socket_cpp/CMakeLists.txt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ if(BUILD_TESTING)
211211
target_link_libraries(test_rmw_qos ${_rmw_test_libs} ${_test_msg_deps})
212212
target_include_directories(test_rmw_qos PRIVATE src)
213213

214+
# RMW API: publisher/subscription events
215+
ament_add_gtest(test_rmw_event test/test_rmw_event.cpp)
216+
target_link_libraries(test_rmw_event ${_rmw_test_libs} ${_test_msg_deps})
217+
target_include_directories(test_rmw_event PRIVATE src)
218+
214219
# Integration: fork()-based two-process tests pushing >4 MB payloads across
215220
# a real PID boundary through the shared-memory path.
216221
ament_add_gtest(test_rmw_cross_process test/test_rmw_cross_process.cpp)

‎rmw_unix_socket_cpp/src/rmw_event.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ rmw_ret_t rmw_publisher_event_init(
2929
{
3030
RMW_CHECK_ARGUMENT_FOR_NULL(rmw_event, RMW_RET_INVALID_ARGUMENT);
3131
RMW_CHECK_ARGUMENT_FOR_NULL(publisher, RMW_RET_INVALID_ARGUMENT);
32+
if (!rmw_event_type_is_supported(event_type)) {
33+
RMW_SET_ERROR_MSG("event type not supported");
34+
return RMW_RET_UNSUPPORTED;
35+
}
3236
// Initialize the event struct so rcl can add it to a wait set without crashing.
3337
// We don't actually generate events, but the struct must be valid.
3438
rmw_event->implementation_identifier = rmw_uds::identifier;
@@ -44,6 +48,10 @@ rmw_ret_t rmw_subscription_event_init(
4448
{
4549
RMW_CHECK_ARGUMENT_FOR_NULL(rmw_event, RMW_RET_INVALID_ARGUMENT);
4650
RMW_CHECK_ARGUMENT_FOR_NULL(subscription, RMW_RET_INVALID_ARGUMENT);
51+
if (!rmw_event_type_is_supported(event_type)) {
52+
RMW_SET_ERROR_MSG("event type not supported");
53+
return RMW_RET_UNSUPPORTED;
54+
}
4755
rmw_event->implementation_identifier = rmw_uds::identifier;
4856
rmw_event->data = subscription->data;
4957
rmw_event->event_type = event_type;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2026 Abderahmane BENALI
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "test_base.hpp"
16+
17+
#include <cstring>
18+
19+
#include "test_msgs/msg/basic_types.hpp"
20+
21+
#include "rmw/event.h"
22+
#include "rmw/qos_profiles.h"
23+
#include "rosidl_typesupport_cpp/message_type_support.hpp"
24+
25+
class EventTest : public RmwUdsNodeTest
26+
{
27+
protected:
28+
rmw_publisher_t * pub = nullptr;
29+
rmw_subscription_t * sub = nullptr;
30+
const rosidl_message_type_support_t * ts = nullptr;
31+
rmw_qos_profile_t qos;
32+
33+
void SetUp() override
34+
{
35+
RmwUdsNodeTest::SetUp();
36+
ts = rosidl_typesupport_cpp::get_message_type_support_handle<
37+
test_msgs::msg::BasicTypes>();
38+
std::memset(&qos, 0, sizeof(qos));
39+
qos.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
40+
qos.depth = 10;
41+
qos.reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
42+
qos.durability = RMW_QOS_POLICY_DURABILITY_VOLATILE;
43+
44+
auto pub_opts = rmw_get_default_publisher_options();
45+
pub = rmw_create_publisher(node, ts, "/event_test_topic", &qos, &pub_opts);
46+
ASSERT_NE(nullptr, pub);
47+
48+
auto sub_opts = rmw_get_default_subscription_options();
49+
sub = rmw_create_subscription(node, ts, "/event_test_topic", &qos, &sub_opts);
50+
ASSERT_NE(nullptr, sub);
51+
}
52+
53+
void TearDown() override
54+
{
55+
if (sub) { auto _r [[maybe_unused]] = rmw_destroy_subscription(node, sub); }
56+
if (pub) { auto _r [[maybe_unused]] = rmw_destroy_publisher(node, pub); }
57+
RmwUdsNodeTest::TearDown();
58+
}
59+
};
60+
61+
// rmw_event_type_is_supported() reports no event types as supported, so
62+
// rclcpp expects *_event_init() to fail with RMW_RET_UNSUPPORTED for those
63+
// event types (it only swallows initialization failures reported this way,
64+
// via UnsupportedEventTypeException). If init instead reports success,
65+
// rclcpp constructs a live event handler for it, and the failure only
66+
// surfaces later - unhandled - when the executor registers its callback,
67+
// crashing with "failed to set the on new message callback for Event".
68+
TEST_F(EventTest, SubscriptionEventInitRejectsUnsupportedEventType)
69+
{
70+
ASSERT_FALSE(rmw_event_type_is_supported(RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE));
71+
72+
rmw_event_t event = rmw_get_zero_initialized_event();
73+
EXPECT_EQ(
74+
RMW_RET_UNSUPPORTED,
75+
rmw_subscription_event_init(&event, sub, RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE));
76+
}
77+
78+
TEST_F(EventTest, PublisherEventInitRejectsUnsupportedEventType)
79+
{
80+
ASSERT_FALSE(rmw_event_type_is_supported(RMW_EVENT_OFFERED_QOS_INCOMPATIBLE));
81+
82+
rmw_event_t event = rmw_get_zero_initialized_event();
83+
EXPECT_EQ(
84+
RMW_RET_UNSUPPORTED,
85+
rmw_publisher_event_init(&event, pub, RMW_EVENT_OFFERED_QOS_INCOMPATIBLE));
86+
}

0 commit comments

Comments
 (0)