summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xnumpy/f2py/crackfortran.py2
-rw-r--r--numpy/f2py/tests/test_crackfortran.py11
2 files changed, 10 insertions, 3 deletions
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index b831697d8..901be1a83 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -935,7 +935,7 @@ typedefpattern = re.compile(
r'(?:,(?P<attributes>[\w(),]+))?(::)?(?P<name>\b[a-z$_][\w$]*\b)'
r'(?:\((?P<params>[\w,]*)\))?\Z', re.I)
nameargspattern = re.compile(
- r'\s*(?P<name>\b[\w$]+\b)\s*(@\(@\s*(?P<args>[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P<result>\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P<bind>.*)\s*@\)@))*\s*\Z', re.I)
+ r'\s*(?P<name>\b[\w$]+\b)\s*(@\(@\s*(?P<args>[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P<result>\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P<bind>[^\s@]*)\s*@\)@))*\s*\Z', re.I)
operatorpattern = re.compile(
r'\s*(?P<scheme>(operator|assignment))'
r'@\(@\s*(?P<name>[^)]+)\s*@\)@\s*\Z', re.I)
diff --git a/numpy/f2py/tests/test_crackfortran.py b/numpy/f2py/tests/test_crackfortran.py
index fc3ab561e..b577eaf38 100644
--- a/numpy/f2py/tests/test_crackfortran.py
+++ b/numpy/f2py/tests/test_crackfortran.py
@@ -279,7 +279,9 @@ class TestUnicodeComment(util.F2PyTest):
self.module.foo(3)
class TestNameArgsPatternBacktracking:
- def test_nameargspattern_backtracking():
+ def test_nameargspattern_backtracking(self):
+ '''address ReDOS vulnerability:
+ https://github.com/numpy/numpy/issues/23338'''
last_time = 0.
trials_per_count = 32
start_reps, end_reps = 10, 16
@@ -291,5 +293,10 @@ class TestNameArgsPatternBacktracking:
crackfortran.nameargspattern.search(atbindat)
total_time += (time.perf_counter() - t0)
if ii > start_reps:
- assert total_time < 1.9 * last_time, f'Going from {ii - 1} to {ii} approximately doubled time'
+ # the hallmark of exponentially catastrophic backtracking
+ # is that runtime doubles for every added instance of
+ # the problematic pattern.
+ assert total_time < 1.9 * last_time
+ # also try to rule out non-exponential but still bad cases
+ assert total_time < 1
last_time = total_time \ No newline at end of file