diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 8b4d2689930..c41722c72f0 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -717,6 +717,12 @@ class ReTests(unittest.TestCase): self.assertRaises(ValueError, re.compile, '(?a)\w', re.UNICODE) self.assertRaises(ValueError, re.compile, '(?au)\w') + def test_dealloc(self): + # issue 3299: check for segfault in debug build + import _sre + long_overflow = sys.maxsize + 2 + self.assertRaises(TypeError, re.finditer, "a", {}) + self.assertRaises(OverflowError, _sre.compile, "abc", 0, [long_overflow]) def run_re_tests(): from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR diff --git a/Misc/NEWS b/Misc/NEWS index a577e65a239..f2e2fed6ca6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -213,6 +213,9 @@ C-API Library ------- +- Issue #3299: Fix possible crash in the _sre module when given bad + argument values in debug mode. Patch by Victor Stinner. + - Issue #2846: Add support for gzip.GzipFile reading zero-padded files. Patch by Brian Curtin. diff --git a/Modules/_sre.c b/Modules/_sre.c index 596fd19dfdb..7b3ee5fe3a8 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2674,6 +2674,10 @@ _compile(PyObject* self_, PyObject* args) self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n); if (!self) return NULL; + self->weakreflist = NULL; + self->pattern = NULL; + self->groupindex = NULL; + self->indexgroup = NULL; self->codesize = n; @@ -2689,7 +2693,7 @@ _compile(PyObject* self_, PyObject* args) } if (PyErr_Occurred()) { - PyObject_DEL(self); + Py_DECREF(self); return NULL; } @@ -3730,7 +3734,7 @@ static void scanner_dealloc(ScannerObject* self) { state_fini(&self->state); - Py_DECREF(self->pattern); + Py_XDECREF(self->pattern); PyObject_DEL(self); } @@ -3860,10 +3864,11 @@ pattern_scanner(PatternObject* pattern, PyObject* args) self = PyObject_NEW(ScannerObject, &Scanner_Type); if (!self) return NULL; + self->pattern = NULL; string = state_init(&self->state, pattern, string, start, end); if (!string) { - PyObject_DEL(self); + Py_DECREF(self); return NULL; }