summaryrefslogtreecommitdiff
path: root/src/common/backend.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-12 00:09:38 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-12 00:09:38 +0300
commit624d1371304a5ae4b3429ad5e4267aac7cd03dfd (patch)
tree32de069f6eec83686521fc4bf39cc9874b123e93 /src/common/backend.c
parente813252e685d761235ad45e170d97c9375f51958 (diff)
missing impls and hardening
Diffstat (limited to 'src/common/backend.c')
-rw-r--r--src/common/backend.c57
1 files changed, 47 insertions, 10 deletions
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);
}