From 7ebe360e85dceb8db580fd76ec8f4d6865e8a5aa Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 2 Jun 2018 13:49:55 +0200
Subject: Fixed a memory leak when reading packed buffers.

---
 src/analysis/db/cdb.c    |  6 +++++-
 src/analysis/db/client.c |  2 ++
 src/analysis/db/server.c |  2 ++
 src/common/packed.c      | 30 ++++++++++++++++--------------
 4 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 7044853..bfe6238 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -876,11 +876,13 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
         {
             /* Le canal est fermé, une sortie doit être demandée... */
             if (fds[i].revents & POLLNVAL)
-                goto gcap_bad_exchange;
+                goto gcap_closed_exchange;
 
             /* Données présentes en entrée */
             if (fds[i].revents & (POLLIN | POLLPRI))
             {
+                init_packed_buffer(&in_pbuf);
+
                 status = recv_packed_buffer(&in_pbuf, fds[i].fd);
                 if (!status) goto gcap_bad_exchange;
 
@@ -958,6 +960,8 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
 
                 exit_packed_buffer(&in_pbuf);
 
+ gcap_closed_exchange:
+
                 /* TODO : close conn */
 
                 ;
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 16d243a..f70c9e1 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -406,6 +406,8 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc)
      *      ou 'DBE_WRONG_VERSION' ... 'DBE_LOADING_ERROR').
      */
 
+    init_packed_buffer(&in_pbuf);
+
     status = recv_packed_buffer(&in_pbuf, client->fd);
     if (!status) goto gdsc_error;
 
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index f6c7a71..eaf3775 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -640,6 +640,8 @@ static void *g_db_server_listener(GDbServer *server)
              * Tout ceci est à synchroniser avec la fonction g_db_client_start().
              */
 
+            init_packed_buffer(&in_pbuf);
+
             status = recv_packed_buffer(&in_pbuf, fd);
             if (!status)
             {
diff --git a/src/common/packed.c b/src/common/packed.c
index ca6e816..d956a42 100644
--- a/src/common/packed.c
+++ b/src/common/packed.c
@@ -296,16 +296,17 @@ bool read_packed_buffer(packed_buffer *pbuf, int fd)
 
     result = safe_read(fd, &used, sizeof(uint32_t));
 
-    if (!result)
-        init_packed_buffer(pbuf);
-
-    else
+    if (result)
     {
-        pbuf->allocated = sizeof(uint32_t) + used;
-        pbuf->data = malloc(pbuf->allocated * sizeof(uint8_t));
+        assert(pbuf->pos == sizeof(uint32_t));
+
+        if ((pbuf->pos + used) > pbuf->allocated)
+        {
+            pbuf->allocated = pbuf->pos + used;
+            pbuf->data = realloc(pbuf->data, pbuf->allocated * sizeof(uint8_t));
+        }
 
         pbuf->used = used;
-        pbuf->pos = sizeof(uint32_t);
 
         result = safe_read(fd, pbuf->data + pbuf->pos, used);
 
@@ -363,16 +364,17 @@ bool recv_packed_buffer(packed_buffer *pbuf, int fd)
 
     result = safe_recv(fd, &used, sizeof(uint32_t), 0);
 
-    if (!result)
-        init_packed_buffer(pbuf);
-
-    else
+    if (result)
     {
-        pbuf->allocated = sizeof(uint32_t) + used;
-        pbuf->data = malloc(pbuf->allocated * sizeof(uint8_t));
+        assert(pbuf->pos == sizeof(uint32_t));
+
+        if ((pbuf->pos + used) > pbuf->allocated)
+        {
+            pbuf->allocated = pbuf->pos + used;
+            pbuf->data = realloc(pbuf->data, pbuf->allocated * sizeof(uint8_t));
+        }
 
         pbuf->used = used;
-        pbuf->pos = sizeof(uint32_t);
 
         result = safe_recv(fd, pbuf->data + pbuf->pos, used, 0);
 
-- 
cgit v0.11.2-87-g4458