He trabajado en un programa que permite a los usuarios ingresar su propia expresión regular y tienen razón; pueden (y lo hacen) ingresar expresiones regulares que pueden tardar mucho tiempo en finalizar, a veces más que la duración del universo. Lo que es peor, al procesar una expresión regular Python contiene el GIL, por lo que no solo bloqueará el hilo que está ejecutando la expresión regular, sino todo el programa.
Limitar la longitud de la expresión regular no funcionará, ya que el problema es retroceder. Por ejemplo, emparejar la expresión regular r"(\S+)+x"
en una cadena de longitud N que no contenga una "x" retrocederá 2 ** N veces. En mi sistema esto toma alrededor de un segundo para coincidir con "a"*21
y el tiempo se duplica para cada carácter adicional, por lo que una cadena de 100 caracteres tardaría aproximadamente 19167393131891000 años en completarse (esta es una estimación, no la he sincronizado).
Para obtener más información, lea el libro de O'Reilly "Dominio de expresiones regulares"; esto tiene un par de capítulos sobre el rendimiento.
edición Para evitar esto escribimos una función de análisis de expresiones regulares que trataba de recuperar y rechazar algunos de los casos degenerados más obvios, pero es imposible conseguir todos ellos.
Otra cosa que vimos fue parchar el módulo re para generar una excepción si retrocede demasiadas veces. Esto es posible, pero requiere cambiar la fuente de Python C y volver a compilar, por lo que no es portátil. También enviamos un parche para liberar el GIL cuando se combina con cadenas de python, pero no creo que haya sido aceptado en el núcleo (python solo contiene el GIL porque el regex se puede ejecutar contra los búferes mutables).
+1 for "(esta es una estimación, no lo he sincronizado)" –
Supongo que podría generar otro proceso y matarlo si se agota luego de demasiado tiempo? – Skeletron
desove y muerte funcionará, pero agrega una sobrecarga considerable para ejecutar cada partido. Si eso es un precio aceptable para pagar depende de usted. –