Skip to content

Commit 08eb754

Browse files
bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012)
1 parent e63894b commit 08eb754

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Protect the :func:`re.finditer` iterator from re-entering.

Modules/_sre.c

+40-4
Original file line numberDiff line numberDiff line change
@@ -2511,6 +2511,25 @@ scanner_dealloc(ScannerObject* self)
25112511
Py_DECREF(tp);
25122512
}
25132513

2514+
static int
2515+
scanner_begin(ScannerObject* self)
2516+
{
2517+
if (self->executing) {
2518+
PyErr_SetString(PyExc_ValueError,
2519+
"regular expression scanner already executing");
2520+
return 0;
2521+
}
2522+
self->executing = 1;
2523+
return 1;
2524+
}
2525+
2526+
static void
2527+
scanner_end(ScannerObject* self)
2528+
{
2529+
assert(self->executing);
2530+
self->executing = 0;
2531+
}
2532+
25142533
/*[clinic input]
25152534
_sre.SRE_Scanner.match
25162535
@@ -2528,16 +2547,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls)
25282547
PyObject* match;
25292548
Py_ssize_t status;
25302549

2531-
if (state->start == NULL)
2550+
if (!scanner_begin(self)) {
2551+
return NULL;
2552+
}
2553+
if (state->start == NULL) {
2554+
scanner_end(self);
25322555
Py_RETURN_NONE;
2556+
}
25332557

25342558
state_reset(state);
25352559

25362560
state->ptr = state->start;
25372561

25382562
status = sre_match(state, PatternObject_GetCode(self->pattern));
2539-
if (PyErr_Occurred())
2563+
if (PyErr_Occurred()) {
2564+
scanner_end(self);
25402565
return NULL;
2566+
}
25412567

25422568
match = pattern_new_match(module_state, (PatternObject*) self->pattern,
25432569
state, status);
@@ -2549,6 +2575,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls)
25492575
state->start = state->ptr;
25502576
}
25512577

2578+
scanner_end(self);
25522579
return match;
25532580
}
25542581

@@ -2570,16 +2597,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls)
25702597
PyObject* match;
25712598
Py_ssize_t status;
25722599

2573-
if (state->start == NULL)
2600+
if (!scanner_begin(self)) {
2601+
return NULL;
2602+
}
2603+
if (state->start == NULL) {
2604+
scanner_end(self);
25742605
Py_RETURN_NONE;
2606+
}
25752607

25762608
state_reset(state);
25772609

25782610
state->ptr = state->start;
25792611

25802612
status = sre_search(state, PatternObject_GetCode(self->pattern));
2581-
if (PyErr_Occurred())
2613+
if (PyErr_Occurred()) {
2614+
scanner_end(self);
25822615
return NULL;
2616+
}
25832617

25842618
match = pattern_new_match(module_state, (PatternObject*) self->pattern,
25852619
state, status);
@@ -2591,6 +2625,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls)
25912625
state->start = state->ptr;
25922626
}
25932627

2628+
scanner_end(self);
25942629
return match;
25952630
}
25962631

@@ -2608,6 +2643,7 @@ pattern_scanner(_sremodulestate *module_state,
26082643
if (!scanner)
26092644
return NULL;
26102645
scanner->pattern = NULL;
2646+
scanner->executing = 0;
26112647

26122648
/* create search state object */
26132649
if (!state_init(&scanner->state, self, string, pos, endpos)) {

Modules/sre.h

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ typedef struct {
8989
PyObject_HEAD
9090
PyObject* pattern;
9191
SRE_STATE state;
92+
int executing;
9293
} ScannerObject;
9394

9495
#endif

0 commit comments

Comments
 (0)