From ce33112cf8c913635402cb8b6d127f9ac9f2b6b5 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 1 Nov 2023 22:36:50 +0100
Subject: Fix various memory leaks.

---
 src/analysis/scan/exprs/access.c            |   2 +
 src/analysis/scan/exprs/call.c              |   4 +
 src/analysis/scan/exprs/handler.c           |   3 +
 src/analysis/scan/exprs/literal.c           |  21 +++++
 src/analysis/scan/grammar.y                 | 129 ++++++++++++++++++++++++----
 src/analysis/scan/patterns/backends/acism.c |  15 ++++
 src/analysis/scan/patterns/token.c          |   2 +
 src/analysis/scan/rule.c                    |   3 +
 src/analysis/scan/space.c                   |   2 +-
 src/core/core.c                             |   3 +
 src/main.c                                  |   4 +-
 src/plugins/pglist.c                        |   3 +
 src/rost.c                                  |   6 +-
 13 files changed, 176 insertions(+), 21 deletions(-)

diff --git a/src/analysis/scan/exprs/access.c b/src/analysis/scan/exprs/access.c
index a1331b0..342c2d7 100644
--- a/src/analysis/scan/exprs/access.c
+++ b/src/analysis/scan/exprs/access.c
@@ -391,6 +391,8 @@ GScanRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAcce
 
         g_scan_registered_item_resolve(base, expr->target, ctx, scope, &result);
 
+        g_object_unref(G_OBJECT(base));
+
     }
 
     /**
diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c
index e335933..3997ff6 100644
--- a/src/analysis/scan/exprs/call.c
+++ b/src/analysis/scan/exprs/call.c
@@ -326,6 +326,10 @@ static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *exp
             {
                 if (new_args != NULL)
                     new_args[i] = new;
+
+                else
+                    g_object_unref(G_OBJECT(new));
+
             }
 
         }
diff --git a/src/analysis/scan/exprs/handler.c b/src/analysis/scan/exprs/handler.c
index 8aab9e5..ea24443 100644
--- a/src/analysis/scan/exprs/handler.c
+++ b/src/analysis/scan/exprs/handler.c
@@ -168,6 +168,9 @@ static void g_scan_pattern_handler_dispose(GScanPatternHandler *handler)
 
 static void g_scan_pattern_handler_finalize(GScanPatternHandler *handler)
 {
+    if (handler->patterns != NULL)
+        free(handler->patterns);
+
     G_OBJECT_CLASS(g_scan_pattern_handler_parent_class)->finalize(G_OBJECT(handler));
 
 }
diff --git a/src/analysis/scan/exprs/literal.c b/src/analysis/scan/exprs/literal.c
index b1a094c..b7aed5b 100644
--- a/src/analysis/scan/exprs/literal.c
+++ b/src/analysis/scan/exprs/literal.c
@@ -124,6 +124,8 @@ static void g_scan_literal_expression_init(GScanLiteralExpression *expr)
 {
     G_SCAN_EXPRESSION(expr)->state = SRS_REDUCED;
 
+    memset(&expr->value, 0, sizeof(expr->value));
+
 }
 
 
@@ -160,6 +162,25 @@ static void g_scan_literal_expression_dispose(GScanLiteralExpression *expr)
 
 static void g_scan_literal_expression_finalize(GScanLiteralExpression *expr)
 {
+    switch (expr->value_type)
+    {
+        case LVT_STRING:
+            exit_szstr(&expr->value.string);
+            break;
+
+        case LVT_REG_EXPR:
+            if (expr->value.regex != NULL)
+            {
+                free(expr->value.regex);
+                regfree(&expr->value.preg);
+            }
+            break;
+
+        default:
+            break;
+
+    }
+
     G_OBJECT_CLASS(g_scan_literal_expression_parent_class)->finalize(G_OBJECT(expr));
 
 }
diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y
index f31a5d1..ecaeb1f 100644
--- a/src/analysis/scan/grammar.y
+++ b/src/analysis/scan/grammar.y
@@ -331,7 +331,11 @@ YY_DECL;
 
              rules : /* empty */
                    | external rules
