changeset: 106418:4e65d6c20dae branch: 3.5 parent: 106405:d7b637af5a7e user: Serhiy Storchaka date: Sat Feb 04 22:53:57 2017 +0200 files: Lib/test/test_re.py Misc/NEWS Modules/_sre.c description: Issue #29444: Fixed out-of-bounds buffer access in the group() method of the match object. Based on patch by WGH. diff -r d7b637af5a7e -r 4e65d6c20dae Lib/test/test_re.py --- a/Lib/test/test_re.py Sat Feb 04 11:04:00 2017 +0200 +++ b/Lib/test/test_re.py Sat Feb 04 22:53:57 2017 +0200 @@ -1679,6 +1679,16 @@ self.checkPatternError(r'(?<>)', 'unknown extension ?<>', 1) self.checkPatternError(r'(?', 'unexpected end of pattern', 2) + def test_bug_29444(self): + s = bytearray(b'abcdefgh') + m = re.search(b'[a-h]+', s) + m2 = re.search(b'[e-h]+', s) + self.assertEqual(m.group(), b'abcdefgh') + self.assertEqual(m2.group(), b'efgh') + s[:] = b'xyz' + self.assertEqual(m.group(), b'xyz') + self.assertEqual(m2.group(), b'') + class PatternReprTests(unittest.TestCase): def check(self, pattern, expected): diff -r d7b637af5a7e -r 4e65d6c20dae Misc/NEWS --- a/Misc/NEWS Sat Feb 04 11:04:00 2017 +0200 +++ b/Misc/NEWS Sat Feb 04 22:53:57 2017 +0200 @@ -21,6 +21,9 @@ Library ------- +- Issue #29444: Fixed out-of-bounds buffer access in the group() method of + the match object. Based on patch by WGH. + - Issue #29335: Fix subprocess.Popen.wait() when the child process has exited to a stopped instead of terminated state (ex: when under ptrace). diff -r d7b637af5a7e -r 4e65d6c20dae Modules/_sre.c --- a/Modules/_sre.c Sat Feb 04 11:04:00 2017 +0200 +++ b/Modules/_sre.c Sat Feb 04 22:53:57 2017 +0200 @@ -2015,6 +2015,7 @@ Py_buffer view; PyObject *result; void* ptr; + Py_ssize_t i, j; if (index < 0 || index >= self->groups) { /* raise IndexError if we were given a bad group number */ @@ -2036,8 +2037,12 @@ ptr = getstring(self->string, &length, &isbytes, &charsize, &view); if (ptr == NULL) return NULL; - result = getslice(isbytes, ptr, - self->string, self->mark[index], self->mark[index+1]); + + i = self->mark[index]; + j = self->mark[index+1]; + i = Py_MIN(i, length); + j = Py_MIN(j, length); + result = getslice(isbytes, ptr, self->string, i, j); if (isbytes && view.buf != NULL) PyBuffer_Release(&view); return result;