webext: Process full messages - surf - surf browser, a WebKit based browser | |
git clone git://git.suckless.org/surf | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 9ef79bf7106496c736ba613c51d2fd5af9d873a8 | |
parent d5f45bffe0c3a54344f61662b4b643e168539251 | |
Author: Quentin Rameau <[email protected]> | |
Date: Sun, 24 Mar 2024 15:24:22 +0100 | |
webext: Process full messages | |
Piped messages would not always be fully sent in a single read. | |
Do a bit of message reassembly. | |
Diffstat: | |
M webext-surf.c | 90 ++++++++++++++++++++++-------… | |
1 file changed, 64 insertions(+), 26 deletions(-) | |
--- | |
diff --git a/webext-surf.c b/webext-surf.c | |
@@ -19,61 +19,99 @@ | |
static WebKitWebExtension *webext; | |
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; | |
JSCContext *jsc; | |
JSCValue *jsv; | |
- GError *gerr = NULL; | |
- gsize msgsz; | |
- | |
- if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) != | |
- G_IO_STATUS_NORMAL) { | |
- if (gerr) { | |
- fprintf(stderr, "webext: error reading socket: %s\n", | |
- gerr->message); | |
- g_error_free(gerr); | |
- } | |
- return TRUE; | |
- } | |
- | |
- if (msgsz < 2) { | |
- fprintf(stderr, "webext: readsock: message too short: %lu\n", | |
- msgsz); | |
- return TRUE; | |
- } | |
if (!(page = webkit_web_extension_get_page(webext, msg[0]))) | |
- return TRUE; | |
+ 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 (msgsz != 3) | |
- return TRUE; | |
+ 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 (msgsz != 3) | |
- return TRUE; | |
+ 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, &… | |
+ G_IO_STATUS_NORMAL) { | |
+ if (gerr) { | |
+ fprintf(stderr, "webext: error reading socket: %s\n", | |
+ gerr->message); | |
+ g_error_free(gerr); | |
+ } | |
+ return TRUE; | |
+ } | |
+ if (msgoff >= sizeof(msg)) { | |
+ fprintf(stderr, "%s:%d:%s: msgoff: %zu", __FILE__, __LINE__, _… | |
+ return FALSE; | |
+ } | |
+ | |
+ for (rsz += msgoff; rsz; rsz -= sz) { | |
+ sz = evalmsg(msg, rsz); | |
+ if (sz == 0) { | |
+ /* need more data */ | |
+ break; | |
+ } | |
+ if (sz != rsz) { | |
+ /* continue processing message */ | |
+ memmove(msg, msg+sz, rsz-sz); | |
+ } | |
+ } | |
+ msgoff = rsz; | |
+ | |
return TRUE; | |
} | |