]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-94675: Add a regression test for rjsmin re slowdown (GH-94685)
authorMiro Hrončok <miro@hroncok.cz>
Wed, 3 Aug 2022 23:19:36 +0000 (01:19 +0200)
committerGitHub <noreply@github.com>
Wed, 3 Aug 2022 23:19:36 +0000 (16:19 -0700)
Adds a regression test for an re slowdown observed by rjsmin.
Uses multiprocessing to kill the test after SHORT_TIMEOUT.

Co-authored-by: Oleg Iarygin <dralife@yandex.ru>
Co-authored-by: Christian Heimes <christian@python.org>
Lib/test/test_re.py
Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst [new file with mode: 0644]

index 9f734d47c54499145e5abad3c0e12cc32dfa8fee..3f0f84ea8cee6fad52cedfba574a8f2fd59a993f 100644 (file)
@@ -1,6 +1,7 @@
 from test.support import (gc_collect, bigmemtest, _2G,
                           cpython_only, captured_stdout,
-                          check_disallow_instantiation, is_emscripten, is_wasi)
+                          check_disallow_instantiation, is_emscripten, is_wasi,
+                          SHORT_TIMEOUT)
 import locale
 import re
 import string
@@ -11,6 +12,14 @@ import warnings
 from re import Scanner
 from weakref import proxy
 
+# some platforms lack working multiprocessing
+try:
+    import _multiprocessing
+except ImportError:
+    multiprocessing = None
+else:
+    import multiprocessing
+
 # Misc tests from Tim Peters' re.doc
 
 # WARNING: Don't change details in these tests if you don't know
@@ -2407,6 +2416,26 @@ class ReTests(unittest.TestCase):
         self.assertTrue(template_re1.match('ahoy'))
         self.assertFalse(template_re1.match('nope'))
 
+    @unittest.skipIf(multiprocessing is None, 'test requires multiprocessing')
+    def test_regression_gh94675(self):
+        pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*'
+                             r'((/[^/\[\n]*(([^\n]|(\[\n]*(]*)*\]))'
+                             r'[^/\[]*)*/))((((//[^\n]*)?[\n])'
+                             r'([\000-\040]|(/\*[^*]*\*+'
+                             r'([^/*]\*+)*/))*)+(?=[^\000-\040);\]}]))')
+        input_js = '''a(function() {
+            ///////////////////////////////////////////////////////////////////
+        });'''
+        p = multiprocessing.Process(target=pattern.sub, args=('', input_js))
+        p.start()
+        p.join(SHORT_TIMEOUT)
+        try:
+            self.assertFalse(p.is_alive(), 'pattern.sub() timed out')
+        finally:
+            if p.is_alive():
+                p.terminate()
+                p.join()
+
 
 def get_debug_out(pat):
     with captured_stdout() as out:
diff --git a/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst b/Misc/NEWS.d/next/Tests/2022-07-08-12-22-00.gh-issue-94675.IiTs5f.rst
new file mode 100644 (file)
index 0000000..d0005d9
--- /dev/null
@@ -0,0 +1 @@
+Add a regression test for :mod:`re` exponentional slowdown when using rjsmin.