Skip to content

Commit 6b58f9a

Browse files
authored
gh-160316: Make re.Pattern.match() return None when pos > endpos (GH-160317)
gh-160316: Make re.Pattern.match() return None when pos > endpos Pattern.match(), prefixmatch(), fullmatch() and the scanner match() ran the engine with the start position past the end position, which could return an empty match or read past the end of the string. ANT-2026-NMTUWIC8
1 parent 83b047e commit 6b58f9a

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

‎Lib/test/test_re.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,25 @@ def test_keyword_parameters(self):
24282428
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
24292429
(7, 9))
24302430

2431+
def test_pos_greater_than_endpos(self):
2432+
# If endpos is less than pos, no match will be found.
2433+
for pattern in ['', r'$', r'^$', r'\b$', r'(?:x|$)']:
2434+
for string in ['abc\n', b'abc\n', bytearray(b'abc\n')]:
2435+
with self.subTest(pattern=pattern, string=string):
2436+
if isinstance(string, str):
2437+
p = re.compile(pattern, re.MULTILINE)
2438+
else:
2439+
p = re.compile(pattern.encode(), re.MULTILINE)
2440+
for pos, endpos in [(3, 0), (4, 0), (4, 3), (2, 1)]:
2441+
self.assertIsNone(p.match(string, pos, endpos))
2442+
self.assertIsNone(p.fullmatch(string, pos, endpos))
2443+
self.assertIsNone(p.search(string, pos, endpos))
2444+
self.assertIsNone(
2445+
p.scanner(string, pos, endpos).match())
2446+
self.assertIsNone(
2447+
p.scanner(string, pos, endpos).search())
2448+
self.assertEqual(p.findall(string, pos, endpos), [])
2449+
24312450
def test_bug_20998(self):
24322451
# Issue #20998: Fullmatch of repeated single character pattern
24332452
# with ignore case.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fix :meth:`re.Pattern.match`, :meth:`re.Pattern.prefixmatch`,
2+
:meth:`re.Pattern.fullmatch` and the ``match()`` and ``prefixmatch()`` methods
3+
of scanner objects returning an empty match, or reading past the end of the
4+
string, when *pos* is greater than *endpos*. They now return ``None``, as
5+
documented.

‎Modules/_sre/sre.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,10 @@ pattern_dealloc(PyObject *self)
899899
LOCAL(Py_ssize_t)
900900
sre_match(SRE_STATE* state, SRE_CODE* pattern)
901901
{
902+
/* No match if pos > endpos. */
903+
if (state->ptr > state->end) {
904+
return 0;
905+
}
902906
if (state->charsize == 1)
903907
return sre_ucs1_match(state, pattern, 1);
904908
if (state->charsize == 2)

0 commit comments

Comments
 (0)