summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_fnmatch.py
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2020-05-06 02:28:24 (GMT)
committerGitHub <noreply@github.com>2020-05-06 02:28:24 (GMT)
commitb9c46a2c2d7fc68457bff641f78932d66f5e5f59 (patch)
tree7f7798c3f7ef5c476705bf2fdb349adddf14c354 /Lib/test/test_fnmatch.py
parent96074de573f82fc66a2bd73c36905141a3f1d5c1 (diff)
downloadcpython-b9c46a2c2d7fc68457bff641f78932d66f5e5f59.zip
cpython-b9c46a2c2d7fc68457bff641f78932d66f5e5f59.tar.gz
cpython-b9c46a2c2d7fc68457bff641f78932d66f5e5f59.tar.bz2
bpo-40480 "fnmatch" exponential execution time (GH-19908)
bpo-40480: create different regexps in the presence of multiple `*` patterns to prevent fnmatch() from taking exponential time.
Diffstat (limited to 'Lib/test/test_fnmatch.py')
-rw-r--r--Lib/test/test_fnmatch.py17
1 files changed, 17 insertions, 0 deletions
diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py
index 55f9f0d..4c17306 100644
--- a/Lib/test/test_fnmatch.py
+++ b/Lib/test/test_fnmatch.py
@@ -45,6 +45,13 @@ class FnmatchTestCase(unittest.TestCase):
check('\nfoo', 'foo*', False)
check('\n', '*')
+ def test_slow_fnmatch(self):
+ check = self.check_match
+ check('a' * 50, '*a*a*a*a*a*a*a*a*a*a')
+ # The next "takes forever" if the regexp translation is
+ # straightforward. See bpo-40480.
+ check('a' * 50 + 'b', '*a*a*a*a*a*a*a*a*a*a', False)
+
def test_mix_bytes_str(self):
self.assertRaises(TypeError, fnmatch, 'test', b'*')
self.assertRaises(TypeError, fnmatch, b'test', '*')
@@ -107,6 +114,16 @@ class TranslateTestCase(unittest.TestCase):
self.assertEqual(translate('[!x]'), r'(?s:[^x])\Z')
self.assertEqual(translate('[^x]'), r'(?s:[\^x])\Z')
self.assertEqual(translate('[x'), r'(?s:\[x)\Z')
+ # from the docs
+ self.assertEqual(translate('*.txt'), r'(?s:.*\.txt)\Z')
+ # squash consecutive stars
+ self.assertEqual(translate('*********'), r'(?s:.*)\Z')
+ self.assertEqual(translate('A*********'), r'(?s:A.*)\Z')
+ self.assertEqual(translate('*********A'), r'(?s:.*A)\Z')
+ self.assertEqual(translate('A*********?[?]?'), r'(?s:A.*.[?].)\Z')
+ # fancy translation to prevent exponential-time match failure
+ self.assertEqual(translate('**a*a****a'),
+ r'(?s:(?=(?P<g1>.*?a))(?P=g1)(?=(?P<g2>.*?a))(?P=g2).*a)\Z')
class FilterTestCase(unittest.TestCase):