Summary
The callback generated by redis_event_handler! converts the event name with to_str().unwrap(). A keyspace event whose name is not valid UTF-8 panics inside the generated handler, before the module author's handler runs.
Location
src/macros.rs line 132 (master, 7fb620f):
let event_str = unsafe { CStr::from_ptr(event) };
$event_handler(
&context,
$crate::NotifyEvent::from_bits_truncate(event_type),
event_str.to_str().unwrap(),
redis_key,
);
Reproduction path
Any co-loaded module can fire an arbitrary event name via RedisModule_NotifyKeyspaceEvent (the API takes a C string, so anything NUL-free is possible, including invalid UTF-8 byte sequences). A module built on this crate that subscribes with event_handlers: or redis_event_handler! then panics inside the generated extern "C" callback. A panic across an FFI boundary into Redis is undefined behavior in older Rust editions and at best aborts the server process.
Built-in event names are ASCII, so this does not trigger in normal operation; the exposure is a hostile or buggy co-loaded module taking down the server through any subscriber built on this crate.
Suggested fix
Either of:
- Lossy decode:
String::from_utf8_lossy(event_str.to_bytes()), passing &str as today with replacement characters for invalid sequences. Non-breaking for handler signatures.
- Bytes-based handler signature (
&[u8] for the event name, matching how the key is already passed as &[u8]). Breaking, but consistent with the key parameter.
The lossy decode is a two-line change and preserves the public API.
Summary
The callback generated by
redis_event_handler!converts the event name withto_str().unwrap(). A keyspace event whose name is not valid UTF-8 panics inside the generated handler, before the module author's handler runs.Location
src/macros.rsline 132 (master, 7fb620f):Reproduction path
Any co-loaded module can fire an arbitrary event name via
RedisModule_NotifyKeyspaceEvent(the API takes a C string, so anything NUL-free is possible, including invalid UTF-8 byte sequences). A module built on this crate that subscribes withevent_handlers:orredis_event_handler!then panics inside the generatedextern "C"callback. A panic across an FFI boundary into Redis is undefined behavior in older Rust editions and at best aborts the server process.Built-in event names are ASCII, so this does not trigger in normal operation; the exposure is a hostile or buggy co-loaded module taking down the server through any subscriber built on this crate.
Suggested fix
Either of:
String::from_utf8_lossy(event_str.to_bytes()), passing&stras today with replacement characters for invalid sequences. Non-breaking for handler signatures.&[u8]for the event name, matching how the key is already passed as&[u8]). Breaking, but consistent with the key parameter.The lossy decode is a two-line change and preserves the public API.