aboutsummaryrefslogtreecommitdiff
path: root/client/libacron/net.c
diff options
context:
space:
mode:
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;