1
0
mirror of git://git.suckless.org/surf synced 2025-03-02 11:40:27 +00:00

webext: Process full messages

Piped messages would not always be fully sent in a single read.
Do a bit of message reassembly.
This commit is contained in:
Quentin Rameau 2024-03-24 15:24:22 +01:00
parent d5f45bffe0
commit 9ef79bf710

View File

@ -19,17 +19,73 @@
static WebKitWebExtension *webext; static WebKitWebExtension *webext;
static int sock; static int sock;
static gboolean /*
readsock(GIOChannel *s, GIOCondition c, gpointer unused) * Return:
* 0 No data processed: need more data
* > 0 Amount of data processed or discarded
*/
static size_t
evalmsg(char *msg, size_t sz)
{ {
static char js[48], msg[MSGBUFSZ]; char js[48];
WebKitWebPage *page; WebKitWebPage *page;
JSCContext *jsc; JSCContext *jsc;
JSCValue *jsv; JSCValue *jsv;
GError *gerr = NULL;
gsize msgsz;
if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) != if (!(page = webkit_web_extension_get_page(webext, msg[0])))
return sz;
if (sz < 2)
return 0;
jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page));
jsv = NULL;
switch (msg[1]) {
case 'h':
if (sz < 3) {
sz = 0;
break;
}
sz = 3;
snprintf(js, sizeof(js),
"window.scrollBy(window.innerWidth/100*%hhd,0);",
msg[2]);
jsv = jsc_context_evaluate(jsc, js, -1);
break;
case 'v':
if (sz < 3) {
sz = 0;
break;
}
sz = 3;
snprintf(js, sizeof(js),
"window.scrollBy(0,window.innerHeight/100*%hhd);",
msg[2]);
jsv = jsc_context_evaluate(jsc, js, -1);
break;
default:
fprintf(stderr, "%s:%d:evalmsg: unknown cmd(%zu): '%#x'\n",
__FILE__, __LINE__, sz, msg[1]);
}
g_object_unref(jsc);
if (jsv)
g_object_unref(jsv);
return sz;
}
static gboolean
readsock(GIOChannel *s, GIOCondition c, gpointer unused)
{
static char msg[MSGBUFSZ];
static size_t msgoff;
GError *gerr = NULL;
size_t sz;
gsize rsz;
if (g_io_channel_read_chars(s, msg+msgoff, sizeof(msg)-msgoff, &rsz, &gerr) !=
G_IO_STATUS_NORMAL) { G_IO_STATUS_NORMAL) {
if (gerr) { if (gerr) {
fprintf(stderr, "webext: error reading socket: %s\n", fprintf(stderr, "webext: error reading socket: %s\n",
@ -38,41 +94,23 @@ readsock(GIOChannel *s, GIOCondition c, gpointer unused)
} }
return TRUE; return TRUE;
} }
if (msgoff >= sizeof(msg)) {
if (msgsz < 2) { fprintf(stderr, "%s:%d:%s: msgoff: %zu", __FILE__, __LINE__, __func__, msgoff);
fprintf(stderr, "webext: readsock: message too short: %lu\n", return FALSE;
msgsz);
return TRUE;
} }
if (!(page = webkit_web_extension_get_page(webext, msg[0]))) for (rsz += msgoff; rsz; rsz -= sz) {
return TRUE; sz = evalmsg(msg, rsz);
if (sz == 0) {
jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page)); /* need more data */
jsv = NULL; break;
}
switch (msg[1]) { if (sz != rsz) {
case 'h': /* continue processing message */
if (msgsz != 3) memmove(msg, msg+sz, rsz-sz);
return TRUE; }
snprintf(js, sizeof(js),
"window.scrollBy(window.innerWidth/100*%hhd,0);",
msg[2]);
jsv = jsc_context_evaluate(jsc, js, -1);
break;
case 'v':
if (msgsz != 3)
return TRUE;
snprintf(js, sizeof(js),
"window.scrollBy(0,window.innerHeight/100*%hhd);",
msg[2]);
jsv = jsc_context_evaluate(jsc, js, -1);
break;
} }
msgoff = rsz;
g_object_unref(jsc);
if (jsv)
g_object_unref(jsv);
return TRUE; return TRUE;
} }