bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012)

This commit is contained in:
Serhiy Storchaka 2022-03-21 13:00:43 +02:00 committed by GitHub
parent e63894b3ee
commit 08eb754d84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 4 deletions

View File

@ -0,0 +1 @@
Protect the :func:`re.finditer` iterator from re-entering.

View File

@ -2511,6 +2511,25 @@ scanner_dealloc(ScannerObject* self)
Py_DECREF(tp); Py_DECREF(tp);
} }
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] /*[clinic input]
_sre.SRE_Scanner.match _sre.SRE_Scanner.match
@ -2528,16 +2547,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls)
PyObject* match; PyObject* match;
Py_ssize_t status; Py_ssize_t status;
if (state->start == NULL) if (!scanner_begin(self)) {
return NULL;
}
if (state->start == NULL) {
scanner_end(self);
Py_RETURN_NONE; Py_RETURN_NONE;
}
state_reset(state); state_reset(state);
state->ptr = state->start; state->ptr = state->start;
status = sre_match(state, PatternObject_GetCode(self->pattern)); status = sre_match(state, PatternObject_GetCode(self->pattern));
if (PyErr_Occurred()) if (PyErr_Occurred()) {
scanner_end(self);
return NULL; return NULL;
}
match = pattern_new_match(module_state, (PatternObject*) self->pattern, match = pattern_new_match(module_state, (PatternObject*) self->pattern,
state, status); state, status);
@ -2549,6 +2575,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls)
state->start = state->ptr; state->start = state->ptr;
} }
scanner_end(self);
return match; return match;
} }
@ -2570,16 +2597,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls)
PyObject* match; PyObject* match;
Py_ssize_t status; Py_ssize_t status;
if (state->start == NULL) if (!scanner_begin(self)) {
return NULL;
}
if (state->start == NULL) {
scanner_end(self);
Py_RETURN_NONE; Py_RETURN_NONE;
}
state_reset(state); state_reset(state);
state->ptr = state->start; state->ptr = state->start;
status = sre_search(state, PatternObject_GetCode(self->pattern)); status = sre_search(state, PatternObject_GetCode(self->pattern));
if (PyErr_Occurred()) if (PyErr_Occurred()) {
scanner_end(self);
return NULL; return NULL;
}
match = pattern_new_match(module_state, (PatternObject*) self->pattern, match = pattern_new_match(module_state, (PatternObject*) self->pattern,
state, status); state, status);
@ -2591,6 +2625,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls)
state->start = state->ptr; state->start = state->ptr;
} }
scanner_end(self);
return match; return match;
} }
@ -2608,6 +2643,7 @@ pattern_scanner(_sremodulestate *module_state,
if (!scanner) if (!scanner)
return NULL; return NULL;
scanner->pattern = NULL; scanner->pattern = NULL;
scanner->executing = 0;
/* create search state object */ /* create search state object */
if (!state_init(&scanner->state, self, string, pos, endpos)) { if (!state_init(&scanner->state, self, string, pos, endpos)) {

View File

@ -89,6 +89,7 @@ typedef struct {
PyObject_HEAD PyObject_HEAD
PyObject* pattern; PyObject* pattern;
SRE_STATE state; SRE_STATE state;
int executing;
} ScannerObject; } ScannerObject;
#endif #endif