From 810bce688d9b0e271d86886e182b62aa7166319f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 14 Oct 2021 08:47:29 +0200
Subject: Improve some reference counters inside binary contents.

---
 plugins/pychrysalide/analysis/content.c | 46 +++++++++++++++++++++++++++++++++
 src/analysis/content.c                  |  2 --
 src/analysis/contents/memory.c          | 10 +++++++
 src/main.c                              |  5 ++--
 4 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index 68ecba2..f94e3f7 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -99,6 +99,9 @@ static int py_binary_content_set_attributes(PyObject *, PyObject *, void *);
 /* Fournit l'ensemble des attributs associés à un contenu. */
 static PyObject *py_binary_content_get_attributes(PyObject *, void *);
 
+/* Donne l'origine d'un contenu binaire. */
+static PyObject *py_binary_content_get_root(PyObject *, void *);
+
 /* Fournit une empreinte unique (SHA256) pour les données. */
 static PyObject *py_binary_content_get_checksum(PyObject *, void *);
 
@@ -1133,6 +1136,48 @@ static PyObject *py_binary_content_get_attributes(PyObject *self, void *closure)
 *  Paramètres  : self    = contenu binaire à manipuler.                       *
 *                closure = adresse non utilisée ici.                          *
 *                                                                             *
+*  Description : Donne l'origine d'un contenu binaire.                        *
+*                                                                             *
+*  Retour      : Contenu à l'origine du contenu courant.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_binary_content_get_root(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GBinContent *content;                   /* Version GLib du format      */
+    GContentAttributes *attribs;            /* Attributs à transmettre     */
+
+#define BINARY_CONTENT_ROOT_ATTRIB PYTHON_GET_DEF_FULL                  \
+(                                                                       \
+    root, py_binary_content,                                            \
+    "Provide, as a pychrysalide.analysis.BinContent instance, the root" \
+    " content leading to the current content."                          \
+    "\n"                                                                \
+    "This property is relevant only for"                                \
+    " pychrysalide.analysis.contents.EncapsulatedContent objects."      \
+)
+
+    content = G_BIN_CONTENT(pygobject_get(self));
+
+    attribs = g_binary_content_get_attributes(content);
+
+    result = pygobject_new(G_OBJECT(attribs));
+
+    g_object_unref(attribs);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = contenu binaire à manipuler.                       *
+*                closure = adresse non utilisée ici.                          *
+*                                                                             *
 *  Description : Fournit une empreinte unique (SHA256) pour les données.      *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
@@ -1347,6 +1392,7 @@ PyTypeObject *get_python_binary_content_type(void)
 
     static PyGetSetDef py_binary_content_getseters[] = {
         BINARY_CONTENT_ATTRIBUTES_ATTRIB,
+        BINARY_CONTENT_ROOT_ATTRIB,
         BINARY_CONTENT_CHECKSUM_ATTRIB,
         BINARY_CONTENT_SIZE_ATTRIB,
         BINARY_CONTENT_START_POS_ATTRIB,
diff --git a/src/analysis/content.c b/src/analysis/content.c
index 626497e..7208f94 100644
--- a/src/analysis/content.c
+++ b/src/analysis/content.c
@@ -143,8 +143,6 @@ GBinContent *g_binary_content_get_root(GBinContent *content)
 
     result = iface->get_root(content);
 
-    g_object_ref(G_OBJECT(result));
-
     return result;
 
 }
diff --git a/src/analysis/contents/memory.c b/src/analysis/contents/memory.c
index e28d31c..0b14a48 100644
--- a/src/analysis/contents/memory.c
+++ b/src/analysis/contents/memory.c
@@ -192,6 +192,8 @@ static void g_memory_content_init(GMemoryContent *content)
 
     g_binary_content_set_attributes(G_BIN_CONTENT(content), empty);
 
+    g_object_unref(G_OBJECT(empty));
+
     content->data = NULL;
     content->length = 0;
 
@@ -372,7 +374,10 @@ GBinContent *g_memory_content_new(const bin_t *data, phys_t size)
 
 static void g_memory_content_set_attributes(GMemoryContent *content, GContentAttributes *attribs)
 {
+    g_clear_object(&content->attribs);
+
     content->attribs = attribs;
+    g_object_unref(G_OBJECT(attribs));
 
 }
 
@@ -395,6 +400,9 @@ static GContentAttributes *g_memory_content_get_attributes(const GMemoryContent
 
     result = content->attribs;
 
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
     return result;
 
 }
@@ -418,6 +426,8 @@ static GBinContent *g_memory_content_get_root(GMemoryContent *content)
 
     result = G_BIN_CONTENT(content);
 
+    g_object_ref(G_OBJECT(result));
+
     return result;
 
 }
diff --git a/src/main.c b/src/main.c
index 434c861..356e796 100644
--- a/src/main.c
+++ b/src/main.c
@@ -540,10 +540,9 @@ static int open_binaries(char **files, int count)
         }
 
         else
-        {
-            g_object_unref(G_OBJECT(attribs));
             result = EXIT_FAILURE;
-        }
+
+        g_object_unref(G_OBJECT(attribs));
 
     }
 
-- 
cgit v0.11.2-87-g4458