diff options
Diffstat (limited to 'src/analysis/scan/patterns/tokens')
-rw-r--r-- | src/analysis/scan/patterns/tokens/node.h | 1 | ||||
-rw-r--r-- | src/analysis/scan/patterns/tokens/nodes/any.c | 10 | ||||
-rw-r--r-- | src/analysis/scan/patterns/tokens/nodes/masked.c | 169 | ||||
-rw-r--r-- | src/analysis/scan/patterns/tokens/nodes/plain.c | 163 |
4 files changed, 218 insertions, 125 deletions
diff --git a/src/analysis/scan/patterns/tokens/node.h b/src/analysis/scan/patterns/tokens/node.h index 55bf0a8..5b1a247 100644 --- a/src/analysis/scan/patterns/tokens/node.h +++ b/src/analysis/scan/patterns/tokens/node.h @@ -33,6 +33,7 @@ #include "../backend.h" #include "../../context.h" #include "../../matches/bytes.h" +#include "../../../../glibext/umemslice.h" #define G_TYPE_SCAN_TOKEN_NODE g_scan_token_node_get_type() diff --git a/src/analysis/scan/patterns/tokens/nodes/any.c b/src/analysis/scan/patterns/tokens/nodes/any.c index d65f3c9..4334fff 100644 --- a/src/analysis/scan/patterns/tokens/nodes/any.c +++ b/src/analysis/scan/patterns/tokens/nodes/any.c @@ -52,7 +52,7 @@ static void g_scan_token_node_any_finalize(GScanTokenNodeAny *); /* Inscrit la définition d'un motif dans un moteur de recherche. */ -static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *, GScanContext *, GEngineBackend *, size_t, size_t *); +static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *, GEngineBackend *, size_t, size_t *); /* Transforme les correspondances locales en trouvailles. */ static void g_scan_token_node_any_check_forward(const GScanTokenNodeAny *, scan_node_check_params_t *, TokenNodeCheckFlags, bool *); @@ -264,7 +264,6 @@ void g_scan_token_node_any_merge(GScanTokenNodeAny *any, GScanTokenNodeAny *extr /****************************************************************************** * * * 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] * @@ -277,7 +276,7 @@ void g_scan_token_node_any_merge(GScanTokenNodeAny *any, GScanTokenNodeAny *extr * * ******************************************************************************/ -static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *node, GScanContext *context, GEngineBackend *backend, size_t maxsize, size_t *slow) +static bool g_scan_token_node_any_enroll(GScanTokenNodeAny *node, GEngineBackend *backend, size_t maxsize, size_t *slow) { bool result; /* Statut à retourner */ bool forced; /* Inclusion dans un scan ? */ @@ -370,7 +369,7 @@ static void g_scan_token_node_any_check_forward(const GScanTokenNodeAny *node, s if (match_size <= size) { - size -= match_size; + size -= (match_size - 1); assert(cflags & TNCF_UPDATE_IN_PLACE); @@ -382,10 +381,11 @@ static void g_scan_token_node_any_check_forward(const GScanTokenNodeAny *node, s space->end = space->start + match_size; add_tail_match_area(space, ¶ms->main_areas); - params->main_count++; } + params->main_count += size; + } } 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 = ¶ms->kept_areas; + count = ¶ms->kept_count; + + copy = false; + inverted = true; + + } + + else if (cflags & TNCF_CREATE_NEW) + { + areas = ¶ms->created_areas; + count = ¶ms->created_count; + + copy = true; + inverted = false; + + } + + else + { + assert(cflags & TNCF_UPDATE_IN_PLACE); + + areas = ¶ms->main_areas; + count = ¶ms->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, ¶ms->kept_areas); - params->kept_count++; - } - - else if (cflags & TNCF_CREATE_NEW) - { - add_tail_match_area(pos, ¶ms->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, ¶ms->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, ¶ms->kept_areas); - params->kept_count++; - } - - else if (cflags & TNCF_CREATE_NEW) - { - add_tail_match_area(pos, ¶ms->created_areas); - params->created_count++; - } - - else - { - assert(cflags & TNCF_UPDATE_IN_PLACE); - - add_tail_match_area(pos, ¶ms->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); + } } diff --git a/src/analysis/scan/patterns/tokens/nodes/plain.c b/src/analysis/scan/patterns/tokens/nodes/plain.c index 71e2e9b..5dd45df 100644 --- a/src/analysis/scan/patterns/tokens/nodes/plain.c +++ b/src/analysis/scan/patterns/tokens/nodes/plain.c @@ -654,16 +654,19 @@ static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *nod { bool track_path; /* Conservation du chemin */ bool nocase; /* Pas d'intérêt pour la casse */ + 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 sized_binary_t *raw; /* Données brutes d'origine */ 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 */ + const sized_binary_t *raw; /* Données brutes d'origine */ 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*/ @@ -689,98 +692,128 @@ static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *nod */ if (!params->initialized) { + /* Destinations établies une fois pour toutes */ + + if (cflags & TNCF_KEEP_DISCARDED) + { + areas = ¶ms->kept_areas; + count = ¶ms->kept_count; + + copy = false; + inverted = true; + + } + + else if (cflags & TNCF_CREATE_NEW) + { + areas = ¶ms->created_areas; + count = ¶ms->created_count; + + copy = true; + inverted = false; + + } + + else + { + assert(cflags & TNCF_UPDATE_IN_PLACE); + + areas = ¶ms->main_areas; + count = ¶ms->main_count; + + copy = false; + inverted = false; + + } + + /* Parcours des combinaisons enregistrées */ + for (i = 0; i < node->count; i++) { - raw = &node->raw[i]; atom = &node->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, ¶ms->kept_areas); - params->kept_count++; - } - - else if (cflags & TNCF_CREATE_NEW) - { - add_tail_match_area(pos, ¶ms->created_areas); - params->created_count++; - } - - else - { - assert(cflags & TNCF_UPDATE_IN_PLACE); + assert(area->end >= atom->len); - add_tail_match_area(pos, ¶ms->main_areas); - params->main_count++; + area->start = area->end - atom->len; - } + (*count)++; } } + else + atoms = NULL; + } else { - for (aiter = g_umem_slice_get_iter(atoms); aiter != NULL; aiter = aiter->next) + raw = &node->raw[i]; + + 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_plain_content(raw, atom, nocase, start, params->content); + + if (status) { - status = check_scan_token_node_plain_content(raw, atom, nocase, - pos->start - atom->pos, 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->start -= atom->pos; - pos->end = pos->start + raw->len; + area->start = start; + area->end += atom->rem; - if (cflags & TNCF_KEEP_DISCARDED) - { - add_tail_match_area(pos, ¶ms->kept_areas); - params->kept_count++; - } + (*count)++; - else if (cflags & TNCF_CREATE_NEW) - { - add_tail_match_area(pos, ¶ms->created_areas); - params->created_count++; - } + } + else + del_match_area(area, &atoms); - else - { - assert(cflags & TNCF_UPDATE_IN_PLACE); + } - add_tail_match_area(pos, ¶ms->main_areas); - params->main_count++; + 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); } @@ -789,6 +822,18 @@ static void g_scan_token_node_plain_check_forward(const GScanTokenNodePlain *nod } + /* Mise à jour de la liste */ + + if (atoms != NULL) + { + if (first_round) + *areas = atoms; + + else + merge_match_areas(areas, &atoms); + + } + } } |