From ba4d05f9ddf188dd08dd98b1d9a54343c6f1bf50 Mon Sep 17 00:00:00 2001 From: Campbell Jones Date: Fri, 12 Apr 2024 18:48:39 -0400 Subject: [PATCH] Short-circuit if missing data in event listeners Instead of segfaulting, of course --- src/foreign_toplevel.cpp | 26 +++++++++++++- src/input/cursor.cpp | 66 +++++++++++++++++++++++++++++++++++ src/input/keyboard.cpp | 9 +++-- src/input/seat.cpp | 30 ++++++++++++++++ src/output.cpp | 6 ++++ src/server.cpp | 39 +++++++++++++++++++-- src/surface/layer.cpp | 10 ++++++ src/surface/popup.cpp | 9 +++++ src/surface/xdg_view.cpp | 6 ++++ src/surface/xwayland_view.cpp | 11 ++++++ src/xwayland.cpp | 5 +++ 11 files changed, 212 insertions(+), 5 deletions(-) diff --git a/src/foreign_toplevel.cpp b/src/foreign_toplevel.cpp index baa2ddfb4..0dd215b27 100644 --- a/src/foreign_toplevel.cpp +++ b/src/foreign_toplevel.cpp @@ -1,10 +1,19 @@ #include "foreign_toplevel.hpp" - #include "output.hpp" + #include "server.hpp" #include "surface/view.hpp" +#include "wlr-wrap-start.hpp" +#include +#include "wlr-wrap-end.hpp" + static void foreign_toplevel_handle_request_maximize_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_foreign_toplevel_handle_v1.events.request_maximize"); + return; + } + const ForeignToplevelHandle& handle = magpie_container_of(listener, handle, request_activate); const auto& event = *static_cast(data); @@ -13,6 +22,11 @@ static void foreign_toplevel_handle_request_maximize_notify(wl_listener* listene } static void foreign_toplevel_handle_request_fullscreen_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_foreign_toplevel_handle_v1.events.request_fullscreen"); + return; + } + const ForeignToplevelHandle& handle = magpie_container_of(listener, handle, request_activate); const auto& event = *static_cast(data); @@ -21,6 +35,11 @@ static void foreign_toplevel_handle_request_fullscreen_notify(wl_listener* liste } static void foreign_toplevel_handle_request_minimize_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_foreign_toplevel_handle_v1.events.request_minimize"); + return; + } + const ForeignToplevelHandle& handle = magpie_container_of(listener, handle, request_activate); const auto& event = *static_cast(data); @@ -41,6 +60,11 @@ static void foreign_toplevel_handle_request_close_notify(wl_listener* listener, } static void foreign_toplevel_handle_set_rectangle_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_foreign_toplevel_handle_v1.events.set_rectangle"); + return; + } + const ForeignToplevelHandle& handle = magpie_container_of(listener, handle, set_rectangle); const auto& event = *static_cast(data); diff --git a/src/input/cursor.cpp b/src/input/cursor.cpp index 8b3cd0102..0e4be5233 100644 --- a/src/input/cursor.cpp +++ b/src/input/cursor.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "wlr-wrap-end.hpp" void Cursor::process_resize(const uint32_t time) const { @@ -93,6 +94,11 @@ void Cursor::process_move(const uint32_t time) { /* This event is forwarded by the cursor when a pointer emits an axis event, * for example when you move the scroll wheel. */ static void cursor_axis_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.cursor_axis"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, axis); const auto* event = static_cast(data); @@ -119,6 +125,11 @@ static void cursor_frame_notify(wl_listener* listener, void*) { * so we have to warp the mouse there. There is also some hardware which * emits these events. */ static void cursor_motion_absolute_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.motion_absolute"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, motion_absolute); const auto* event = static_cast(data); @@ -142,6 +153,11 @@ static void cursor_motion_absolute_notify(wl_listener* listener, void* data) { /* This event is forwarded by the cursor when a pointer emits a button event. */ static void cursor_button_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.button"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, button); const auto* event = static_cast(data); @@ -170,6 +186,11 @@ static void cursor_button_notify(wl_listener* listener, void* data) { /* This event is forwarded by the cursor when a pointer emits a _relative_ * pointer motion event (i.e. a delta) */ static void cursor_motion_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.motion"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, motion); const auto* event = static_cast(data); @@ -189,6 +210,11 @@ static void cursor_motion_notify(wl_listener* listener, void* data) { } static void gesture_pinch_begin_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.pinch_begin"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_pinch_begin); const auto* event = static_cast(data); @@ -196,6 +222,11 @@ static void gesture_pinch_begin_notify(wl_listener* listener, void* data) { } static void gesture_pinch_update_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.pinch_update"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_pinch_update); const auto* event = static_cast(data); @@ -204,6 +235,11 @@ static void gesture_pinch_update_notify(wl_listener* listener, void* data) { } static void gesture_pinch_end_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.pinch_end"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_pinch_end); const auto* event = static_cast(data); @@ -211,6 +247,11 @@ static void gesture_pinch_end_notify(wl_listener* listener, void* data) { } static void gesture_swipe_begin_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.swipe_begin"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_swipe_begin); const auto* event = static_cast(data); @@ -218,6 +259,11 @@ static void gesture_swipe_begin_notify(wl_listener* listener, void* data) { } static void gesture_swipe_update_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.swipe_update"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_swipe_update); const auto* event = static_cast(data); @@ -225,6 +271,11 @@ static void gesture_swipe_update_notify(wl_listener* listener, void* data) { } static void gesture_swipe_end_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.swipe_end"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_swipe_end); const auto* event = static_cast(data); @@ -232,6 +283,11 @@ static void gesture_swipe_end_notify(wl_listener* listener, void* data) { } static void gesture_hold_begin_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.hold_begin"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_hold_begin); const auto* event = static_cast(data); @@ -239,6 +295,11 @@ static void gesture_hold_begin_notify(wl_listener* listener, void* data) { } static void gesture_hold_end_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.hold_end"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, gesture_hold_end); const auto* event = static_cast(data); @@ -246,6 +307,11 @@ static void gesture_hold_end_notify(wl_listener* listener, void* data) { } static void request_set_shape_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_cursor.events.set_shape"); + return; + } + Cursor& cursor = magpie_container_of(listener, cursor, request_set_shape); const auto* event = static_cast(data); diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp index a7dc0535d..d446e882c 100644 --- a/src/input/keyboard.cpp +++ b/src/input/keyboard.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "wlr-wrap-end.hpp" /* This event is raised by the keyboard base wlr_input_device to signal @@ -61,11 +62,15 @@ static bool handle_compositor_keybinding(const Keyboard& keyboard, const uint32_ /* This event is raised when a key is pressed or released. */ static void keyboard_handle_key(wl_listener* listener, void* data) { - const Keyboard& keyboard = magpie_container_of(listener, keyboard, key); + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_keyboard.events.key"); + return; + } + const Keyboard& keyboard = magpie_container_of(listener, keyboard, key); const auto* event = static_cast(data); - wlr_seat* seat = keyboard.seat.wlr; + wlr_seat* seat = keyboard.seat.wlr; wlr_idle_notifier_v1_notify_activity(keyboard.seat.server.idle_notifier, seat); /* Translate libinput keycode -> xkbcommon */ diff --git a/src/input/seat.cpp b/src/input/seat.cpp index 63737ef7c..17d575ffe 100644 --- a/src/input/seat.cpp +++ b/src/input/seat.cpp @@ -19,6 +19,11 @@ #include "wlr-wrap-end.hpp" static void new_input_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_seat.events.new_input"); + return; + } + Seat& seat = magpie_container_of(listener, seat, new_input); auto* device = static_cast(data); @@ -26,6 +31,11 @@ static void new_input_notify(wl_listener* listener, void* data) { } static void new_virtual_pointer_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_seat.events.new_virtual_pointer"); + return; + } + Seat& seat = magpie_container_of(listener, seat, new_virtual_pointer); const auto* event = static_cast(data); @@ -33,6 +43,11 @@ static void new_virtual_pointer_notify(wl_listener* listener, void* data) { } static void new_virtual_keyboard_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_seat.events.new_virtual_keyboard"); + return; + } + Seat& seat = magpie_container_of(listener, seat, new_virtual_keyboard); auto* keyboard = static_cast(data); @@ -40,6 +55,11 @@ static void new_virtual_keyboard_notify(wl_listener* listener, void* data) { } static void new_pointer_constraint_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_seat.events.new_pointer_constraint"); + return; + } + Seat& seat = magpie_container_of(listener, seat, new_pointer_constraint); auto* wlr_constraint = static_cast(data); @@ -51,6 +71,11 @@ static void new_pointer_constraint_notify(wl_listener* listener, void* data) { } static void request_cursor_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_seat.events.request_cursor"); + return; + } + const Seat& seat = magpie_container_of(listener, seat, request_cursor); const auto* event = static_cast(data); @@ -70,6 +95,11 @@ static void request_cursor_notify(wl_listener* listener, void* data) { * ignore such requests if they so choose, but in magpie we always honor */ static void request_set_selection_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_seat.events.request_set_selection"); + return; + } + const Seat& seat = magpie_container_of(listener, seat, request_set_selection); const auto* event = static_cast(data); diff --git a/src/output.cpp b/src/output.cpp index fbb8e4982..7fb982f3d 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -10,11 +10,17 @@ #include #include #include +#include #include /* This function is called every time an output is ready to display a frame, * generally at the output's refresh rate (e.g. 60Hz). */ static void output_request_state_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_output.events.request_state"); + return; + } + Output& output = magpie_container_of(listener, output, request_state); const auto* event = static_cast(data); diff --git a/src/server.cpp b/src/server.cpp index 10b5bb3c4..5011a64a2 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -120,6 +120,11 @@ Surface* Server::surface_at(const double lx, const double ly, wlr_surface** wlr, /* This event is raised by the backend when a new output (aka a display or * monitor) becomes available. */ static void new_output_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_backend.events.new_output"); + return; + } + Server& server = magpie_container_of(listener, server, backend_new_output); auto* new_output = static_cast(data); @@ -164,6 +169,11 @@ static void new_output_notify(wl_listener* listener, void* data) { } static void output_power_manager_set_mode_notify(wl_listener*, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_output_power_manager.events.set_mode"); + return; + } + const auto& event = *static_cast(data); if (event.mode == ZWLR_OUTPUT_POWER_V1_MODE_ON) { @@ -181,6 +191,11 @@ static void output_power_manager_set_mode_notify(wl_listener*, void* data) { /* This event is raised when wlr_xdg_shell receives a new xdg surface from a * client, either a toplevel (application window) or popup. */ static void new_xdg_surface_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xdg_shell.events.new_surface"); + return; + } + Server& server = magpie_container_of(listener, server, xdg_shell_new_xdg_surface); const auto& xdg_surface = *static_cast(data); @@ -193,6 +208,11 @@ static void new_xdg_surface_notify(wl_listener* listener, void* data) { } static void new_layer_surface_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_layer_shell_v1.events.new_surface"); + return; + } + Server& server = magpie_container_of(listener, server, layer_shell_new_layer_surface); auto& layer_surface = *static_cast(data); @@ -209,6 +229,11 @@ static void new_layer_surface_notify(wl_listener* listener, void* data) { } static void request_activation_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xdg_activation_v1.events.request_activation"); + return; + } + Server& server = magpie_container_of(listener, server, activation_request_activation); const auto* event = static_cast(data); @@ -223,7 +248,12 @@ static void request_activation_notify(wl_listener* listener, void* data) { } } -static void drm_lease_notify(wl_listener* listener, void* data) { +static void drm_lease_request_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_drm_lease_manager_v1.events.drm_lease_request"); + return; + } + Server& server = magpie_container_of(listener, server, drm_lease_request); auto* request = static_cast(data); @@ -269,6 +299,11 @@ void output_layout_change_notify(wl_listener* listener, void*) { } void output_manager_apply_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_output_manager_v1.events.apply"); + return; + } + Server& server = magpie_container_of(listener, server, output_manager_apply); auto& config = *static_cast(data); @@ -446,7 +481,7 @@ Server::Server() : listeners(*this) { drm_manager = wlr_drm_lease_v1_manager_create(display, backend); if (drm_manager != nullptr) { - listeners.drm_lease_request.notify = drm_lease_notify; + listeners.drm_lease_request.notify = drm_lease_request_notify; wl_signal_add(&drm_manager->events.request, &listeners.drm_lease_request); } diff --git a/src/surface/layer.cpp b/src/surface/layer.cpp index d93b666eb..b8c65c283 100644 --- a/src/surface/layer.cpp +++ b/src/surface/layer.cpp @@ -95,6 +95,11 @@ static void wlr_layer_surface_v1_commit_notify(wl_listener* listener, void*) { } static void wlr_layer_surface_v1_new_popup_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_layer_surface_v1.events.new_popup"); + return; + } + Layer& layer = magpie_container_of(listener, layer, new_popup); const auto* surface = static_cast(layer.layer_surface.surface->data); @@ -102,6 +107,11 @@ static void wlr_layer_surface_v1_new_popup_notify(wl_listener* listener, void* d } static void wlr_layer_surface_v1_new_subsurface_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_layer_surface_v1.events.new_subsurface"); + return; + } + Layer& layer = magpie_container_of(listener, layer, new_subsurface); auto& subsurface = *static_cast(data); diff --git a/src/surface/popup.cpp b/src/surface/popup.cpp index fce26eaca..289e76ee8 100644 --- a/src/surface/popup.cpp +++ b/src/surface/popup.cpp @@ -7,6 +7,10 @@ #include +#include "wlr-wrap-start.hpp" +#include +#include "wlr-wrap-end.hpp" + static void popup_map_notify(wl_listener* listener, void*) { Popup& popup = magpie_container_of(listener, popup, map); @@ -31,6 +35,11 @@ static void popup_destroy_notify(wl_listener* listener, void*) { } static void popup_new_popup_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_layer_surface_v1.events.new_popup"); + return; + } + const Popup& popup = magpie_container_of(listener, popup, new_popup); new Popup(popup, *static_cast(data)); diff --git a/src/surface/xdg_view.cpp b/src/surface/xdg_view.cpp index 37986fff9..47058d9dd 100644 --- a/src/surface/xdg_view.cpp +++ b/src/surface/xdg_view.cpp @@ -9,6 +9,7 @@ #include "wlr-wrap-start.hpp" #include +#include #include "wlr-wrap-end.hpp" /* Called when the surface is mapped, or ready to display on-screen. */ @@ -51,6 +52,11 @@ static void xdg_toplevel_request_move_notify(wl_listener* listener, void*) { * provided serial against a list of button press serials sent to this * client, to prevent the client from requesting this whenever they want. */ static void xdg_toplevel_request_resize_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xdg_toplevel.events.request_resize"); + return; + } + XdgView& view = magpie_container_of(listener, view, request_resize); const auto* event = static_cast(data); diff --git a/src/surface/xwayland_view.cpp b/src/surface/xwayland_view.cpp index 992a394a5..72e410b2d 100644 --- a/src/surface/xwayland_view.cpp +++ b/src/surface/xwayland_view.cpp @@ -12,6 +12,7 @@ #include "wlr-wrap-start.hpp" #include +#include #include "wlr-wrap-end.hpp" /* Called when the surface is mapped, or ready to display on-screen. */ @@ -53,6 +54,11 @@ static void xwayland_surface_destroy_notify(wl_listener* listener, void*) { } static void xwayland_surface_request_configure_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xwayland_surface.events.request_configure"); + return; + } + XWaylandView& view = magpie_container_of(listener, view, request_configure); const auto& event = *static_cast(data); @@ -89,6 +95,11 @@ static void xwayland_surface_request_move_notify(wl_listener* listener, void*) { * provided serial against a list of button press serials sent to this * client, to prevent the client from requesting this whenever they want. */ static void xwayland_surface_request_resize_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xwayland_surface.events.request_resize"); + return; + } + XWaylandView& view = magpie_container_of(listener, view, request_resize); const auto* event = static_cast(data); diff --git a/src/xwayland.cpp b/src/xwayland.cpp index 24d100fb1..e26bb5e87 100644 --- a/src/xwayland.cpp +++ b/src/xwayland.cpp @@ -57,6 +57,11 @@ static void ready_notify(wl_listener* listener, void*) { } static void new_surface_notify(wl_listener* listener, void* data) { + if (data == nullptr) { + wlr_log(WLR_ERROR, "No data passed to wlr_xwayland.events.new_surface"); + return; + } + XWayland& xwayland = magpie_container_of(listener, xwayland, new_surface); auto& xwayland_surface = *static_cast(data);