aboutsummaryrefslogtreecommitdiff
path: root/client/libacron/net.c
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-07-28 15:38:34 -0700
committerTrumeet <yuuta@yuuta.moe>2022-07-28 15:38:34 -0700
commit0506ca8bdf8584858c0e462a24712c651a7e4e59 (patch)
treee8fd11d7fe7615536ec3f244bd5f90d39b396450 /client/libacron/net.c
parent35caf0da7fbf4ece60def1df1d88d34bf16185aa (diff)
downloadacron-0506ca8bdf8584858c0e462a24712c651a7e4e59.tar
acron-0506ca8bdf8584858c0e462a24712c651a7e4e59.tar.gz
acron-0506ca8bdf8584858c0e462a24712c651a7e4e59.tar.bz2
acron-0506ca8bdf8584858c0e462a24712c651a7e4e59.zip
fix(libacron): memory leak when received more than one frames
API:CHANGE
Diffstat (limited to 'client/libacron/net.c')
-rw-r--r--client/libacron/net.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/client/libacron/net.c b/client/libacron/net.c
index b393475..55b10ce 100644
--- a/client/libacron/net.c
+++ b/client/libacron/net.c
@@ -62,6 +62,17 @@ static bool on_message_handler(struct wic_inst *inst,
}
/* TODO: Only parse when fin = true? */
struct ac_result *res = &conn->result;
+ if (res->has_result) {
+ /* This flag will be cleared upon ac_receive using memset().
+ * A positive flag indicates that on_message_handler was called
+ * more than once before wic_parse returns. This could happen due
+ * to more than one WebSocket frames were returned by a single read.
+ * To prevent the new message from being overwritten (and thus causing
+ * memory leaks), we return false here, making wic backlog the new message
+ * until the next wic_parse. */
+ LOGD("Two or more frames arrived before wic_parse returns. Keeping the message.");
+ return false;
+ }
int r;
if ((r = deserialize(data, size, &res->obj))) {
if (r == AC_E_SERIALIZER_CONTINUE) {
@@ -202,12 +213,20 @@ int ac_receive(void *connection,
/* In case the deserializer does not run at all. */
memset(&conn->result, 0, sizeof(struct ac_result));
- for (pos = 0U; pos < len; pos += retval) {
- retval = wic_parse(inst, &ptr[pos], len - pos);
+ if (!len) {
+ retval = wic_parse(inst, NULL, 0);
if (wic_get_state(inst) == WIC_STATE_CLOSED) {
LOGE("Connection closed.");
return AC_E_NET;
}
+ } else {
+ for (pos = 0U; pos < len; pos += retval) {
+ retval = wic_parse(inst, &ptr[pos], len - pos);
+ if (wic_get_state(inst) == WIC_STATE_CLOSED) {
+ LOGE("Connection closed.");
+ return AC_E_NET;
+ }
+ }
}
struct ac_result *res = &conn->result;