-                   | rule rules { g_content_scanner_add_rule(scanner, $1); }
+                   | rule rules
+                   {
+                       g_content_scanner_add_rule(scanner, $1);
+                       g_object_unref(G_OBJECT($1));
+                   }
                    ;
 
 
@@ -538,9 +542,11 @@ YY_DECL;
                        {
                            $$ = g_scan_modifier_pipe_new();
                            g_scan_modifier_pipe_add(G_SCAN_MODIFIER_PIPE($$), $1);
+                           g_object_unref(G_OBJECT($1));
                        }
 
                        g_scan_modifier_pipe_add(G_SCAN_MODIFIER_PIPE($$), $3);
+                       g_object_unref(G_OBJECT($3));
 
                    }
                    ;
@@ -575,6 +581,7 @@ YY_DECL;
                        {
                            $$ = g_scan_modifier_list_new();
                            g_scan_modifier_list_add(G_SCAN_MODIFIER_LIST($$), $1);
+                           g_object_unref(G_OBJECT($1));
                        }
 
                        status = g_scan_modifier_list_add(G_SCAN_MODIFIER_LIST($$), $2);
@@ -582,9 +589,10 @@ YY_DECL;
                        {
                            if (1)
                                log_simple_message(LMT_WARNING, "modifier already taken into account!");
-                           g_object_unref(G_OBJECT($2));
                        }
 
+                       g_object_unref(G_OBJECT($2));
+
                    }
                    ;
 
@@ -634,6 +642,9 @@ YY_DECL;
                        }
 
                        _status = g_scan_token_customizer_attach_modifier(G_SCAN_TOKEN_CUSTOMIZER($$), _mod);
+
+                       g_object_unref(G_OBJECT(_mod));
+
                        if (!_status)
                        {
                            char *_msg;
@@ -1065,6 +1076,7 @@ YY_DECL;
                 | chain_items "." chain_item
                 {
                     g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS($1), G_SCAN_NAMED_ACCESS($3));
+                    g_object_unref(G_OBJECT($3));
                     $$ = $1;
                 }
                 ;
@@ -1107,58 +1119,143 @@ YY_DECL;
                 }
                 ;
 
