summaryrefslogtreecommitdiff
path: root/src/analysis/scan/patterns/tokens/nodes/masked.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/scan/patterns/tokens/nodes/masked.c')
-rw-r--r--src/analysis/scan/patterns/tokens/nodes/masked.c169
1 files changed, 108 insertions, 61 deletions
diff --git a/src/analysis/scan/patterns/tokens/nodes/masked.c b/src/analysis/scan/patterns/tokens/nodes/masked.c
index 4941e0e..5194cb8 100644
--- a/src/analysis/scan/patterns/tokens/nodes/masked.c
+++ b/src/analysis/scan/patterns/tokens/nodes/masked.c
@@ -475,15 +475,18 @@ static void g_scan_token_node_masked_check_forward(const GScanTokenNodeMasked *n
#ifndef NDEBUG
bool forced; /* Inclusion dans un scan ? */
#endif
+ match_area_t **areas; /* Liste de zones à constituer */
+ size_t *count; /* Taille de cette liste */
+ bool copy; /* Besoin d'une copie ? */
+ bool inverted; /* Inversion des bilans ? */
size_t i; /* Boucle de parcours #1 */
const tracked_scan_atom_t *atom; /* Atome correspondant */
- GUMemSlice *atoms; /* Localisations des bribes */
- const umem_slice_iter_t *aiter; /* Boucle de parcours #2 */
- match_area_t *end; /* Borne de fin de parcours */
- match_area_t *pos; /* Position courante */
- bool status; /* Bilan d'une correspondance */
+ match_area_t *atoms; /* Localisations des bribes */
+ bool first_round; /* Premier tour de traitement */
match_area_t *area; /* Correspondance à valider */
match_area_t *next; /* Correspondance suivante */
+ phys_t start; /* Début potentiel de motif */
+ bool status; /* Bilan d'une correspondance */
phys_t after; /* Espace disposible après */
phys_t min_end; /* Fin la plus proche possible */
phys_t max_end; /* Fin la plus éloignée trouvée*/
@@ -514,101 +517,145 @@ static void g_scan_token_node_masked_check_forward(const GScanTokenNodeMasked *n
if (!params->initialized)
{
+ /* Destinations établies une fois pour toutes */
+
+ if (cflags & TNCF_KEEP_DISCARDED)
+ {
+ areas = &params->kept_areas;
+ count = &params->kept_count;
+
+ copy = false;
+ inverted = true;
+
+ }
+
+ else if (cflags & TNCF_CREATE_NEW)
+ {
+ areas = &params->created_areas;
+ count = &params->created_count;
+
+ copy = true;
+ inverted = false;
+
+ }
+
+ else
+ {
+ assert(cflags & TNCF_UPDATE_IN_PLACE);
+
+ areas = &params->main_areas;
+ count = &params->main_count;
+
+ copy = false;
+ inverted = false;
+
+ }
+
+ /* Parcours des combinaisons enregistrées */
+
for (i = 0; i < node->enrolled_count; i++)
{
atom = &node->enrolled_atoms[i];
atoms = g_scan_context_get_atom_matches(params->context, atom->pid);
+ first_round = (*count == 0);
+
if (atom->fast_check)
{
- for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next)
- {
- end = aiter->data_end;
+ /**
+ * Toutes les correspondances sont validées d'office car le motif identifié
+ * correspondant au motif complet.
+ */
- for (pos = aiter->data; pos < end; pos++)
+ if (!inverted)
+ {
+ for_each_match_area(area, atoms)
{
/**
* La modification de la zone d'origine est possible dans tous les cas
* car cette zone a été allouée de façon dédiée à un type de correspondances
* et ne sera pas réutilisée comme autre source de correspondance ailleurs.
*/
- pos->end = pos->start + atom->len;
- if (cflags & TNCF_KEEP_DISCARDED)
- {
- add_tail_match_area(pos, &params->kept_areas);
- params->kept_count++;
- }
-
- else if (cflags & TNCF_CREATE_NEW)
- {
- add_tail_match_area(pos, &params->created_areas);
- params->created_count++;
- }
+ assert(area->end >= atom->len);
- else
- {
- assert(cflags & TNCF_UPDATE_IN_PLACE);
+ area->start = area->end - atom->len;
- add_tail_match_area(pos, &params->main_areas);
- params->main_count++;
-
- }
+ (*count)++;
}
}
+ else
+ atoms = NULL;
+
}
else
{
- for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next)
+ for_each_match_area_safe(area, &atoms, next)
{
- end = aiter->data_end;
+ start = area->end - atom->len - atom->pos;
- for (pos = aiter->data; pos < end; pos++)
+ status = check_scan_token_node_masked_content(node->bytes, node->len,
+ start, params->content);
+
+ if (status)
{
- status = check_scan_token_node_masked_content(node->bytes, node->len,
- pos->start, params->content);
+ /**
+ * La modification de la zone d'origine est possible dans tous les cas
+ * car cette zone a été allouée de façon dédiée à un type de correspondances
+ * et ne sera pas réutilisée comme autre source de correspondance ailleurs.
+ */
- if (status)
+ if (!inverted)
{
- /**
- * La modification de la zone d'origine est possible dans tous les cas
- * car cette zone a été allouée de façon dédiée à un type de correspondances
- * et ne sera pas réutilisée comme autre source de correspondance ailleurs.
- */
- pos->end = pos->start + node->len;
-
- if (cflags & TNCF_KEEP_DISCARDED)
- {
- add_tail_match_area(pos, &params->kept_areas);
- params->kept_count++;
- }
-
- else if (cflags & TNCF_CREATE_NEW)
- {
- add_tail_match_area(pos, &params->created_areas);
- params->created_count++;
- }
-
- else
- {
- assert(cflags & TNCF_UPDATE_IN_PLACE);
-
- add_tail_match_area(pos, &params->main_areas);
- params->main_count++;
-
- }
+ area->start = start;
+ area->end += atom->rem;
+
+ (*count)++;
}
+ else
+ del_match_area(area, &atoms);
+
+ }
+
+ else
+ {
+ /**
+ * Les principes de modifications restent valables, même inversés.
+ */
+ if (inverted)
+ {
+ area->start = start;
+ area->end += atom->rem;
+
+ (*count)++;
+
+ }
+ else
+ del_match_area(area, &atoms);
}
}
+
+ }
+
+ /* Mise à jour de la liste */
+
+ if (atoms != NULL)
+ {
+ if (first_round)
+ *areas = atoms;
+
+ else
+ merge_match_areas(areas, &atoms);
+
}
}