6
votes

Toute façon de traiter. * Comme. {0,1024} à Perl Re?

Nous permettons à certains résultats fournis par l'utilisateur dans le but de filtrer le courrier électronique. Au début, nous avons rencontré des problèmes de performance avec qui contenus, par exemple, . * Code>, lors de la correspondance contre des courriels arbitrairement élevés. Nous avons trouvé une solution simple devait S / \ * / {0,1024} / code> sur le re. Cependant, ce n'est pas une solution parfaite, car elle se brisera avec le motif suivant:

/[*]/


5 commentaires

Dans quelle partie d'un email effectue ces filtres? Les en-têtes, le corps?


@Fge: Le corps est l'endroit où cela importe, car c'est la partie qui peut être arbitrairement grande. Nous vérifions également les en-têtes, mais un seul en-tête à la fois. Et même les plus longs en-têtes de courrier électronique ne sont pas assez longs pour causer des problèmes de performance avec * et +.


OK, puis une autre question: exécutez-vous ces regex sur l'ensemble du contenu, des pièces jointes incluses ou de sauter des pièces jointes?


@Fge: Nous l'exécutons sur toutes les pièces MIME avec un type de contenu Text-ISH (texte / plaine, texte / html, vcards et une petite poignée des autres)


Interdire * et + et instruez les utilisateurs à utiliser {n, m} à la place? Celui-ci a une limite supérieure de 32766.


4 Réponses :


1
votes

Vous voulez dire sauf de corriger la source?

  1. Vous pouvez casser les textes d'entrée dans des morceaux plus courts et ne correspondez que celles-ci. Mais là encore, vous ne correspondriez pas sur une pause "ligne".
  2. Vous pouvez casser la regex, rechercher uniquement le 1er carton, chargez les 1024 caractères du texte suivant, puis correspond à l'ensemble de la regex à ce sujet (évidemment, cela ne fonctionne pas avec la regex à partir de.)
  3. Trouvez le premier caractère de la regex qui n'est pas. * + () \, trouvez cela, chargez 1024 caractères avant et après, puis faites correspondre à l'ensemble du regex sur cette chaîne. (compliqué et élaguer des erreurs dans une étrange regex imprévu)

1 commentaires

Oui ... autre que de corriger la source :) (nous avons toujours besoin du comportement standard dans certains cas qui n'impliquent pas l'entrée de l'utilisateur)



4
votes

Mise à jour

Ajout d'un (? Avant les quantifiers, car il ne faut pas correspondre. Le remplacement échouera toujours s'il y a un \\ * (correspondez \ 0 ou plusieurs fois).

Une amélioration serait cette xxx

voir ici sur Regexr

Cela signifie que cela signifie Match [* +] mais uniquement s'il n'y a pas de fermeture ] à l'avance et non [ jusqu'à présent. Et il n'y a pas de \ (le (? partie) autorisé avant les crochets.

(?! ...) est un lookahead négatif

(? est un lookeded négatif

Voir Perlretut pour plus de détails

Mise à jour 2 Inclure les quantificateurs possessifs xxx

voir Ici sur Regexr

semble fonctionner, mais sa réelle compliquée maintenant!


4 commentaires

Oui, c'est une amélioration ... il laisse toujours le cas du quantificateur "possessif" + (c.-à-d. * + , ++ , ? + et {..} + ). Je suppose que je peux former une recette similaire pour ignorer le + caractère dans ces cas aussi.


Bon point avec les quantificateurs possessifs, a ajouté une solution pour cela.


Merci ... j'identifie complètement avec votre dernier commentaire ... C'est vraiment compliqué! Je souhaite qu'il n'y ait qu'un perlvar de $ max_regexp_string_length ou quelque chose! :)


@ikegami j'ai déclaré que la restriction au sommet de mon post.



5
votes

Cela ne répond pas vraiment à votre question, mais vous devez être au courant d'autres problèmes avec des expressions régulières fournies par l'utilisateur, voir par exemple ce Résumé chez Owasp . En fonction de votre situation exacte, il peut être préférable d'écrire ou de trouver une bibliothèque de correspondance de modèle simple personnalisée?


3 commentaires

+1, parce que ^ (a | aa) {} $ 0,30 est suffisant pour maintenir le moteur regex occupé pour des millions de cycles avec une chaîne comme aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaX


Merci; un bon avertissement. Bien qu'il soit certainement possible qu'un utilisateur puisse en vigueur à DOS eux-mêmes, ils ne pouvaient vraiment que le faire à eux-mêmes. Ainsi, notre objectif principal est de les empêcher de le faire accidentellement.


Cela me donne l'idée d'envelopper tous mes résultats fournis par l'utilisateur dans un eval {alarme 1; ...}; bloc, bien que ...



4
votes

Obtenez un arbre en utilisant Regexp :: anal erser et modifier regex comme vous le souhaitez ou fournissez une interface interface graphique à Regexp :: Anglais


0 commentaires