diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 13:18:53 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 13:18:53 +0300 |
| commit | 87d0bc50d53dc216efb2b04495f090616318bc5c (patch) | |
| tree | 9d86e4f49631b06875bd51f8f51410370cebe435 /tests/wayland/test_app_input.c | |
| parent | 71091ca35176f62469311fbf02f6e9333b5f6f0b (diff) | |
test(app): destroy a surface from its input event callback
The test pushes two key events into a Wayland surface's queue. The
first event's callback destroys the surface. The run must end cleanly,
without delivering the second event. Before 71091ca, ASan reported a
heap-use-after-free in app_runner_dispatch_input_events. The test
skips when WAYLAND_DISPLAY is unset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tests/wayland/test_app_input.c')
| -rw-r--r-- | tests/wayland/test_app_input.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/tests/wayland/test_app_input.c b/tests/wayland/test_app_input.c new file mode 100644 index 0000000..24b8b64 --- /dev/null +++ b/tests/wayland/test_app_input.c @@ -0,0 +1,60 @@ +/* An input event callback that destroys its own surface. The app runner + * must not touch the surface's entry after the callback, and must not + * deliver the surface's remaining input. Needs a Wayland compositor. */ +#include "wayland/internal.h" +#include "yasl/app.h" + +#include <assert.h> +#include <stdlib.h> + +struct test_state { + int keys; +}; + +static void push_key(struct yasl_surface *s) +{ + struct yasl_input_event ev = { + .surface = s, + .kind = YASL_INPUT_KEY, + .key = { .key = YASL_KEY_A, .action = YASL_KEY_PRESS }, + }; + assert(input_queue_push(&((struct wayland_surface *)s)->input, &ev)); +} + +static int on_init(void *ud, struct yasl_display *d) +{ + (void)ud; + struct yasl_surface *s = yasl_surface_create_toplevel(d, + &(struct yasl_surface_spec){ .title = "App Input Test", .size = {64, 64} }); + assert(s); + push_key(s); + push_key(s); + return YASL_APP_CONTINUE; +} + +static int on_event(void *ud, const struct yasl_event *ev) +{ + struct test_state *state = ud; + if (ev->type == YASL_EVENT_KEY) { + state->keys++; + yasl_surface_destroy(ev->surface); + } + return YASL_APP_CONTINUE; +} + +int main(void) +{ + if (!getenv("WAYLAND_DISPLAY")) + return 77; + struct test_state state = {0}; + int res = yasl_run(&(struct yasl_app_desc){ + .app_id = "org.yasl.test.app-input", + .backend = YASL_BACKEND_WAYLAND, + .userdata = &state, + .init = on_init, + .event = on_event, + }); + assert(res == 0); + assert(state.keys == 1); + return 0; +} |
