diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index feb71603e0a..c04b626d3ce 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -685,6 +685,12 @@ class ReTests(unittest.TestCase): self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a#\nb#\nc#') self.assertEqual(pattern.sub('#', '\n'), '#\n#') + 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 9386a18142b..a292c74fd3e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -48,6 +48,9 @@ Core and Builtins Library ------- +- Issue #3299: Fix possible crash in the _sre module when given bad + argument values in debug mode. Patch by Victor Stinner. + - Issue #5827: Make sure that normpath preserves unicode. Initial patch by Matt Giuca. diff --git a/Modules/_sre.c b/Modules/_sre.c index 1aea53bf94e..731b13d1a88 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2684,6 +2684,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; @@ -2700,7 +2704,7 @@ _compile(PyObject* self_, PyObject* args) } if (PyErr_Occurred()) { - PyObject_DEL(self); + Py_DECREF(self); return NULL; } @@ -3718,7 +3722,7 @@ static void scanner_dealloc(ScannerObject* self) { state_fini(&self->state); - Py_DECREF(self->pattern); + Py_XDECREF(self->pattern); PyObject_DEL(self); } @@ -3840,10 +3844,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; }