From 624d1371304a5ae4b3429ad5e4267aac7cd03dfd Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 00:09:38 +0300 Subject: missing impls and hardening --- src/common/backend.c | 57 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'src/common/backend.c') diff --git a/src/common/backend.c b/src/common/backend.c index 2220f1f..214854b 100644 --- a/src/common/backend.c +++ b/src/common/backend.c @@ -113,14 +113,18 @@ int yasl_display_modifiers(const struct yasl_display *d) void yasl_display_copy(struct yasl_display *d, enum yasl_selection sel, const char *text) { - if (!d || !d->ops->display_copy) + if (!d || !d->ops->display_copy || !text || + (sel != YASL_CLIPBOARD && sel != YASL_PRIMARY) || + (sel == YASL_PRIMARY && !(yasl_display_caps(d) & YASL_CAP_PRIMARY_SELECTION))) return; d->ops->display_copy(d, sel, text); } void yasl_display_paste(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *target) { - if (!d || !d->ops->display_paste) + if (!d || !d->ops->display_paste || + (sel != YASL_CLIPBOARD && sel != YASL_PRIMARY) || + (sel == YASL_PRIMARY && !(yasl_display_caps(d) & YASL_CAP_PRIMARY_SELECTION))) return; if (!target || target->display != d) return; @@ -145,8 +149,17 @@ void yasl_display_drag_cancel(struct yasl_display *d) struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d, const struct yasl_surface_spec *spec) { - if (!d || !d->ops->surface_create_toplevel) - return 0; + if (!d || !d->ops->surface_create_toplevel || !spec || + spec->size.x <= 0 || spec->size.y <= 0 || + spec->size.x > 32767 || spec->size.y > 32767 || + (int64_t)spec->size.x * spec->size.y * 4 > INT32_MAX) { + errno = EINVAL; + return NULL; + } + if (spec->graphics_device && !(yasl_display_caps(d) & YASL_CAP_NATIVE_GRAPHICS)) { + errno = ENOTSUP; + return NULL; + } return d->ops->surface_create_toplevel(d, spec); } @@ -201,14 +214,34 @@ void yasl_surface_schedule_redraw(struct yasl_surface *s) bool yasl_surface_present(struct yasl_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage) { - if (!s || !s->display->ops->surface_present) - return 0; - return s->display->ops->surface_present(s, fb, damage); + if (!s || !s->display->ops->surface_present || !fb || !damage || + !fb->generation || fb->generation != s->frame_generation || + fb->size.x <= 0 || fb->size.y <= 0 || + damage->n < -1 || damage->n > YASL_DAMAGE_MAX) + return false; + struct yasl_damage_list clipped = {.n = damage->n}; + if (damage->n >= 0) { + clipped.n = 0; + for (int i = 0; i < damage->n; i++) { + struct yasl_rect2i r = damage->rects[i]; + if (r.width < 0 || r.height < 0) return false; + int64_t right = (int64_t)r.x + r.width; + int64_t bottom = (int64_t)r.y + r.height; + int64_t x = r.x > 0 ? r.x : 0, y = r.y > 0 ? r.y : 0; + if (right > fb->size.x) right = fb->size.x; + if (bottom > fb->size.y) bottom = fb->size.y; + if (right > x && bottom > y) + clipped.rects[clipped.n++] = (struct yasl_rect2i){ + (int)x, (int)y, (int)(right - x), (int)(bottom - y), + }; + } + } + return s->display->ops->surface_present(s, fb, &clipped); } bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev) { - if (!s || !s->display->ops->surface_input_poll) + if (!s || !ev || !s->display->ops->surface_input_poll) return 0; return s->display->ops->surface_input_poll(s, ev); } @@ -271,7 +304,7 @@ const char *yasl_surface_ime_preedit(const struct yasl_surface *s) bool yasl_surface_ime_preedit_cursor(const struct yasl_surface *s, int *begin, int *end) { - if (!s || !s->display->ops->surface_ime_preedit_cursor) + if (!s || !begin || !end || !s->display->ops->surface_ime_preedit_cursor) return 0; return s->display->ops->surface_ime_preedit_cursor(s, begin, end); } @@ -292,7 +325,11 @@ bool yasl_surface_start_interactive_move(struct yasl_surface *s) bool yasl_surface_start_interactive_resize(struct yasl_surface *s, enum yasl_resize_edge edge) { - if (!s || !s->display->ops->surface_start_interactive_resize) + if (!s || !s->display->ops->surface_start_interactive_resize || + (edge != YASL_EDGE_TOP && edge != YASL_EDGE_BOTTOM && + edge != YASL_EDGE_LEFT && edge != YASL_EDGE_RIGHT && + edge != YASL_EDGE_TOP_LEFT && edge != YASL_EDGE_TOP_RIGHT && + edge != YASL_EDGE_BOTTOM_LEFT && edge != YASL_EDGE_BOTTOM_RIGHT)) return 0; return s->display->ops->surface_start_interactive_resize(s, edge); } -- cgit v1.2.3