Любой способ обработать. * Как. {0,1024} в Perl RE? - PullRequest
6 голосов
/ 15 декабря 2011

Мы разрешаем некоторые предоставляемые пользователем RE для фильтрации электронной почты. Ранее мы столкнулись с некоторыми проблемами с производительностью RE, которые содержали, например, .*, при сопоставлении с произвольно большими электронными письмами. Мы обнаружили, что простым решением было s/\*/{0,1024}/ для RE, предоставленного пользователем. Однако это не идеальное решение, так как оно будет нарушено по следующей схеме:

/[*]/

И вместо того, чтобы придумывать какой-то замысловатый рецепт для учета каждой возможной мутации пользовательского ввода RE, я бы хотел ограничить интерпретацию perl символов * и + максимальной длиной 1024 символа.

Есть ли способ сделать это?

Ответы [ 4 ]

5 голосов
/ 15 декабря 2011

Это на самом деле не отвечает на ваш вопрос, но вы должны знать о других проблемах с предоставленными пользователем регулярными выражениями, см., Например, сводку в OWASP .В зависимости от вашей конкретной ситуации, может быть лучше написать или найти собственную простую библиотеку сопоставления с образцом?

4 голосов
/ 15 декабря 2011

Получите дерево с помощью Regexp :: Parser и измените регулярное выражение по своему усмотрению или предоставьте интерфейс GUI для Regexp :: English

4 голосов
/ 15 декабря 2011

Обновление

Добавлен (?<!\\) перед квантификаторами, потому что экранированные * + не должны совпадать. Замена все равно не удастся, если есть \\* (соответствует \ 0 или более раз).

Улучшение было бы это

s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/
s/(?<!\\)\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/

Смотри здесь, на Regexr

Это означает совпадение [*+], но только если впереди нет закрытия ] и до [ нет. И в квадратных скобках не допускается \ ((?<!\\) часть) .

(?! ... ) - негативный взгляд

(?<! ... ) - негативный взгляд

Подробнее см. perlretut

Обновление 2 включает квантификаторы притяжений

s/(?<!(?<!\\)[\\+*?])\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/   # for +
s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/    # for *

Смотрите это здесь на Regexr

Кажется, работает, но сейчас становится все сложнее!

1 голос
/ 15 декабря 2011

Вы имеете в виду, кроме исправления источника?

  1. Вы можете разбивать входные тексты на более короткие куски и сопоставлять только те. Но с другой стороны, вы не сможете сравниться с разрывом строки.
  2. Вы можете разбить регулярное выражение, выполнить поиск только по его 1-му символу, загрузить следующие 1024 символа текста и затем сопоставить с ним все регулярное выражение (очевидно, это не работает с регулярным выражением, начинающимся с.)
  3. Найдите первый символ регулярного выражения, который не является. * + () \, Найдите его, загрузите 1024 символа до и после, а затем сопоставьте все регулярное выражение в этой строке. (усложняется и сводится к ошибкам в странном непредвиденном регулярном выражении)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...