From f89949ec6741bd02841bece61f5b703e738dd13c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 21 Mar 2022 04:28:31 -0700 Subject: [PATCH] bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) (cherry picked from commit 08eb754d840696914928355014c2d424131f8835) Co-authored-by: Serhiy Storchaka --- .../2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst | 1 + Modules/_sre.c | 44 +++++++++++++++++-- Modules/sre.h | 1 + 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst diff --git a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst new file mode 100644 index 00000000000..053a2b2709e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst @@ -0,0 +1 @@ +Protect the :func:`re.finditer` iterator from re-entering. diff --git a/Modules/_sre.c b/Modules/_sre.c index 8225c36da1a..338530e2dc9 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2391,6 +2391,25 @@ scanner_dealloc(ScannerObject* self) PyObject_DEL(self); } +static int +scanner_begin(ScannerObject* self) +{ + if (self->executing) { + PyErr_SetString(PyExc_ValueError, + "regular expression scanner already executing"); + return 0; + } + self->executing = 1; + return 1; +} + +static void +scanner_end(ScannerObject* self) +{ + assert(self->executing); + self->executing = 0; +} + /*[clinic input] _sre.SRE_Scanner.match @@ -2404,16 +2423,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_match(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match((PatternObject*) self->pattern, state, status); @@ -2425,6 +2451,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2442,16 +2469,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match((PatternObject*) self->pattern, state, status); @@ -2463,6 +2497,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2476,6 +2511,7 @@ pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_ if (!scanner) return NULL; scanner->pattern = NULL; + scanner->executing = 0; /* create search state object */ if (!state_init(&scanner->state, self, string, pos, endpos)) { diff --git a/Modules/sre.h b/Modules/sre.h index 9b0d8b19042..785adbd003e 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -89,6 +89,7 @@ typedef struct { PyObject_HEAD PyObject* pattern; SRE_STATE state; + int executing; } ScannerObject; #endif