diff options
| author | molsonkiko <46202915+molsonkiko@users.noreply.github.com> | 2023-03-26 17:45:01 -0700 |
|---|---|---|
| committer | molsonkiko <46202915+molsonkiko@users.noreply.github.com> | 2023-03-26 17:45:01 -0700 |
| commit | 09c23ef73c839d3a7f31e755f40f2f06b9791b7f (patch) | |
| tree | 526f251000553c4c6fb242b9842b79520f945b89 /numpy/f2py | |
| parent | fd0f29de9365dcceec26d6a2a7539f61b0b037cf (diff) | |
| download | numpy-09c23ef73c839d3a7f31e755f40f2f06b9791b7f.tar.gz | |
make regex still match cases where OG fix failed
My first replacement regex would have failed to match
cases like '@)@bind foo bar baz@(@@)@' which should
apparently be matched.
Added a test to make sure the regex does this.
Diffstat (limited to 'numpy/f2py')
| -rwxr-xr-x | numpy/f2py/crackfortran.py | 2 | ||||
| -rw-r--r-- | numpy/f2py/tests/test_crackfortran.py | 25 |
2 files changed, 20 insertions, 7 deletions
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py index 901be1a83..36a913047 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*@\)@))*\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*\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 67693b019..449251435 100644 --- a/numpy/f2py/tests/test_crackfortran.py +++ b/numpy/f2py/tests/test_crackfortran.py @@ -4,7 +4,7 @@ import time import unicodedata import pytest import numpy as np -from numpy.f2py.crackfortran import markinnerspaces +from numpy.f2py.crackfortran import markinnerspaces, nameargspattern from . import util from numpy.f2py import crackfortran import textwrap @@ -279,19 +279,32 @@ class TestUnicodeComment(util.F2PyTest): self.module.foo(3) class TestNameArgsPatternBacktracking: - def test_nameargspattern_backtracking(self): + @pytest.mark.parametrize( + ['adversary'], + [ + ('@)@bind@(@',), + ('@)@bind @(@',), + ('@)@bind foo bar baz@(@',) + ] + ) + def test_nameargspattern_backtracking(self, adversary): '''address ReDOS vulnerability: https://github.com/numpy/numpy/issues/23338''' last_time = 0. - trials_per_count = 32 - start_reps, end_reps = 10, 16 + trials_per_count = 128 + start_reps, end_reps = 15, 25 for ii in range(start_reps, end_reps): - atbindat = '@)@bind@(@' * ii + repeated_adversary = adversary * ii total_time = 0 for _ in range(trials_per_count): t0 = time.perf_counter() - crackfortran.nameargspattern.search(atbindat) + mtch = nameargspattern.search(repeated_adversary) total_time += (time.perf_counter() - t0) + assert not mtch + # if the adversary is capped with @)@, it becomes acceptable. + # that should still be true. + good_version_of_adversary = repeated_adversary + '@)@' + assert nameargspattern.search(good_version_of_adversary) if ii > start_reps: # the hallmark of exponentially catastrophic backtracking # is that runtime doubles for every added instance of |
