fix: harden caret and IBus dispatch

This commit is contained in:
2026-08-12 17:34:34 +09:00
parent de536da0bb
commit 4e90fdd5c7
5 changed files with 21 additions and 12 deletions

1
dat.h
View File

@@ -135,7 +135,6 @@ struct Caret
int valid; int valid;
int x; int x;
int y; int y;
int w;
int h; int h;
}; };

7
ibus.c
View File

@@ -558,7 +558,6 @@ handlecursor(DBusConnection *c, DBusMessage *m, Ictx *ctx)
ctx->caret.valid = 1; ctx->caret.valid = 1;
ctx->caret.x = x; ctx->caret.x = x;
ctx->caret.y = y; ctx->caret.y = y;
ctx->caret.w = w;
ctx->caret.h = h; ctx->caret.h = h;
if(ctx->focused) if(ctx->focused)
sendrequest(ctx, Keycaret, 0, 0, &res); sendrequest(ctx, Keycaret, 0, 0, &res);
@@ -743,6 +742,7 @@ void
ibusthread(void *_) ibusthread(void *_)
{ {
struct pollfd pfds[Maxwatches]; struct pollfd pfds[Maxwatches];
DBusWatch *polled[Maxwatches];
int wi[Maxwatches]; int wi[Maxwatches];
int i, n, rv; int i, n, rv;
unsigned int f; unsigned int f;
@@ -765,6 +765,7 @@ ibusthread(void *_)
if(f & DBUS_WATCH_READABLE) pfds[n].events |= POLLIN; if(f & DBUS_WATCH_READABLE) pfds[n].events |= POLLIN;
if(f & DBUS_WATCH_WRITABLE) pfds[n].events |= POLLOUT; if(f & DBUS_WATCH_WRITABLE) pfds[n].events |= POLLOUT;
wi[n] = i; wi[n] = i;
polled[n] = watches[i].w;
n++; n++;
} }
rv = poll(pfds, n, 200); rv = poll(pfds, n, 200);
@@ -773,14 +774,14 @@ ibusthread(void *_)
for(i = 0; i < n; i++){ for(i = 0; i < n; i++){
if(pfds[i].revents == 0) if(pfds[i].revents == 0)
continue; continue;
if(watches[wi[i]].w == nil) if(watches[wi[i]].w != polled[i])
continue; continue;
f = 0; f = 0;
if(pfds[i].revents & POLLIN) f |= DBUS_WATCH_READABLE; if(pfds[i].revents & POLLIN) f |= DBUS_WATCH_READABLE;
if(pfds[i].revents & POLLOUT) f |= DBUS_WATCH_WRITABLE; if(pfds[i].revents & POLLOUT) f |= DBUS_WATCH_WRITABLE;
if(pfds[i].revents & POLLHUP) f |= DBUS_WATCH_HANGUP; if(pfds[i].revents & POLLHUP) f |= DBUS_WATCH_HANGUP;
if(pfds[i].revents & POLLERR) f |= DBUS_WATCH_ERROR; if(pfds[i].revents & POLLERR) f |= DBUS_WATCH_ERROR;
dbus_watch_handle(watches[wi[i]].w, f); dbus_watch_handle(polled[i], f);
} }
for(i = 0; i < nconns; i++) for(i = 0; i < nconns; i++)
while(dbus_connection_dispatch(conns[i]) == DBUS_DISPATCH_DATA_REMAINS) while(dbus_connection_dispatch(conns[i]) == DBUS_DISPATCH_DATA_REMAINS)

View File

@@ -17,13 +17,17 @@ void
popupposition(Caret *caret, int pointerx, int pointery, int screenw, popupposition(Caret *caret, int pointerx, int pointery, int screenw,
int screenh, int w, int h, int *x, int *y) int screenh, int w, int h, int *x, int *y)
{ {
vlong px, py, xmax, ymax;
if(caret->valid){ if(caret->valid){
*x = caret->x; px = caret->x;
*y = caret->y + max(caret->h, 0); py = (vlong)caret->y + max(caret->h, 0);
}else{ }else{
*x = pointerx + 10; px = (vlong)pointerx + 10;
*y = pointery + 10; py = (vlong)pointery + 10;
} }
*x = max(0, min(*x, screenw - w)); xmax = max((vlong)screenw - w, 0);
*y = max(0, min(*y, screenh - h)); ymax = max((vlong)screenh - h, 0);
*x = max(0, min(px, xmax));
*y = max(0, min(py, ymax));
} }

View File

@@ -249,7 +249,6 @@ engine_active_owner_caret(struct ct *t)
a.valid = 1; a.valid = 1;
a.x = 10; a.x = 10;
a.y = 20; a.y = 20;
a.w = 3;
a.h = 14; a.h = 14;
moved = a; moved = a;
moved.x = 80; moved.x = 80;
@@ -1221,7 +1220,6 @@ engine_randomized_stress(struct ct *t)
pos.valid = (rnd >> 25) & 1; pos.valid = (rnd >> 25) & 1;
pos.x = (rnd >> 3) & 0x3ff; pos.x = (rnd >> 3) & 0x3ff;
pos.y = (rnd >> 13) & 0x3ff; pos.y = (rnd >> 13) & 0x3ff;
pos.w = 1 + ((rnd >> 23) & 0x1f);
pos.h = 1 + ((rnd >> 18) & 0x1f); pos.h = 1 + ((rnd >> 18) & 0x1f);
if(op < 13) if(op < 13)
res = ownerrequestat(owner, Keypress, res = ownerrequestat(owner, Keypress,

View File

@@ -1,4 +1,5 @@
#include "test.h" #include "test.h"
#include <limits.h>
void void
popup_layout(struct ct *t) popup_layout(struct ct *t)
@@ -24,4 +25,10 @@ popup_layout(struct ct *t)
popupposition(&caret, 0, 0, 800, 600, 100, 60, &x, &y); popupposition(&caret, 0, 0, 800, 600, 100, 60, &x, &y);
CT_EQ_INT(t, 700, x); CT_EQ_INT(t, 700, x);
CT_EQ_INT(t, 540, y); CT_EQ_INT(t, 540, y);
caret.x = INT_MIN;
caret.y = INT_MAX;
caret.h = INT_MAX;
popupposition(&caret, 0, 0, 800, 600, 100, 60, &x, &y);
CT_EQ_INT(t, 0, x);
CT_EQ_INT(t, 540, y);
} }