-   logical_expr : cexpression "and" cexpression { $$ = g_scan_logical_operation_new(BOT_AND, $1, $3); }
-                | cexpression "or" cexpression  { $$ = g_scan_logical_operation_new(BOT_OR, $1, $3); }
-                | "not" "(" cexpression ")"     { $$ = g_scan_logical_operation_new(BOT_NOT, $3, NULL); }
+   logical_expr : cexpression "and" cexpression
+                {
+                    $$ = g_scan_logical_operation_new(BOT_AND, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "or" cexpression
+                {
+                    $$ = g_scan_logical_operation_new(BOT_OR, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | "not" "(" cexpression ")"
+                {
+                    $$ = g_scan_logical_operation_new(BOT_NOT, $3, NULL);
+                    g_object_unref(G_OBJECT($3));
+                }
                 ;
 
-relational_expr : cexpression "<" cexpression  { $$ = g_scan_relational_operation_new(RCO_LT, $1, $3); }
-                | cexpression "<=" cexpression { $$ = g_scan_relational_operation_new(RCO_LE, $1, $3); }
-                | cexpression "==" cexpression { $$ = g_scan_relational_operation_new(RCO_EQ, $1, $3); }
-                | cexpression "!=" cexpression { $$ = g_scan_relational_operation_new(RCO_NE, $1, $3); }
-                | cexpression ">" cexpression  { $$ = g_scan_relational_operation_new(RCO_GT, $1, $3); }
-                | cexpression ">=" cexpression { $$ = g_scan_relational_operation_new(RCO_GE, $1, $3); }
+relational_expr : cexpression "<" cexpression
+                {
+                    $$ = g_scan_relational_operation_new(RCO_LT, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "<=" cexpression
+                {
+                    $$ = g_scan_relational_operation_new(RCO_LE, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "==" cexpression
+                {
+                    $$ = g_scan_relational_operation_new(RCO_EQ, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "!=" cexpression
+                {
+                    $$ = g_scan_relational_operation_new(RCO_NE, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression ">" cexpression
+                {
+                    $$ = g_scan_relational_operation_new(RCO_GT, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression ">=" cexpression
+                {
+                    $$ = g_scan_relational_operation_new(RCO_GE, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
                 ;
 
       string_op : cexpression "contains" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_CONTAINS, $1, $3, true);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "startswith" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_STARTSWITH, $1, $3, true);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "endswith" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_ENDSWITH, $1, $3, true);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "matches" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_MATCHES, $1, $3, true);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "icontains" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_CONTAINS, $1, $3, false);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "istartswith" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_STARTSWITH, $1, $3, false);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "iendswith" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_ENDSWITH, $1, $3, false);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 | cexpression "iequals" cexpression
                 {
                     $$ = g_scan_string_operation_new(SOT_IEQUALS, $1, $3, false);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
                 }
                 ;
 
-    arithm_expr : cexpression "+" cexpression { $$ = g_scan_arithmetic_operation_new(AEO_PLUS, $1, $3); }
-                | cexpression "-" cexpression { $$ = g_scan_arithmetic_operation_new(AEO_MINUS, $1, $3); }
-                | cexpression "*" cexpression { $$ = g_scan_arithmetic_operation_new(AEO_MUL, $1, $3); }
-                | cexpression "/" cexpression { $$ = g_scan_arithmetic_operation_new(AEO_DIV, $1, $3); }
-                | cexpression "%" cexpression { $$ = g_scan_arithmetic_operation_new(AEO_MOD, $1, $3); }
+    arithm_expr : cexpression "+" cexpression
+                {
+                    $$ = g_scan_arithmetic_operation_new(AEO_PLUS, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "-" cexpression
+                {
+                    $$ = g_scan_arithmetic_operation_new(AEO_MINUS, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "*" cexpression
+                {
+                    $$ = g_scan_arithmetic_operation_new(AEO_MUL, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "/" cexpression
+                {
+                    $$ = g_scan_arithmetic_operation_new(AEO_DIV, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
+                | cexpression "%" cexpression
+                {
+                    $$ = g_scan_arithmetic_operation_new(AEO_MOD, $1, $3);
+                    g_object_unref(G_OBJECT($1));
+                    g_object_unref(G_OBJECT($3));
+                }
                 ;
 
 
diff --git a/src/analysis/scan/patterns/backends/acism.c b/src/analysis/scan/patterns/backends/acism.c
index 97f8561..70e9a42 100644
--- a/src/analysis/scan/patterns/backends/acism.c
+++ b/src/analysis/scan/patterns/backends/acism.c
@@ -217,6 +217,21 @@ static void g_acism_backend_dispose(GAcismBackend *backend)
 
 static void g_acism_backend_finalize(GAcismBackend *backend)
 {
+    if (backend->sources != NULL)
+        free(backend->sources);
+
+    if (backend->nodes != NULL)
+        free(backend->nodes);
+
+    if (backend->bitmap_usage != NULL)
+        delete_bit_field(backend->bitmap_usage);
+
+    if (backend->states != NULL)
+        free(backend->states);
+
+    if (backend->pids != NULL)
+        free(backend->pids);
+
     G_OBJECT_CLASS(g_acism_backend_parent_class)->finalize(G_OBJECT(backend));
 
 }
diff --git a/src/analysis/scan/patterns/token.c b/src/analysis/scan/patterns/token.c
index 030e4a1..e5eb287 100644
--- a/src/analysis/scan/patterns/token.c
+++ b/src/analysis/scan/patterns/token.c
@@ -141,6 +141,8 @@ static void g_bytes_token_init(GBytesToken *token)
 
 static void g_bytes_token_dispose(GBytesToken *token)
 {
+    g_clear_object(&token->root);
+
     G_OBJECT_CLASS(g_bytes_token_parent_class)->dispose(G_OBJECT(token));
 
 }
diff --git a/src/analysis/scan/rule.c b/src/analysis/scan/rule.c
index d4420b7..e3f84d4 100644
--- a/src/analysis/scan/rule.c
+++ b/src/analysis/scan/rule.c
@@ -165,6 +165,9 @@ static void g_scan_rule_finalize(GScanRule *rule)
     if (rule->tags != NULL)
         free(rule->tags);
 
+    if (rule->bytes_locals != NULL)
+        free(rule->bytes_locals);
+
     G_OBJECT_CLASS(g_scan_rule_parent_class)->finalize(G_OBJECT(rule));
 
 }
diff --git a/src/analysis/scan/space.c b/src/analysis/scan/space.c
index 7dd9082..1aaf8b8 100644
--- a/src/analysis/scan/space.c
+++ b/src/analysis/scan/space.c
@@ -274,7 +274,7 @@ bool g_scan_namespace_register_item(GScanNamespace *space, GScanRegisteredItem *
         g_object_ref(G_OBJECT(child));
 
         space->names = realloc(space->names, space->count * sizeof(char *));
-        space->names[space->count - 1] = strdup(name);
+        space->names[space->count - 1] = name;
 
     }
 
diff --git a/src/core/core.c b/src/core/core.c
index fe7a5e0..0fa2c74 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -101,9 +101,11 @@ bool load_all_core_components(bool cs)
 
             explorer = g_content_explorer_new();
             set_current_content_explorer(explorer);
+            g_object_unref(G_OBJECT(explorer));
 
             resolver = g_content_resolver_new();
             set_current_content_resolver(resolver);
+            g_object_unref(G_OBJECT(resolver));
 
 #ifdef INCLUDE_MAGIC_SUPPORT
             if (result) result = init_magic_cookie();
@@ -111,6 +113,7 @@ bool load_all_core_components(bool cs)
 
             root_ns = g_scan_namespace_new(NULL);
             set_rost_root_namespace(root_ns);
+            g_object_unref(G_OBJECT(root_ns));
 
             if (result) result = populate_main_scan_namespace(root_ns);
             if (result) result = load_all_known_scan_token_modifiers();
diff --git a/src/main.c b/src/main.c
index ad13ef1..5b3f397 100644
--- a/src/main.c
+++ b/src/main.c
@@ -484,8 +484,6 @@ int main(int argc, char **argv)
     remember_gtypes_for_leaks();
 #endif
 
-    exit_all_plugins();
-
 #ifdef INCLUDE_GTK_SUPPORT
 
     if (!batch_mode)
@@ -506,6 +504,8 @@ int main(int argc, char **argv)
     dump_remaining_gtypes();
 #endif
 
+    exit_all_plugins();
+
  done:
 
     return result;
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index bacb3ac..9931eec 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -342,6 +342,9 @@ void _register_plugin(GPluginModule *plugin)
 
     }
 
+    else
+        /* FIXME : leak(plugin); */;
+
 }
 
 
diff --git a/src/rost.c b/src/rost.c
index e9a7ccb..337b013 100644
--- a/src/rost.c
+++ b/src/rost.c
@@ -459,16 +459,18 @@ int main(int argc, char **argv)
 
     /* Sortie */
 
-    unload_all_core_components(false);
-
 #ifdef TRACK_GOBJECT_LEAKS
     remember_gtypes_for_leaks();
 #endif
 
+    unload_all_core_components(true);
+
 #ifdef TRACK_GOBJECT_LEAKS
     dump_remaining_gtypes();
 #endif
 
+    exit_all_plugins();
+
  done:
 
     return result;
-- 
cgit v0.11.2-87-g4458