summaryrefslogtreecommitdiff
path: root/src/analysis/scan/exprs
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/exprs')
-rw-r--r--src/analysis/scan/exprs/Makefile.am4
-rw-r--r--src/analysis/scan/exprs/access-int.h6
-rw-r--r--src/analysis/scan/exprs/access.c20
-rw-r--r--src/analysis/scan/exprs/access.h4
-rw-r--r--src/analysis/scan/exprs/call.c28
-rw-r--r--src/analysis/scan/exprs/counter-int.h57
-rw-r--r--src/analysis/scan/exprs/counter.c251
-rw-r--r--src/analysis/scan/exprs/counter.h59
-rw-r--r--src/analysis/scan/exprs/extract-int.h57
-rw-r--r--src/analysis/scan/exprs/extract.c396
-rw-r--r--src/analysis/scan/exprs/extract.h56
-rw-r--r--src/analysis/scan/exprs/handler-int.h14
-rw-r--r--src/analysis/scan/exprs/handler.c291
-rw-r--r--src/analysis/scan/exprs/handler.h16
-rw-r--r--src/analysis/scan/exprs/item.c4
-rw-r--r--src/analysis/scan/exprs/literal.c73
-rw-r--r--src/analysis/scan/exprs/logical.c7
-rw-r--r--src/analysis/scan/exprs/setcounter-int.h11
-rw-r--r--src/analysis/scan/exprs/setcounter.c137
-rw-r--r--src/analysis/scan/exprs/setcounter.h8
20 files changed, 1046 insertions, 453 deletions
diff --git a/src/analysis/scan/exprs/Makefile.am b/src/analysis/scan/exprs/Makefile.am
index a0b2f3d..c97fa25 100644
--- a/src/analysis/scan/exprs/Makefile.am
+++ b/src/analysis/scan/exprs/Makefile.am
@@ -9,8 +9,8 @@ libanalysisscanexprs_la_SOURCES = \
arithmetic.h arithmetic.c \
call-int.h \
call.h call.c \
- counter-int.h \
- counter.h counter.c \
+ extract-int.h \
+ extract.h extract.c \
handler-int.h \
handler.h handler.c \
intersect-int.h \
diff --git a/src/analysis/scan/exprs/access-int.h b/src/analysis/scan/exprs/access-int.h
index 3216493..be37241 100644
--- a/src/analysis/scan/exprs/access-int.h
+++ b/src/analysis/scan/exprs/access-int.h
@@ -42,8 +42,8 @@ struct _GScanNamedAccess
union
{
- GRegisteredItem *base; /* Base de recherche */
- GRegisteredItem *resolved; /* Elément ciblé au final */
+ GScanRegisteredItem *base; /* Base de recherche */
+ GScanRegisteredItem *resolved; /* Elément ciblé au final */
GObject *any; /* Accès indistinct */
};
@@ -67,7 +67,7 @@ struct _GScanNamedAccessClass
bool g_scan_named_access_create(GScanNamedAccess *, const sized_string_t *);
/* Prépare une réduction en menant une résolution locale. */
-GRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *, GScanContext *, GScanScope *);
+GScanRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *, GScanContext *, GScanScope *);
diff --git a/src/analysis/scan/exprs/access.c b/src/analysis/scan/exprs/access.c
index 0df46e6..342c2d7 100644
--- a/src/analysis/scan/exprs/access.c
+++ b/src/analysis/scan/exprs/access.c
@@ -281,7 +281,7 @@ static void g_scan_named_access_copy(GScanNamedAccess *dest, const GScanNamedAcc
* *
******************************************************************************/
-GScanExpression *g_scan_named_access_duplicate(const GScanNamedAccess *access, GRegisteredItem *resolved)
+GScanExpression *g_scan_named_access_duplicate(const GScanNamedAccess *access, GScanRegisteredItem *resolved)
{
GScanExpression *result; /* Instance copiée à retourner */
GType type; /* Type d'objet à copier */
@@ -315,7 +315,7 @@ GScanExpression *g_scan_named_access_duplicate(const GScanNamedAccess *access, G
* *
******************************************************************************/
-void g_scan_named_access_set_base(GScanNamedAccess *access, GRegisteredItem *base)
+void g_scan_named_access_set_base(GScanNamedAccess *access, GScanRegisteredItem *base)
{
g_clear_object(&access->base);
@@ -372,10 +372,10 @@ void g_scan_named_access_attach_next(GScanNamedAccess *access, GScanNamedAccess
* *
******************************************************************************/
-GRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope)
+GScanRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope)
{
- GRegisteredItem *result; /* Etat synthétisé à retourner */
- GRegisteredItem *base; /* Base de recherche courante */
+ GScanRegisteredItem *result; /* Etat synthétisé à retourner */
+ GScanRegisteredItem *base; /* Base de recherche courante */
result = NULL;
@@ -387,9 +387,11 @@ GRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *
g_object_ref(G_OBJECT(base));
}
else
- base = G_REGISTERED_ITEM(get_rost_root_namespace());
+ base = G_SCAN_REGISTERED_ITEM(get_rost_root_namespace());
- g_registered_item_resolve(base, expr->target, ctx, scope, &result);
+ g_scan_registered_item_resolve(base, expr->target, ctx, scope, &result);
+
+ g_object_unref(G_OBJECT(base));
}
@@ -429,7 +431,7 @@ GRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *
static ScanReductionState g_scan_named_access_reduce(const GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
ScanReductionState result; /* Etat synthétisé à retourner */
- GRegisteredItem *resolved; /* Cible concrète obtenue */
+ GScanRegisteredItem *resolved; /* Cible concrète obtenue */
GScanExpression *new_next; /* Nouvelle version du suivant */
const char *current_rule; /* Nom de la règle courante */
bool status; /* Bilan d'une autre règle */
@@ -448,7 +450,7 @@ static ScanReductionState g_scan_named_access_reduce(const GScanNamedAccess *exp
*/
if (expr->next == NULL)
{
- status = g_registered_item_reduce(resolved, ctx, scope, out);
+ status = g_scan_registered_item_reduce(resolved, ctx, scope, out);
result = (status ? SRS_REDUCED : SRS_UNRESOLVABLE);
diff --git a/src/analysis/scan/exprs/access.h b/src/analysis/scan/exprs/access.h
index 7c007a9..bf83dd0 100644
--- a/src/analysis/scan/exprs/access.h
+++ b/src/analysis/scan/exprs/access.h
@@ -53,10 +53,10 @@ GType g_scan_named_access_get_type(void);
GScanExpression *g_scan_named_access_new(const sized_string_t *);
/* Reproduit un accès en place dans une nouvelle instance. */
-GScanExpression *g_scan_named_access_duplicate(const GScanNamedAccess *, GRegisteredItem *);
+GScanExpression *g_scan_named_access_duplicate(const GScanNamedAccess *, GScanRegisteredItem *);
/* Définit une base de recherche pour la cible d'accès. */
-void g_scan_named_access_set_base(GScanNamedAccess *, GRegisteredItem *);
+void g_scan_named_access_set_base(GScanNamedAccess *, GScanRegisteredItem *);
/* Complète la chaine d'accès à des expressions. */
void g_scan_named_access_attach_next(GScanNamedAccess *, GScanNamedAccess *);
diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c
index f68159f..3997ff6 100644
--- a/src/analysis/scan/exprs/call.c
+++ b/src/analysis/scan/exprs/call.c
@@ -264,16 +264,16 @@ static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *exp
{
ScanReductionState result; /* Etat synthétisé à retourner */
GScanNamedAccess *access; /* Autre vision de l'expression*/
- GRegisteredItem *resolved; /* Cible concrète obtenue */
+ GScanRegisteredItem *resolved; /* Cible concrète obtenue */
size_t i; /* Boucle de parcours #1 */
GScanExpression *arg; /* Argument réduit à échanger */
GScanExpression *new; /* Nouvelle réduction obtenue */
ScanReductionState state; /* Etat synthétisé d'un élément*/
size_t k; /* Boucle de parcours #2 */
GScanExpression **new_args; /* Nouvelle séquence d'args. */
- GScanExpression *new_next; /* Nouvelle version du suivant */
GObject *final; /* Expression ou élément ? */
bool valid; /* Validité de l'élément */
+ GScanExpression *new_next; /* Nouvelle version du suivant */
access = G_SCAN_NAMED_ACCESS(expr);
@@ -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));
+
}
}
@@ -358,15 +362,15 @@ static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *exp
else if (result == SRS_PENDING)
{
if (new_args == NULL)
- valid = g_registered_item_run_call(resolved,
- expr->args,
- expr->count,
- ctx, scope, &final);
+ valid = g_scan_registered_item_run_call(resolved,
+ expr->args,
+ expr->count,
+ ctx, scope, &final);
else
- valid = g_registered_item_run_call(resolved,
- new_args,
- expr->count,
- ctx, scope, &final);
+ valid = g_scan_registered_item_run_call(resolved,
+ new_args,
+ expr->count,
+ ctx, scope, &final);
if (valid && final != NULL)
{
@@ -376,7 +380,7 @@ static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *exp
*
* Ce cas de figure ne se rencontre normalement qu'en bout de chaîne.
*/
- if (!G_IS_REGISTERED_ITEM(final))
+ if (!G_IS_SCAN_REGISTERED_ITEM(final))
{
if (access->next != NULL)
result = SRS_UNRESOLVABLE;
@@ -395,7 +399,7 @@ static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *exp
{
assert(access->next != NULL);
- new_next = g_scan_named_access_duplicate(access->next, G_REGISTERED_ITEM(final));
+ new_next = g_scan_named_access_duplicate(access->next, G_SCAN_REGISTERED_ITEM(final));
result = g_scan_expression_reduce(new_next, ctx, scope, out);
diff --git a/src/analysis/scan/exprs/counter-int.h b/src/analysis/scan/exprs/counter-int.h
deleted file mode 100644
index 8c5e56b..0000000
--- a/src/analysis/scan/exprs/counter-int.h
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * counter-int.h - prototypes internes pour le décompte de correspondances identifiées dans du contenu binaire
- *
- * Copyright (C) 2023 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_EXPRS_COUNTER_INT_H
-#define _ANALYSIS_SCAN_EXPRS_COUNTER_INT_H
-
-
-#include "counter.h"
-
-
-#include "../expr-int.h"
-
-
-
-/* Décompte des identifications de motifs (instance) */
-struct _GScanMatchCounter
-{
- GScanExpression parent; /* A laisser en premier */
-
- GSearchPattern *pattern; /* Motif associé */
-
-};
-
-/* Décompte des identifications de motifs (classe) */
-struct _GScanMatchCounterClass
-{
- GScanExpressionClass parent; /* A laisser en premier */
-
-};
-
-
-/* Met en place un compteur de correspondances. */
-bool g_scan_match_counter_create(GScanMatchCounter *, GSearchPattern *);
-
-
-
-#endif /* _ANALYSIS_SCAN_EXPRS_COUNTER_INT_H */
diff --git a/src/analysis/scan/exprs/counter.c b/src/analysis/scan/exprs/counter.c
deleted file mode 100644
index 7fadb91..0000000
--- a/src/analysis/scan/exprs/counter.c
+++ /dev/null
@@ -1,251 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * counter.c - décompte de correspondances identifiées dans du contenu binaire
- *
- * Copyright (C) 2023 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "counter.h"
-
-
-#include "counter-int.h"
-#include "literal.h"
-
-
-
-/* --------------------- INSTANCIATION D'UNE FORME DE CONDITION --------------------- */
-
-
-/* Initialise la classe des opérations booléennes. */
-static void g_scan_match_counter_class_init(GScanMatchCounterClass *);
-
-/* Initialise une instance d'opération booléenne. */
-static void g_scan_match_counter_init(GScanMatchCounter *);
-
-/* Supprime toutes les références externes. */
-static void g_scan_match_counter_dispose(GScanMatchCounter *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_scan_match_counter_finalize(GScanMatchCounter *);
-
-
-
-/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-
-
-/* Réduit une expression à une forme plus simple. */
-static ScanReductionState g_scan_match_counter_reduce(const GScanMatchCounter *, GScanContext *, GScanScope *, GScanExpression **);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* INSTANCIATION D'UNE FORME DE CONDITION */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour un décompte de résultats lors d'une recherche de motifs. */
-G_DEFINE_TYPE(GScanMatchCounter, g_scan_match_counter, G_TYPE_SCAN_EXPRESSION);
-
-
-/******************************************************************************
-* *
-* Paramètres : klass = classe à initialiser. *
-* *
-* Description : Initialise la classe des opérations booléennes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_match_counter_class_init(GScanMatchCounterClass *klass)
-{
- GObjectClass *object; /* Autre version de la classe */
- GScanExpressionClass *expr; /* Version de classe parente */
-
- object = G_OBJECT_CLASS(klass);
-
- object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_match_counter_dispose;
- object->finalize = (GObjectFinalizeFunc)g_scan_match_counter_finalize;
-
- expr = G_SCAN_EXPRESSION_CLASS(klass);
-
- expr->cmp_rich = (compare_expr_rich_fc)NULL;
- expr->reduce = (reduce_expr_fc)g_scan_match_counter_reduce;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance à initialiser. *
-* *
-* Description : Initialise une instance d'opération booléenne. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_match_counter_init(GScanMatchCounter *counter)
-{
- counter->pattern = NULL;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_match_counter_dispose(GScanMatchCounter *counter)
-{
- g_clear_object(&counter->pattern);
-
- G_OBJECT_CLASS(g_scan_match_counter_parent_class)->dispose(G_OBJECT(counter));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : op = instance d'objet GLib à traiter. *
-* *
-* Description : Procède à la libération totale de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_scan_match_counter_finalize(GScanMatchCounter *counter)
-{
- G_OBJECT_CLASS(g_scan_match_counter_parent_class)->finalize(G_OBJECT(counter));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : pattern = motif à impliquer. *
-* *
-* Description : Met en place un décompte de correspondances obtenues. *
-* *
-* Retour : Expression mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GScanExpression *g_scan_match_counter_new(GSearchPattern *pattern)
-{
- GScanExpression *result; /* Structure à retourner */
-
- result = g_object_new(G_TYPE_SCAN_MATCH_COUNTER, NULL);
-
- if (!g_scan_match_counter_create(G_SCAN_MATCH_COUNTER(result), pattern))
- g_clear_object(&result);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : counter = instance à initialiser pleinement. *
-* pattern = motif à impliquer. *
-* *
-* Description : Met en place un compteur de correspondances. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_scan_match_counter_create(GScanMatchCounter *counter, GSearchPattern *pattern)
-{
- bool result; /* Bilan à retourner */
-
- result = g_scan_expression_create(G_SCAN_EXPRESSION(counter), SRS_WAIT_FOR_SCAN);
- if (!result) goto exit;
-
- counter->pattern = pattern;
- g_object_ref(G_OBJECT(pattern));
-
- exit:
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : expr = expression à consulter. *
-* ctx = contexte de suivi de l'analyse courante. *
-* scope = portée courante des variables locales. *
-* out = zone d'enregistrement de la réduction opérée. [OUT] *
-* *
-* Description : Réduit une expression à une forme plus simple. *
-* *
-* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static ScanReductionState g_scan_match_counter_reduce(const GScanMatchCounter *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
-{
- ScanReductionState result; /* Etat synthétisé à retourner */
- size_t count; /* Quantité de correspondances */
-
- if (g_scan_context_is_scan_done(ctx))
- {
- g_scan_context_get_full_matches(ctx, expr->pattern, &count);
-
- *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, (unsigned long long []){ count });
-
- result = SRS_REDUCED;
-
- }
- else
- result = SRS_WAIT_FOR_SCAN;
-
- return result;
-
-}
diff --git a/src/analysis/scan/exprs/counter.h b/src/analysis/scan/exprs/counter.h
deleted file mode 100644
index c90953e..0000000
--- a/src/analysis/scan/exprs/counter.h
+++ /dev/null
@@ -1,59 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * counter.h - prototypes pour le décompte de correspondances identifiées dans du contenu binaire
- *
- * Copyright (C) 2023 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chrysalide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_SCAN_EXPRS_COUNTER_H
-#define _ANALYSIS_SCAN_EXPRS_COUNTER_H
-
-
-#include <glib-object.h>
-
-
-#include "../expr.h"
-#include "../pattern.h"
-
-
-
-#define G_TYPE_SCAN_MATCH_COUNTER g_scan_match_counter_get_type()
-#define G_SCAN_MATCH_COUNTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_MATCH_COUNTER, GScanMatchCounter))
-#define G_IS_SCAN_MATCH_COUNTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_MATCH_COUNTER))
-#define G_SCAN_MATCH_COUNTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_MATCH_COUNTER, GScanMatchCounterClass))
-#define G_IS_SCAN_MATCH_COUNTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_MATCH_COUNTER))
-#define G_SCAN_MATCH_COUNTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_MATCH_COUNTER, GScanMatchCounterClass))
-
-
-/* Décompte des identifications de motifs (instance) */
-typedef struct _GScanMatchCounter GScanMatchCounter;
-
-/* Décompte des identifications de motifs (classe) */
-typedef struct _GScanMatchCounterClass GScanMatchCounterClass;
-
-
-/* Indique le type défini pour un décompte de résultats lors d'une recherche de motifs. */
-GType g_scan_match_counter_get_type(void);
-
-/* Met en place un décompte de correspondances obtenues. */
-GScanExpression *g_scan_match_counter_new(GSearchPattern *);
-
-
-
-#endif /* _ANALYSIS_SCAN_EXPRS_COUNTER_H */
diff --git a/src/analysis/scan/exprs/extract-int.h b/src/analysis/scan/exprs/extract-int.h
new file mode 100644
index 0000000..562e537
--- /dev/null
+++ b/src/analysis/scan/exprs/extract-int.h
@@ -0,0 +1,57 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * extract-int.h - prototypes internes pour l'organisation d'une extraction d'un élément d'une série interne
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_EXTRACT_INT_H
+#define _ANALYSIS_SCAN_EXPRS_EXTRACT_INT_H
+
+
+#include "extract.h"
+
+
+#include "access-int.h"
+
+
+
+/* Extraction d'un élément donné au sein d'une série interne (instance) */
+struct _GScanPendingExtraction
+{
+ GScanNamedAccess parent; /* A laisser en premier */
+
+ GScanExpression *index; /* Arguments d'appel fournis */
+
+};
+
+/* Extraction d'un élément donné au sein d'une série interne (classe) */
+struct _GScanPendingExtractionClass
+{
+ GScanNamedAccessClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une expression d'extraction d'élément interne. */
+bool g_scan_pending_extraction_create(GScanPendingExtraction *, const sized_string_t *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_EXTRACT_INT_H */
diff --git a/src/analysis/scan/exprs/extract.c b/src/analysis/scan/exprs/extract.c
new file mode 100644
index 0000000..b140ed9
--- /dev/null
+++ b/src/analysis/scan/exprs/extract.c
@@ -0,0 +1,396 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * extract.c - organisation d'une extraction d'un élément d'une série interne
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "extract.h"
+
+
+#include <assert.h>
+#include <string.h>
+
+
+#include "extract-int.h"
+#include "../../../core/global.h"
+
+
+
+/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */
+
+
+/* Initialise la classe des extractions d'éléments internes. */
+static void g_scan_pending_extraction_class_init(GScanPendingExtractionClass *);
+
+/* Initialise une instance d'extraction d'élément interne. */
+static void g_scan_pending_extraction_init(GScanPendingExtraction *);
+
+/* Supprime toutes les références externes. */
+static void g_scan_pending_extraction_dispose(GScanPendingExtraction *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_scan_pending_extraction_finalize(GScanPendingExtraction *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Réduit une expression à une forme plus simple. */
+static ScanReductionState g_scan_pending_extraction_reduce(const GScanPendingExtraction *, GScanContext *, GScanScope *, GScanExpression **);
+
+/* Reproduit un accès en place dans une nouvelle instance. */
+static void g_scan_pending_extraction_copy(GScanPendingExtraction *, const GScanPendingExtraction *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour une extraction d'élément de série interne. */
+G_DEFINE_TYPE(GScanPendingExtraction, g_scan_pending_extraction, G_TYPE_SCAN_NAMED_ACCESS);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des extractions d'éléments internes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_pending_extraction_class_init(GScanPendingExtractionClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GScanExpressionClass *expr; /* Version de classe parente */
+ GScanNamedAccessClass *access; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_pending_extraction_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_scan_pending_extraction_finalize;
+
+ expr = G_SCAN_EXPRESSION_CLASS(klass);
+
+ expr->cmp_rich = (compare_expr_rich_fc)NULL;
+ expr->reduce = (reduce_expr_fc)g_scan_pending_extraction_reduce;
+
+ access = G_SCAN_NAMED_ACCESS_CLASS(klass);
+
+ access->copy = (copy_scan_access_fc)g_scan_pending_extraction_copy;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : extract = instance à initialiser. *
+* *
+* Description : Initialise une instance d'extraction d'élément interne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_pending_extraction_init(GScanPendingExtraction *extract)
+{
+ extract->index = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : extract = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_pending_extraction_dispose(GScanPendingExtraction *extract)
+{
+ g_clear_object(&extract->index);
+
+ G_OBJECT_CLASS(g_scan_pending_extraction_parent_class)->dispose(G_OBJECT(extract));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : extract = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_pending_extraction_finalize(GScanPendingExtraction *extract)
+{
+ G_OBJECT_CLASS(g_scan_pending_extraction_parent_class)->finalize(G_OBJECT(extract));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = désignation de l'objet d'appel à identifier. *
+* index = indice de l'élément à extraire. *
+* *
+* Description : Organise l'extraction d'un élément d'une série interne. *
+* *
+* Retour : Fonction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_scan_pending_extraction_new(const sized_string_t *target, GScanExpression *index)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_PENDING_EXTRACTION, NULL);
+
+ if (!g_scan_pending_extraction_create(G_SCAN_PENDING_EXTRACTION(result), target, index))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : extract = instance à initialiser pleinement. *
+* target = désignation de l'objet d'appel à identifier. *
+* index = indice de l'élément à extraire. *
+* *
+* Description : Met en place une expression d'extraction d'élément interne. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_scan_pending_extraction_create(GScanPendingExtraction *extract, const sized_string_t *target, GScanExpression *index)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_scan_named_access_create(G_SCAN_NAMED_ACCESS(extract), target);
+ if (!result) goto exit;
+
+ extract->index = index;
+ g_object_ref(G_OBJECT(index));
+
+ exit:
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* ctx = contexte de suivi de l'analyse courante. *
+* scope = portée courante des variables locales. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
+* *
+* Description : Réduit une expression à une forme plus simple. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static ScanReductionState g_scan_pending_extraction_reduce(const GScanPendingExtraction *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
+{
+ ScanReductionState result; /* Etat synthétisé à retourner */
+ GScanNamedAccess *access; /* Autre vision de l'expression*/
+ GScanRegisteredItem *resolved; /* Cible concrète obtenue */
+ GScanExpression *new; /* Nouvelle réduction obtenue */
+ GObject *final; /* Expression ou élément ? */
+ GScanExpression *new_next; /* Nouvelle version du suivant */
+
+ access = G_SCAN_NAMED_ACCESS(expr);
+
+ resolved = _g_scan_named_access_prepare_reduction(access, ctx, scope);
+
+ if (resolved == NULL)
+ result = SRS_UNRESOLVABLE;
+
+ else
+ {
+ /* Actualisation nécessaire des arguments ? */
+
+ result = g_scan_expression_reduce(expr->index, ctx, scope, &new);
+
+ /* Suite des traitements */
+
+ if (result == SRS_WAIT_FOR_SCAN)
+ {
+ /**
+ * Si changement il y a eu...
+ */
+ if (new != expr->index)
+ {
+ *out = g_scan_pending_extraction_new(NULL, new);
+
+ /**
+ * Fonctionnement équivalent de :
+ * g_scan_named_access_set_base(G_SCAN_NAMED_ACCESS(*out), resolved);
+ */
+ G_SCAN_NAMED_ACCESS(*out)->resolved = resolved;
+ g_object_ref(G_OBJECT(resolved));
+
+ if (G_SCAN_NAMED_ACCESS(expr)->next != NULL)
+ g_scan_named_access_attach_next(G_SCAN_NAMED_ACCESS(*out), G_SCAN_NAMED_ACCESS(expr)->next);
+
+ }
+
+ }
+
+ else if (result == SRS_REDUCED)
+ {
+ final = g_scan_registered_item_extract_at(resolved, new, ctx, scope);
+
+ if (final != NULL)
+ {
+ /**
+ * Si le produit de l'appel à la fonction est une expression d'évaluation
+ * classique, alors ce produit constitue la réduction finale de la chaîne.
+ *
+ * Ce cas de figure ne se rencontre normalement qu'en bout de chaîne.
+ */
+ if (!G_IS_SCAN_REGISTERED_ITEM(final))
+ {
+ if (access->next != NULL)
+ result = SRS_UNRESOLVABLE;
+
+ else
+ {
+ *out = G_SCAN_EXPRESSION(final);
+ g_object_ref(G_OBJECT(final));
+
+ result = SRS_REDUCED;
+
+ }
+
+ }
+ else
+ {
+ if (access->next != NULL)
+ {
+ new_next = g_scan_named_access_duplicate(access->next, G_SCAN_REGISTERED_ITEM(final));
+
+ result = g_scan_expression_reduce(new_next, ctx, scope, out);
+
+ g_object_unref(G_OBJECT(new_next));
+
+ }
+
+ /**
+ * Le cas ci-après est typique de l'extension Kaitai : field[n]
+ * renvoie vers une instance GScanRegisteredItem (GKaitaiBrowser).
+ *
+ * Il n'y a donc pas d'expression en jeu, et l'élément est le dernier
+ * de la liste.
+ */
+ else
+ {
+ if (g_scan_registered_item_reduce(G_SCAN_REGISTERED_ITEM(final), ctx, scope, out))
+ result = SRS_REDUCED;
+ else
+ result = SRS_UNRESOLVABLE;
+
+ }
+
+ }
+
+ }
+
+ else
+ result = SRS_UNRESOLVABLE;
+
+ g_clear_object(&final);
+
+ }
+
+ /* Libération locale des arguments reconstruits */
+
+ g_clear_object(&new);
+
+ g_object_unref(G_OBJECT(resolved));
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] *
+* src = expression source à copier. *
+* *
+* Description : Reproduit un accès en place dans une nouvelle instance. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_pending_extraction_copy(GScanPendingExtraction *dest, const GScanPendingExtraction *src)
+{
+ GScanNamedAccessClass *class; /* Classe parente à solliciter */
+
+ class = G_SCAN_NAMED_ACCESS_CLASS(g_scan_pending_extraction_parent_class);
+
+ class->copy(G_SCAN_NAMED_ACCESS(dest), G_SCAN_NAMED_ACCESS(src));
+
+ dest->index = src->index;
+ g_object_ref(G_OBJECT(src->index));
+
+}
diff --git a/src/analysis/scan/exprs/extract.h b/src/analysis/scan/exprs/extract.h
new file mode 100644
index 0000000..8ed1cfa
--- /dev/null
+++ b/src/analysis/scan/exprs/extract.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * extract.h - prototypes pour l'organisation d'une extraction d'un élément d'une série interne
+ *
+ * Copyright (C) 2023 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_SCAN_EXPRS_EXTRACT_H
+#define _ANALYSIS_SCAN_EXPRS_EXTRACT_H
+
+
+#include "../expr.h"
+#include "../../../common/szstr.h"
+
+
+
+#define G_TYPE_SCAN_PENDING_EXTRACTION g_scan_pending_extraction_get_type()
+#define G_SCAN_PENDING_EXTRACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SCAN_PENDING_EXTRACTION, GScanPendingExtraction))
+#define G_IS_SCAN_PENDING_EXTRACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SCAN_PENDING_EXTRACTION))
+#define G_SCAN_PENDING_EXTRACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SCAN_PENDING_EXTRACTION, GScanPendingExtractionClass))
+#define G_IS_SCAN_PENDING_EXTRACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SCAN_PENDING_EXTRACTION))
+#define G_SCAN_PENDING_EXTRACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SCAN_PENDING_EXTRACTION, GScanPendingExtractionClass))
+
+
+/* Extraction d'un élément donné au sein d'une série interne (instance) */
+typedef struct _GScanPendingExtraction GScanPendingExtraction;
+
+/* Extraction d'un élément donné au sein d'une série interne (classe) */
+typedef struct _GScanPendingExtractionClass GScanPendingExtractionClass;
+
+
+/* Indique le type défini pour une extraction d'élément de série interne. */
+GType g_scan_pending_extraction_get_type(void);
+
+/* Organise l'extraction d'un élément d'une série interne. */
+GScanExpression *g_scan_pending_extraction_new(const sized_string_t *, GScanExpression *);
+
+
+
+#endif /* _ANALYSIS_SCAN_EXPRS_EXTRACT_H */
diff --git a/src/analysis/scan/exprs/handler-int.h b/src/analysis/scan/exprs/handler-int.h
index f707fdb..e051b30 100644
--- a/src/analysis/scan/exprs/handler-int.h
+++ b/src/analysis/scan/exprs/handler-int.h
@@ -37,7 +37,14 @@ struct _GScanPatternHandler
{
GScanExpression parent; /* A laisser en premier */
- GSearchPattern *pattern; /* Motif associé */
+ union
+ {
+ const GSearchPattern **patterns; /* Motifs associés */
+ GSearchPattern **ref_patterns; /* Motifs associés */
+ };
+ size_t count; /* Nombre de ces motifs */
+ bool shared; /* Définition de propriété */
+
ScanHandlerType type; /* Manipulation attendue */
};
@@ -51,7 +58,10 @@ struct _GScanPatternHandlerClass
/* Met en place une manipulation de correspondances établies. */
-bool g_scan_pattern_handler_create(GScanPatternHandler *, GSearchPattern *, ScanHandlerType);
+bool g_scan_pattern_handler_create_shared(GScanPatternHandler *, const GSearchPattern ** const, size_t, ScanHandlerType);
+
+/* Met en place une manipulation de correspondances établies. */
+bool g_scan_pattern_handler_create_and_ref(GScanPatternHandler *, GSearchPattern ** const, size_t, ScanHandlerType);
diff --git a/src/analysis/scan/exprs/handler.c b/src/analysis/scan/exprs/handler.c
index 1676522..2706dae 100644
--- a/src/analysis/scan/exprs/handler.c
+++ b/src/analysis/scan/exprs/handler.c
@@ -122,7 +122,10 @@ static void g_scan_pattern_handler_class_init(GScanPatternHandlerClass *klass)
static void g_scan_pattern_handler_init(GScanPatternHandler *handler)
{
- handler->pattern = NULL;
+ handler->patterns = NULL;
+ handler->count = 0;
+ handler->shared = true;
+
handler->type = SHT_RAW;
}
@@ -142,7 +145,11 @@ static void g_scan_pattern_handler_init(GScanPatternHandler *handler)
static void g_scan_pattern_handler_dispose(GScanPatternHandler *handler)
{
- g_clear_object(&handler->pattern);
+ size_t i; /* Boucle de parcours */
+
+ if (!handler->shared)
+ for (i = 0; i < handler->count; i++)
+ g_clear_object(&handler->ref_patterns[i]);
G_OBJECT_CLASS(g_scan_pattern_handler_parent_class)->dispose(G_OBJECT(handler));
@@ -163,6 +170,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));
}
@@ -170,8 +180,9 @@ static void g_scan_pattern_handler_finalize(GScanPatternHandler *handler)
/******************************************************************************
* *
-* Paramètres : pattern = motif à impliquer. *
-* type = type de manipulation attendue. *
+* Paramètres : patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* type = type de manipulation attendue. *
* *
* Description : Met en place une manipulation de correspondances établies. *
* *
@@ -181,13 +192,13 @@ static void g_scan_pattern_handler_finalize(GScanPatternHandler *handler)
* *
******************************************************************************/
-GScanExpression *g_scan_pattern_handler_new(GSearchPattern *pattern, ScanHandlerType type)
+GScanExpression *g_scan_pattern_handler_new_shared(const GSearchPattern ** const patterns, size_t count, ScanHandlerType type)
{
GScanExpression *result; /* Structure à retourner */
result = g_object_new(G_TYPE_SCAN_PATTERN_HANDLER, NULL);
- if (!g_scan_pattern_handler_create(G_SCAN_PATTERN_HANDLER(result), pattern, type))
+ if (!g_scan_pattern_handler_create_shared(G_SCAN_PATTERN_HANDLER(result), patterns, count, type))
g_clear_object(&result);
return result;
@@ -197,9 +208,10 @@ GScanExpression *g_scan_pattern_handler_new(GSearchPattern *pattern, ScanHandler
/******************************************************************************
* *
-* Paramètres : handler = instance à initialiser pleinement. *
-* pattern = motif à impliquer. *
-* type = type de manipulation attendue. *
+* Paramètres : handler = instance à initialiser pleinement. *
+* patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* type = type de manipulation attendue. *
* *
* Description : Met en place une manipulation de correspondances établies. *
* *
@@ -209,15 +221,19 @@ GScanExpression *g_scan_pattern_handler_new(GSearchPattern *pattern, ScanHandler
* *
******************************************************************************/
-bool g_scan_pattern_handler_create(GScanPatternHandler *handler, GSearchPattern *pattern, ScanHandlerType type)
+bool g_scan_pattern_handler_create_shared(GScanPatternHandler *handler, const GSearchPattern ** const patterns, size_t count, ScanHandlerType type)
{
bool result; /* Bilan à retourner */
result = g_scan_expression_create(G_SCAN_EXPRESSION(handler), SRS_WAIT_FOR_SCAN);
if (!result) goto exit;
- handler->pattern = pattern;
- g_object_ref(G_OBJECT(pattern));
+ handler->patterns = malloc(count * sizeof(GSearchPattern *));
+ handler->count = count;
+
+ memcpy(handler->patterns, patterns, count * sizeof(GSearchPattern *));
+
+ handler->shared = true;
handler->type = type;
@@ -228,6 +244,159 @@ bool g_scan_pattern_handler_create(GScanPatternHandler *handler, GSearchPattern
}
+/******************************************************************************
+* *
+* Paramètres : patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* type = type de manipulation attendue. *
+* *
+* Description : Met en place une manipulation de correspondances établies. *
+* *
+* Retour : Expression mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanExpression *g_scan_pattern_handler_new(GSearchPattern ** const patterns, size_t count, ScanHandlerType type)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_PATTERN_HANDLER, NULL);
+
+ if (!g_scan_pattern_handler_create_and_ref(G_SCAN_PATTERN_HANDLER(result), patterns, count, type))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : handler = instance à initialiser pleinement. *
+* patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* type = type de manipulation attendue. *
+* *
+* Description : Met en place une manipulation de correspondances établies. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_scan_pattern_handler_create_and_ref(GScanPatternHandler *handler, GSearchPattern ** const patterns, size_t count, ScanHandlerType type)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = g_scan_expression_create(G_SCAN_EXPRESSION(handler), SRS_WAIT_FOR_SCAN);
+ if (!result) goto exit;
+
+ handler->patterns = malloc(count * sizeof(GSearchPattern *));
+ handler->count = count;
+
+ memcpy(handler->patterns, patterns, count * sizeof(GSearchPattern *));
+
+ for (i = 0; i < count; i++)
+ g_object_ref(G_OBJECT(patterns[i]));
+
+ handler->shared = false;
+
+ handler->type = type;
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : handler = instance à initialiser pleinement. *
+* *
+* Description : Indique le type de manipulation de correspondances spécifié. *
+* *
+* Retour : Type de manipulation de correspondances représentée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+ScanHandlerType g_scan_pattern_handler_get_handler_type(const GScanPatternHandler *handler)
+{
+ ScanHandlerType result; /* Nature à retourner */
+
+ result = handler->type;
+
+ return result;
+
+}
+
+
+#if 0 /* FIXME */
+
+/******************************************************************************
+* *
+* Paramètres : handler = instance à initialiser pleinement. *
+* ctx = contexte de suivi de l'analyse courante. *
+* count = quantité de correspondances enregistrées. [OUT] *
+* *
+* Description : Fournit la liste de toutes les correspondances représentées. *
+* *
+* Retour : Liste courante de correspondances établies. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GScanMatch **g_scan_pattern_handler_get_all_matches(const GScanPatternHandler *handler, GScanContext *ctx, size_t *count)
+{
+ GScanMatch **result; /* Liste à retourner */
+ size_t used; /* Indice pour le stockage */
+ size_t i; /* Boucle de parcours #1 */
+ size_t partial; /* Décompte partiel */
+ const GScanMatch **matches; /* Correspondances en place */
+ size_t k; /* Boucle de parcours #2 */
+
+ result = NULL;
+
+ if (!g_scan_pattern_handler_count_items(handler, ctx, count))
+ {
+ *count = 0;
+ goto exit;
+ }
+
+ if (*count == 0)
+ goto exit;
+
+ result = malloc(*count * sizeof(GScanMatch *));
+
+ used = 0;
+
+ for (i = 0; i < handler->count; i++)
+ {
+ matches = g_scan_context_get_full_matches(ctx, handler->patterns[i], &partial);
+
+ for (k = 0; k < partial; k++)
+ {
+ result[used++] = matches[k];
+ g_object_ref(G_OBJECT(matches[k]));
+ }
+
+ }
+
+ exit:
+
+ return result;
+
+}
+#endif
+
+
/* ---------------------------------------------------------------------------------- */
/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
@@ -252,9 +421,27 @@ bool g_scan_pattern_handler_create(GScanPatternHandler *handler, GSearchPattern
static ScanReductionState g_scan_pattern_handler_reduce(const GScanPatternHandler *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out)
{
ScanReductionState result; /* Etat synthétisé à retourner */
+ size_t count; /* Quantité de correspondances */
if (g_scan_context_is_scan_done(ctx))
- result = SRS_REDUCED;
+ {
+ if (expr->type == SHT_COUNTER)
+ {
+ if (!g_scan_pattern_handler_count_items(expr, ctx, &count))
+ result = SRS_UNRESOLVABLE;
+
+ else
+ {
+ result = SRS_REDUCED;
+ *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, (unsigned long long []){ count });
+ }
+
+ }
+
+ else
+ result = SRS_REDUCED;
+
+ }
else
result = SRS_WAIT_FOR_SCAN;
@@ -284,9 +471,7 @@ static bool g_scan_pattern_handler_reduce_to_boolean(const GScanPatternHandler *
bool result; /* Bilan à retourner */
size_t count; /* Quantité de correspondances */
- result = true;
-
- g_scan_context_get_full_matches(ctx, expr->pattern, &count);
+ result = g_scan_pattern_handler_count_items(expr, ctx, &count);
*out = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []){ count > 0 });
@@ -312,12 +497,16 @@ static bool g_scan_pattern_handler_reduce_to_boolean(const GScanPatternHandler *
static bool g_scan_pattern_handler_count_items(const GScanPatternHandler *expr, GScanContext *ctx, size_t *count)
{
bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
result = true;
assert(g_scan_context_is_scan_done(ctx));
- g_scan_context_get_full_matches(ctx, expr->pattern, count);
+ *count = 0;
+
+ for (i = 0; i < expr->count; i++)
+ *count += g_scan_context_count_full_matches(ctx, expr->patterns[i]);
return result;
@@ -342,62 +531,90 @@ static bool g_scan_pattern_handler_count_items(const GScanPatternHandler *expr,
static bool g_scan_pattern_handler_get_item(const GScanPatternHandler *expr, size_t index, GScanContext *ctx, GScanExpression **out)
{
bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
size_t count; /* Quantité de correspondances */
- const GScanMatch **matches; /* Correspondances en place */
- const GScanBytesMatch *match; /* Correspondance ciblée */
- phys_t start; /* Point de départ du motif */
- phys_t end; /* Point d'arrivée du motif */
- phys_t len; /* Taille du motif */
+ GScanMatches *matches; /* Correspondances d'un motif */
+ const match_area_t *area; /* Zone de correspondance */
GBinContent *content; /* Contenu binaire à relire */
vmpa2t pos; /* Tête de lecture */
const bin_t *data; /* Accès aux données brutes */
sized_string_t binary; /* Conversion de formats */
+ result = false;
+
assert(g_scan_context_is_scan_done(ctx));
- matches = g_scan_context_get_full_matches(ctx, expr->pattern, &count);
+ /* Identification du motif concerné */
+
+ for (i = 0; i < expr->count; i++)
+ {
+ count = g_scan_context_count_full_matches(ctx, expr->patterns[i]);
+
+ if (index < count)
+ break;
+ else
+ index -= count;
+
+ }
+
+ if (i == expr->count) goto done;
- result = (index < count);
- if (!result) goto done;
+ /* Identification de la correspondance concernée */
- result = G_IS_SCAN_BYTES_MATCH(matches[index]);
- if (!result) goto done;
+ matches = g_scan_context_get_full_matches(ctx, expr->patterns[i]);
+ if (matches == NULL) goto done;
- match = G_SCAN_BYTES_MATCH(matches[index]);
+ area = g_scan_bytes_matches_get(G_SCAN_BYTES_MATCHES(matches), index);
+ if (area == NULL) goto done_with_matches;
- len = g_scan_bytes_match_get_location(match, &start, &end);
+ /* Traitement adapté de la requête */
switch (expr->type)
{
case SHT_RAW:
- content = g_scan_bytes_match_get_content(match);
+ content = g_scan_context_get_content(ctx);
- init_vmpa(&pos, start, VMPA_NO_VIRTUAL);
+ init_vmpa(&pos, area->start, VMPA_NO_VIRTUAL);
- data = g_binary_content_get_raw_access(content, &pos, len);
+ data = g_binary_content_get_raw_access(content, &pos, area->end - area->start);
- binary.data = data;
- binary.len = len;
+ binary.static_bin_data = data;
+ binary.len = area->end - area->start;
*out = g_scan_literal_expression_new(LVT_STRING, &binary);
g_object_unref(G_OBJECT(content));
+ result = true;
+ break;
+
+ case SHT_COUNTER:
+ assert(false);
break;
case SHT_START:
- *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, (unsigned long long []){ start });
+ *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER,
+ (unsigned long long []){ area->start });
+ result = true;
break;
case SHT_LENGTH:
- *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, (unsigned long long []){ len });
+ *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER,
+ (unsigned long long []){ area->end - area->start });
+ result = true;
break;
case SHT_END:
- *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER, (unsigned long long []){ end });
+ *out = g_scan_literal_expression_new(LVT_UNSIGNED_INTEGER,
+ (unsigned long long []){ area->end });
+ result = true;
break;
}
+ done_with_matches:
+
+ g_object_unref(G_OBJECT(matches));
+
done:
return result;
diff --git a/src/analysis/scan/exprs/handler.h b/src/analysis/scan/exprs/handler.h
index 8ad700a..a1ddf98 100644
--- a/src/analysis/scan/exprs/handler.h
+++ b/src/analysis/scan/exprs/handler.h
@@ -48,6 +48,7 @@ typedef struct _GScanPatternHandlerClass GScanPatternHandlerClass;
typedef enum _ScanHandlerType
{
SHT_RAW, /* Correspondances brutes */
+ SHT_COUNTER, /* Dénombrement de résultats */
SHT_START, /* Départs de correspondances */
SHT_LENGTH, /* Taille de correspondances */
SHT_END, /* Fins de correspondances */
@@ -59,7 +60,20 @@ typedef enum _ScanHandlerType
GType g_scan_pattern_handler_get_type(void);
/* Met en place une manipulation de correspondances établies. */
-GScanExpression *g_scan_pattern_handler_new(GSearchPattern *, ScanHandlerType);
+GScanExpression *g_scan_pattern_handler_new_shared(const GSearchPattern ** const, size_t, ScanHandlerType);
+
+/* Met en place une manipulation de correspondances établies. */
+GScanExpression *g_scan_pattern_handler_new(GSearchPattern ** const, size_t, ScanHandlerType);
+
+/* Indique le type de manipulation de correspondances spécifié. */
+ScanHandlerType g_scan_pattern_handler_get_handler_type(const GScanPatternHandler *);
+
+#if 0 /* FIXME */
+
+/* Fournit la liste de toutes les correspondances représentées. */
+GScanMatch **g_scan_pattern_handler_get_all_matches(const GScanPatternHandler *, GScanContext *, size_t *);
+
+#endif
diff --git a/src/analysis/scan/exprs/item.c b/src/analysis/scan/exprs/item.c
index b7cd970..a5a6fdf 100644
--- a/src/analysis/scan/exprs/item.c
+++ b/src/analysis/scan/exprs/item.c
@@ -308,6 +308,7 @@ static ScanReductionState g_scan_set_item_reduce(const GScanSetItem *expr, GScan
status = g_scan_expression_get_item(expr->set, val_s, ctx, out);
}
+
else if (vtype == LVT_UNSIGNED_INTEGER)
{
if (!g_scan_literal_expression_get_unsigned_integer_value(op_index, &val_u))
@@ -320,6 +321,9 @@ static ScanReductionState g_scan_set_item_reduce(const GScanSetItem *expr, GScan
}
+ else
+ status = false;
+
result = (status ? SRS_REDUCED : SRS_UNRESOLVABLE);
}
diff --git a/src/analysis/scan/exprs/literal.c b/src/analysis/scan/exprs/literal.c
index de7e32a..b7aed5b 100644
--- a/src/analysis/scan/exprs/literal.c
+++ b/src/analysis/scan/exprs/literal.c
@@ -62,6 +62,9 @@ static bool g_scan_literal_expression_reduce_to_boolean(const GScanLiteralExpres
/* Dénombre les éléments portés par une expression. */
static bool g_scan_literal_expression_count(const GScanLiteralExpression *, GScanContext *, size_t *);
+/* Fournit un élément donné issu d'un ensemble constitué. */
+static bool g_scan_literal_expression_get_item(const GScanLiteralExpression *, size_t, GScanContext *, GScanExpression **);
+
/* ---------------------------------------------------------------------------------- */
@@ -100,6 +103,7 @@ static void g_scan_literal_expression_class_init(GScanLiteralExpressionClass *kl
expr->cmp_rich = (compare_expr_rich_fc)g_scan_literal_expression_compare_rich;
expr->reduce_to_bool = (reduce_expr_to_bool_fc)g_scan_literal_expression_reduce_to_boolean;
expr->count = (count_scan_expr_fc)g_scan_literal_expression_count;
+ expr->get = (get_scan_expr_fc)g_scan_literal_expression_get_item;
}
@@ -120,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));
+
}
@@ -156,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));
}
@@ -659,3 +684,51 @@ static bool g_scan_literal_expression_count(const GScanLiteralExpression *expr,
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à consulter. *
+* index = indice de l'élément à transférer. *
+* ctx = contexte de suivi de l'analyse courante. *
+* out = zone d'enregistrement de la réduction opérée. [OUT] *
+* *
+* Description : Fournit un élément donné issu d'un ensemble constitué. *
+* *
+* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_scan_literal_expression_get_item(const GScanLiteralExpression *expr, size_t index, GScanContext *ctx, GScanExpression **out)
+{
+ bool result; /* Bilan à retourner */
+ sized_string_t ch; /* Caractère extrait */
+
+ switch (expr->value_type)
+ {
+ case LVT_STRING:
+
+ result = (index < expr->value.string.len);
+
+ if (result)
+ {
+ ch.data = expr->value.string.data + index;
+ ch.len = 1;
+
+ *out = g_scan_literal_expression_new(LVT_STRING, &ch);
+
+ }
+
+ break;
+
+ default:
+ result = false;
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/analysis/scan/exprs/logical.c b/src/analysis/scan/exprs/logical.c
index cc78a75..3b07843 100644
--- a/src/analysis/scan/exprs/logical.c
+++ b/src/analysis/scan/exprs/logical.c
@@ -230,7 +230,7 @@ bool g_scan_logical_operation_create(GScanLogicalOperation *op, BooleanOperation
g_object_ref(G_OBJECT(op->first));
result = (second == NULL);
- assert(second != NULL);
+ assert(second == NULL);
break;
default:
@@ -483,6 +483,11 @@ static ScanReductionState g_scan_logical_operation_reduce(const GScanLogicalOper
break;
+ /* Pour GCC... */
+ default:
+ result = SRS_UNRESOLVABLE;
+ break;
+
}
/* Mise à jour de la progression ? */
diff --git a/src/analysis/scan/exprs/setcounter-int.h b/src/analysis/scan/exprs/setcounter-int.h
index fbed209..c9e3da5 100644
--- a/src/analysis/scan/exprs/setcounter-int.h
+++ b/src/analysis/scan/exprs/setcounter-int.h
@@ -37,8 +37,13 @@ struct _GScanSetMatchCounter
{
GScanExpression parent; /* A laisser en premier */
- GSearchPattern **patterns; /* Motifs associés */
+ union
+ {
+ const GSearchPattern **patterns; /* Motifs associés */
+ GSearchPattern **ref_patterns; /* Motifs associés */
+ };
size_t count; /* Nombre de ces motifs */
+ bool shared; /* Définition de propriété */
ScanSetCounterType type; /* Type de décompte */
size_t number; /* Eventuel volume associé */
@@ -53,9 +58,11 @@ struct _GScanSetMatchCounterClass
};
+/* Met en place un décompte de motifs avec correspondances. */
+bool g_scan_set_match_counter_create_shared(GScanSetMatchCounter *, const GSearchPattern ** const, size_t);
/* Met en place un décompte de motifs avec correspondances. */
-bool g_scan_set_match_counter_create(GScanSetMatchCounter *, GSearchPattern ** const, size_t);
+bool g_scan_set_match_counter_create_and_ref(GScanSetMatchCounter *, GSearchPattern ** const, size_t);
diff --git a/src/analysis/scan/exprs/setcounter.c b/src/analysis/scan/exprs/setcounter.c
index 14e7676..bed315e 100644
--- a/src/analysis/scan/exprs/setcounter.c
+++ b/src/analysis/scan/exprs/setcounter.c
@@ -24,6 +24,10 @@
#include "setcounter.h"
+#include <assert.h>
+#include <string.h>
+
+
#include "setcounter-int.h"
#include "literal.h"
@@ -109,6 +113,7 @@ static void g_scan_set_match_counter_init(GScanSetMatchCounter *counter)
{
counter->patterns = NULL;
counter->count = 0;
+ counter->shared = true;
counter->type = SSCT_NONE;
counter->number = 0;
@@ -132,8 +137,9 @@ static void g_scan_set_match_counter_dispose(GScanSetMatchCounter *counter)
{
size_t i; /* Boucle de parcours */
- for (i = 0; i < counter->count; i++)
- g_clear_object(&counter->patterns[i]);
+ if (!counter->shared)
+ for (i = 0; i < counter->count; i++)
+ g_clear_object(&counter->ref_patterns[i]);
G_OBJECT_CLASS(g_scan_set_match_counter_parent_class)->dispose(G_OBJECT(counter));
@@ -175,13 +181,75 @@ static void g_scan_set_match_counter_finalize(GScanSetMatchCounter *counter)
* *
******************************************************************************/
+GScanExpression *g_scan_set_match_counter_new_shared(const GSearchPattern ** const patterns, size_t count)
+{
+ GScanExpression *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_SCAN_SET_MATCH_COUNTER, NULL);
+
+ if (!g_scan_set_match_counter_create_shared(G_SCAN_SET_MATCH_COUNTER(result), patterns, count))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : counter = instance à initialiser pleinement. *
+* patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* *
+* Description : Met en place un décompte de motifs avec correspondances. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_scan_set_match_counter_create_shared(GScanSetMatchCounter *counter, const GSearchPattern ** const patterns, size_t count)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_scan_expression_create(G_SCAN_EXPRESSION(counter), SRS_WAIT_FOR_SCAN);
+ if (!result) goto exit;
+
+ counter->patterns = malloc(count * sizeof(GSearchPattern *));
+ counter->count = count;
+
+ memcpy(counter->patterns, patterns, count * sizeof(GSearchPattern *));
+
+ counter->shared = true;
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* *
+* Description : Constitue un décompte de motifs avec correspondances. *
+* *
+* Retour : Expression mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
GScanExpression *g_scan_set_match_counter_new(GSearchPattern ** const patterns, size_t count)
{
GScanExpression *result; /* Structure à retourner */
result = g_object_new(G_TYPE_SCAN_SET_MATCH_COUNTER, NULL);
- if (!g_scan_set_match_counter_create(G_SCAN_SET_MATCH_COUNTER(result), patterns, count))
+ if (!g_scan_set_match_counter_create_and_ref(G_SCAN_SET_MATCH_COUNTER(result), patterns, count))
g_clear_object(&result);
return result;
@@ -203,7 +271,7 @@ GScanExpression *g_scan_set_match_counter_new(GSearchPattern ** const patterns,
* *
******************************************************************************/
-bool g_scan_set_match_counter_create(GScanSetMatchCounter *counter, GSearchPattern ** const patterns, size_t count)
+bool g_scan_set_match_counter_create_and_ref(GScanSetMatchCounter *counter, GSearchPattern ** const patterns, size_t count)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
@@ -214,11 +282,12 @@ bool g_scan_set_match_counter_create(GScanSetMatchCounter *counter, GSearchPatte
counter->patterns = malloc(count * sizeof(GSearchPattern *));
counter->count = count;
+ memcpy(counter->patterns, patterns, count * sizeof(GSearchPattern *));
+
for (i = 0; i < count; i++)
- {
- counter->patterns[i] = patterns[i];
g_object_ref(G_OBJECT(patterns[i]));
- }
+
+ counter->shared = false;
exit:
@@ -241,21 +310,52 @@ bool g_scan_set_match_counter_create(GScanSetMatchCounter *counter, GSearchPatte
* *
******************************************************************************/
-void g_scan_set_match_counter_add_extra_patterns(GScanSetMatchCounter *counter, GSearchPattern ** const patterns, size_t count)
+void g_scan_set_match_counter_add_extra_shared_patterns(GScanSetMatchCounter *counter, const GSearchPattern ** const patterns, size_t count)
+{
+ size_t first; /* Premier emplacement libre */
+
+ assert(counter->shared);
+
+ first = counter->count;
+
+ counter->count += count;
+ counter->patterns = realloc(counter->patterns, counter->count * sizeof(GSearchPattern *));
+
+ memcpy(counter->patterns + first, patterns, count * sizeof(GSearchPattern *));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : counter = décompte à compléter. *
+* patterns = motifs à impliquer. *
+* count = quantité de ces motifs. *
+* *
+* Description : Ajoute de nouveaux motifs à un ensemble à décompter. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_scan_set_match_counter_add_and_ref_extra_patterns(GScanSetMatchCounter *counter, GSearchPattern ** const patterns, size_t count)
{
size_t first; /* Premier emplacement libre */
size_t i; /* Boucle de parcours */
+ assert(!counter->shared);
+
first = counter->count;
counter->count += count;
counter->patterns = realloc(counter->patterns, counter->count * sizeof(GSearchPattern *));
+ memcpy(counter->patterns + first, patterns, count * sizeof(GSearchPattern *));
+
for (i = 0; i < count; i++)
- {
- counter->patterns[first + i] = patterns[i];
g_object_ref(G_OBJECT(patterns[i]));
- }
}
@@ -319,6 +419,7 @@ static ScanReductionState g_scan_set_match_counter_reduce(const GScanSetMatchCou
ScanReductionState result; /* Etat synthétisé à retourner */
size_t matched; /* Qté de motifs avec résultats*/
size_t i; /* Boucle de parcours */
+ GScanMatches *matches; /* Série de correspondances */
size_t count; /* Quantité de correspondances */
bool status; /* Bilan d'évaluation finale */
@@ -328,10 +429,18 @@ static ScanReductionState g_scan_set_match_counter_reduce(const GScanSetMatchCou
for (i = 0; i < expr->count; i++)
{
- g_scan_context_get_full_matches(ctx, expr->patterns[i], &count);
+ matches = g_scan_context_get_full_matches(ctx, expr->patterns[i]);
+
+ if (matches != NULL)
+ {
+ count = g_scan_matches_count(matches);
+
+ if (count > 0)
+ matched++;
+
+ g_object_unref(G_OBJECT(matches));
- if (count > 0)
- matched++;
+ }
}
diff --git a/src/analysis/scan/exprs/setcounter.h b/src/analysis/scan/exprs/setcounter.h
index 59762f9..28c92b4 100644
--- a/src/analysis/scan/exprs/setcounter.h
+++ b/src/analysis/scan/exprs/setcounter.h
@@ -52,10 +52,16 @@ typedef struct _GScanSetMatchCounterClass GScanSetMatchCounterClass;
GType g_scan_set_match_counter_get_type(void);
/* Met en place un décompte de correspondances obtenues. */
+GScanExpression *g_scan_set_match_counter_new_shared(const GSearchPattern ** const, size_t);
+
+/* Met en place un décompte de correspondances obtenues. */
GScanExpression *g_scan_set_match_counter_new(GSearchPattern ** const, size_t);
/* Ajoute de nouveaux motifs à un ensemble à décompter. */
-void g_scan_set_match_counter_add_extra_patterns(GScanSetMatchCounter *, GSearchPattern ** const, size_t);
+void g_scan_set_match_counter_add_extra_shared_patterns(GScanSetMatchCounter *, const GSearchPattern ** const, size_t);
+
+/* Ajoute de nouveaux motifs à un ensemble à décompter. */
+void g_scan_set_match_counter_add_and_ref_extra_patterns(GScanSetMatchCounter *, GSearchPattern ** const, size_t);
/* Formes de volume de correspondances */
typedef enum _ScanSetCounterType