summaryrefslogtreecommitdiff
path: root/src/analysis/scan/patterns/tokens/nodes/plain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/patterns/tokens/nodes/plain.c')
-rw-r--r--src/analysis/scan/patterns/tokens/nodes/plain.c244
1 files changed, 209 insertions, 35 deletions
diff --git a/src/analysis/scan/patterns/tokens/nodes/plain.c b/src/analysis/scan/patterns/tokens/nodes/plain.c
index ee87c73..5a7f976 100644
--- a/src/analysis/scan/patterns/tokens/nodes/plain.c
+++ b/src/analysis/scan/patterns/tokens/nodes/plain.c
@@ -24,7 +24,11 @@
#include "plain.h"
+#include <assert.h>
+
+
#include "plain-int.h"
+#include "../../../../../common/extstr.h"
@@ -32,7 +36,7 @@
/* Initialise la classe des noeuds pour motif textuel. */
-static void g_scan_token_node_plain_class_init(GScanTokenNodePlainClass *klass);
+static void g_scan_token_node_plain_class_init(GScanTokenNodePlainClass *);
/* Initialise une instance de noeud pour motif textuel. */
static void g_scan_token_node_plain_init(GScanTokenNodePlain *);
@@ -48,14 +52,20 @@ static void g_scan_token_node_plain_finalize(GScanTokenNodePlain *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+/* Parcourt une arborescence de noeuds et y relève des éléments. */
+static void g_scan_token_node_plain_visit(GScanTokenNodePlain *, scan_tree_points_t *);
+
/* Inscrit la définition d'un motif dans un moteur de recherche. */
-static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *, GScanContext *, GEngineBackend *, size_t );
+static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *, GScanContext *, GEngineBackend *, size_t, size_t *);
/* Détermine si un contenu d'intérêt est présent à une position. */
-static bool check_scan_token_node_plain_content(const sized_binary_t *, const tracked_scan_atom_t *, phys_t, GBinContent *);
+static bool check_scan_token_node_plain_content(const sized_binary_t *, const tracked_scan_atom_t *, bool, phys_t, GBinContent *);
/* Transforme les correspondances locales en trouvailles. */
-static void g_scan_plain_bytes_check(const GScanTokenNodePlain *, GScanContext *, GBinContent *, pending_matches_t *, const node_search_offset_t *);
+static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *, GScanContext *, GBinContent *, pending_matches_t *, node_search_offset_t *, bool, bool *);
+
+/* Transforme les correspondances locales en trouvailles. */
+static void g_scan_token_node_plain_check_backward(const GScanTokenNodePlain *, GScanContext *, GBinContent *, pending_matches_t *, node_search_offset_t *, bool, bool *);
@@ -92,8 +102,10 @@ static void g_scan_token_node_plain_class_init(GScanTokenNodePlainClass *klass)
node = G_SCAN_TOKEN_NODE_CLASS(klass);
+ node->visit = (visit_scan_token_node_fc)g_scan_token_node_plain_visit;
node->enroll = (enroll_scan_token_node_fc)g_scan_token_node_plain_enroll;
- node->check = (check_scan_token_node_fc)g_scan_plain_bytes_check;
+ node->check_forward = (check_scan_token_node_fc)g_scan_token_node_plain_check_forward;
+ node->check_backward = (check_scan_token_node_fc)g_scan_token_node_plain_check_backward;
}
@@ -112,6 +124,8 @@ static void g_scan_token_node_plain_class_init(GScanTokenNodePlainClass *klass)
static void g_scan_token_node_plain_init(GScanTokenNodePlain *plain)
{
+ g_scan_token_node_set_flags(G_SCAN_TOKEN_NODE(plain), STNF_PROD);
+
init_szstr(&plain->orig);
plain->modifier = NULL;
plain->flags = SPNF_NONE;
@@ -203,6 +217,7 @@ GScanTokenNode *g_scan_token_node_plain_new(const sized_binary_t *text, GScanTok
}
+
/******************************************************************************
* *
* Paramètres : plain = encadrement de motif à initialiser pleinement. *
@@ -210,7 +225,7 @@ GScanTokenNode *g_scan_token_node_plain_new(const sized_binary_t *text, GScanTok
* modifier = transformateur éventuel à solliciter. *
* flags = particularités à prendre en considération. *
* *
-* Description : Met en place un un noeud représentant un motif textuel. *
+* Description : Met en place un noeud représentant un motif textuel. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -239,6 +254,29 @@ bool g_scan_token_node_plain_create(GScanTokenNodePlain *plain, const sized_bina
}
+/******************************************************************************
+* *
+* Paramètres : plain = noeud de motif textuel à consulter. *
+* *
+* Description : Indique les propriétés particulières d'un noeud de texte. *
+* *
+* Retour : Propriétés particulières associées au noeud. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+ScanPlainNodeFlags g_scan_token_node_plain_get_flags(const GScanTokenNodePlain *plain)
+{
+ ScanPlainNodeFlags result; /* Statut à retourner */
+
+ result = plain->flags;
+
+ return result;
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
@@ -247,10 +285,32 @@ bool g_scan_token_node_plain_create(GScanTokenNodePlain *plain, const sized_bina
/******************************************************************************
* *
+* Paramètres : node = point de départ du parcours à effectuer. *
+* points = points capitaux de l'arborescence. [OUT] *
+* *
+* Description : Parcourt une arborescence de noeuds et y relève des éléments.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_token_node_plain_visit(GScanTokenNodePlain *node, scan_tree_points_t *points)
+{
+ if (points->first_plain == NULL)
+ points->first_plain = G_SCAN_TOKEN_NODE(node);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : node = définition de la bribe à enregistrer. *
* context = contexte de l'analyse à mener. *
* backend = moteur de recherche à préchauffer. *
* maxsize = taille max. des atomes (mise en commun optimisée). *
+* slow = niveau de ralentissement induit (0 = idéal). [OUT] *
* *
* Description : Inscrit la définition d'un motif dans un moteur de recherche.*
* *
@@ -260,7 +320,7 @@ bool g_scan_token_node_plain_create(GScanTokenNodePlain *plain, const sized_bina
* *
******************************************************************************/
-static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanContext *context, GEngineBackend *backend, size_t maxsize)
+static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanContext *context, GEngineBackend *backend, size_t maxsize, size_t *slow)
{
bool result; /* Statut à retourner */
size_t i; /* Boucle de parcours #1 */
@@ -312,13 +372,14 @@ static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanConte
if (letters == 0)
node->atoms[i] = atom;
- /* Insertion des combinaisons pour couvrir toutes les casses */
+ /* Insertion des nouvelles combinaisons pour couvrir toutes les casses */
else
{
- for (k = 0, extra_count = 1; k < letters; k++, extra_count *= 2)
+ /* extra_count = 2^letters */
+ for (k = 1, extra_count = 2; k < letters; k++, extra_count *= 2)
;
- extra = make_atoms_case_insensitive(&node->raw[i], extra_count);
+ extra = make_atoms_case_insensitive(&node->raw[i], &atom, extra_count);
remaining = node->count - i - 1;
@@ -333,7 +394,7 @@ static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanConte
free(extra);
- node->atoms = realloc(node->raw, node->count * sizeof(tracked_scan_atom_t));
+ node->atoms = realloc(node->atoms, node->count * sizeof(tracked_scan_atom_t));
for (k = 0; k < extra_count; k++)
node->atoms[i + k] = atom;
@@ -365,6 +426,7 @@ static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanConte
* *
* Paramètres : raw = contneu brut à retrouver idéalement. *
* atom = contenu brut représentatif ciblé. *
+* nocase = marque un éventuel désintérêt pour la casse. *
* start = point d'analyse à respecter. *
* content = accès au contenu brut pour vérifications (optim.) *
* *
@@ -376,7 +438,7 @@ static bool g_scan_token_node_plain_enroll(GScanTokenNodePlain *node, GScanConte
* *
******************************************************************************/
-static bool check_scan_token_node_plain_content(const sized_binary_t *raw, const tracked_scan_atom_t *atom, phys_t start, GBinContent *content)
+static bool check_scan_token_node_plain_content(const sized_binary_t *raw, const tracked_scan_atom_t *atom, bool nocase, phys_t start, GBinContent *content)
{
bool result; /* Bilan à retourner */
vmpa2t pos; /* Position dans les données */
@@ -393,7 +455,11 @@ static bool check_scan_token_node_plain_content(const sized_binary_t *raw, const
{
ptr = g_binary_content_get_raw_access(content, &pos, atom->pos);
- ret = memcmp(raw->data, ptr, atom->pos);
+ if (nocase)
+ ret = memcasecmp(raw->data, ptr, atom->pos);
+ else
+ ret = memcmp(raw->data, ptr, atom->pos);
+
if (ret != 0) goto done;
}
@@ -406,7 +472,11 @@ static bool check_scan_token_node_plain_content(const sized_binary_t *raw, const
ptr = g_binary_content_get_raw_access(content, &pos, atom->rem);
- ret = memcmp(raw->data + atom->pos + atom->len, ptr, atom->rem);
+ if (nocase)
+ ret = memcasecmp(raw->data + atom->pos + atom->len, ptr, atom->rem);
+ else
+ ret = memcmp(raw->data + atom->pos + atom->len, ptr, atom->rem);
+
if (ret != 0) goto done;
}
@@ -427,6 +497,8 @@ static bool check_scan_token_node_plain_content(const sized_binary_t *raw, const
* content = accès au contenu brut pour vérifications (optim.) *
* matches = suivi des correspondances à consolider. *
* offset = tolérance dans les positions à appliquer. *
+* not = indique si les résultats doivent être inversés. *
+* skip = détermine si l'analyse est différée. [OUT] *
* *
* Description : Transforme les correspondances locales en trouvailles. *
* *
@@ -436,22 +508,33 @@ static bool check_scan_token_node_plain_content(const sized_binary_t *raw, const
* *
******************************************************************************/
-static void g_scan_plain_bytes_check(const GScanTokenNodePlain *node, GScanContext *context, GBinContent *content, pending_matches_t *matches, const node_search_offset_t *offset)
+static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *node, GScanContext *context, GBinContent *content, pending_matches_t *matches, node_search_offset_t *offset, bool not, bool *skip)
{
bool initialized; /* Initialisation du suivi ? */
+ bool nocase; /* Pas d'intérêt pour la casse */
+ size_t ocount; /* Quantité de bornes présentes*/
size_t i; /* Boucle de parcours #1 */
const sized_binary_t *raw; /* Données brutes d'origine */
const tracked_scan_atom_t *atom; /* Atome correspondant */
size_t count; /* Quantité de bribes trouvées */
const phys_t *found; /* Localisations des bribes */
size_t k; /* Boucle de parcours #2 */
- phys_t start; /* Point de départ */
+ phys_t new_begin; /* Nouveau départ à tester */
bool status; /* Bilan d'une correspondance */
size_t pcount; /* Nombre de correspondances */
+ match_area_t * const *pending_ptr; /* Correspondances actuelles */
size_t p; /* Boucle de parcours #3 */
+ const match_area_t *pending; /* Correspondance à traiter */
+
+ if (*skip)
+ return;
initialized = are_pending_matches_initialized(matches);
+ nocase = (node->flags & SPNF_CASE_INSENSITIVE);
+
+ get_node_search_offset_ranges(offset, &ocount);
+
for (i = 0; i < node->count; i++)
{
raw = &node->raw[i];
@@ -463,28 +546,34 @@ static void g_scan_plain_bytes_check(const GScanTokenNodePlain *node, GScanConte
{
for (k = 0; k < count; k++)
{
- start = found[k] - atom->pos;
+ new_begin = found[k] - atom->pos;
/**
* Si personne n'a manipulé les pré-résultats, mais qu'un décallage
* est spécifié par un noeud précédent, une validation sur la base
* d'une position 0 est menée.
*/
- if (offset != NULL)
+ if (ocount > 0)
{
- if (start < offset->min || start > offset->max)
+ if (!does_node_search_offset_include_pos_forward(offset, 0, new_begin))
+ {
+ if (not)
+ add_pending_match(matches, new_begin, raw->len);
+
continue;
+
+ }
}
- status = check_scan_token_node_plain_content(raw, atom, start, content);
+ status = check_scan_token_node_plain_content(raw, atom, nocase, new_begin, content);
- if (status)
+ if ((status && !not) || (!status && not))
/**
* Il ne peut y avoir qu'une seule séquence d'octets à un même
- * emplacement, donc le couple (start, len) enregistré est
+ * emplacement, donc le couple (new_begin, len) enregistré est
* unique.
*/
- add_pending_match(matches, start, raw->len);
+ add_pending_match(matches, new_begin, raw->len);
}
@@ -494,12 +583,17 @@ static void g_scan_plain_bytes_check(const GScanTokenNodePlain *node, GScanConte
{
reset_pending_matches_ttl(matches);
- pcount = count_pending_matches(matches);
+ pending_ptr = get_all_pending_matches(matches, &pcount);
for (p = 0; p < pcount; p++)
+ {
+ pending = (*pending_ptr) + p;
+
+ assert(matches->content_start <= pending->start);
+
for (k = 0; k < count; k++)
{
- start = found[k] - atom->pos;
+ new_begin = found[k] - atom->pos;
/**
* Si bornes de tolérance il y a, on valide la position.
@@ -507,20 +601,52 @@ static void g_scan_plain_bytes_check(const GScanTokenNodePlain *node, GScanConte
* Sinon les correspondances passées et actuelle doivent
* être jointes.
*/
- if (offset != NULL)
+ if (ocount > 0)
{
- if (!has_pending_match_ending_between(matches, p, start, offset->min, offset->max))
+ if (!does_node_search_offset_include_pos_forward(offset, pending->end, new_begin))
+ {
+ if (not)
+ {
+ extend_pending_match_ending(matches, p, pending->end + raw->len);
+
+ /**
+ * Comme l'extension a pu conduire à un ajout et donc à une
+ * réallocation de la liste, on recharge l'élément pour les
+ * itérations suivantes.
+ */
+ pending = (*pending_ptr) + p;
+
+ }
+
continue;
+
+ }
}
else
{
- if (!has_pending_match_ending_at(matches, p, start))
+ if (pending->end != new_begin)
+ {
+ if (not)
+ {
+ extend_pending_match_ending(matches, p, pending->end + raw->len);
+
+ /**
+ * Comme l'extension a pu conduire à un ajout et donc à une
+ * réallocation de la liste, on recharge l'élément pour les
+ * itérations suivantes.
+ */
+ pending = (*pending_ptr) + p;
+
+ }
+
continue;
+
+ }
}
- status = check_scan_token_node_plain_content(raw, atom, start, content);
+ status = check_scan_token_node_plain_content(raw, atom, nocase, new_begin, content);
- if (status)
+ if ((status && !not) || (!status && not))
{
/**
* Même si une base de couples uniques est assurée,
@@ -559,18 +685,28 @@ static void g_scan_plain_bytes_check(const GScanTokenNodePlain *node, GScanConte
/**
* La seconde situation est prise en compte par la fonction
- * extend_pending_match() qui s'appuie sur le TTL pour dupliquer
- * la correspondance pending[x] initiale. Le nouvel élément est
- * placé en fin de liste, ce qui ne boulverse pas le parcours
- * de liste courant, la valeur de pcount n'étant pas actualisée.
+ * extend_pending_match_ending() qui s'appuie sur le TTL pour
+ * dupliquer la correspondance pending[x] initiale. Le nouvel
+ * élément est placé en fin de liste, ce qui ne boulverse pas
+ * le parcours de liste courant, la valeur de pcount n'étant
+ * pas actualisée.
*/
- extend_pending_match(matches, p, start + raw->len);
+ extend_pending_match_ending(matches, p, new_begin + raw->len);
+
+ /**
+ * Comme l'extension a pu conduire à un ajout et donc à une
+ * réallocation de la liste, on recharge l'élément pour les
+ * itérations suivantes.
+ */
+ pending = (*pending_ptr) + p;
}
}
+ }
+
purge_pending_matches(matches);
}
@@ -579,4 +715,42 @@ static void g_scan_plain_bytes_check(const GScanTokenNodePlain *node, GScanConte
set_pending_matches_initialized(matches);
+ disable_all_ranges_in_node_search_offset(offset);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = définition de la bribe à manipuler. *
+* context = contexte de l'analyse à mener. *
+* content = accès au contenu brut pour vérifications (optim.) *
+* matches = suivi des correspondances à consolider. *
+* offset = tolérance dans les positions à appliquer. *
+* not = indique si les résultats doivent être inversés. *
+* skip = détermine si l'analyse est différée. [OUT] *
+* *
+* Description : Transforme les correspondances locales en trouvailles. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_scan_token_node_plain_check_backward(const GScanTokenNodePlain *node, GScanContext *context, GBinContent *content, pending_matches_t *matches, node_search_offset_t *offset, bool not, bool *skip)
+{
+
+
+
+ if (*skip)
+ return;
+
+
+
+ printf("TODO\n");
+ assert(0);
+
+
+
}