From 0506ca8bdf8584858c0e462a24712c651a7e4e59 Mon Sep 17 00:00:00 2001 From: Trumeet Date: Thu, 28 Jul 2022 15:38:34 -0700 Subject: fix(libacron): memory leak when received more than one frames API:CHANGE --- client/libacron/net.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'client/libacron/net.c') 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; -- cgit v1.2.3