8000 bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32… · python/cpython@1b21b55 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1b21b55

Browse files
bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012)
(cherry picked from commit 08eb754) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 4c989e1 commit 1b21b55

File tree

3 files changed

+42
-4
lines changed

3 files changed

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

Modules/_sre.c

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,6 +2510,25 @@ scanner_dealloc(ScannerObject* self)
25102510
Py_DECREF(tp);
25112511
}
25122512

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

2530-
if (state->start == NULL)
2549+
if (!scanner_begin(self)) {
2550+
return NULL;
2551+
}
2552+
if (state->start == NULL) {
2553+
scanner_end(self);
25312554
Py_RETURN_NONE;
2555+
}
25322556

25332557
state_reset(state);
25342558

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

25372561
status = sre_match(state, PatternObject_GetCode(self->pattern));
2538-
if (PyErr_Occurred())
2562+
if (PyErr_Occurred()) {
2563+
scanner_end(self);
25392564
return NULL;
2565+
}
25402566

25412567
match = pattern_new_match(module_state, (PatternObject*) self->pattern,
25422568
state, status);
@@ -2548,6 +2574,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls)
25482574
state->start = state->ptr;
25492575
}
25502576

2577+
scanner_end(self);
25512578
return match;
25522579
}
25532580

@@ -2569,16 +2596,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls)
25692596
PyObject* match;
25702597
Py_ssize_t status;
25712598

2572-
if (state->start == NULL)
2599+
if (!scanner_begin(self)) {
2600+
return NULL;
2601+
}
2602+
if (state->start == NULL) {
2603+
scanner_end(self);
25732604
Py_RETURN_NONE;
2605+
}
25742606

25752607
state_reset(state);
25762608

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

25792611
status = sre_search(state, PatternObject_GetCode(self->pattern));
2580-
if (PyErr_Occurred())
2612+
if (PyErr_Occurred()) {
2613+
scanner_end(self);
25812614
return NULL;
2615+
}
25822616

25832617
match = pattern_new_match(module_state, (PatternObject*) self->pattern,
25842618
state, status);
@@ -2590,6 +2624,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls)
25902624
state->start = state->ptr;
25912625
}
25922626

2627+
scanner_end(self);
25932628
return match;
25942629
}
25952630

@@ -2607,6 +2642,7 @@ pattern_scanner(_sremodulestate *module_state,
26072642
if (!scanner)
26082643
return NULL;
26092644
scanner->pattern = NULL;
2645+
scanner->executing = 0;
26102646

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

Modules/sre.h

Lines changed: 1 addition & 0 deletions
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)
0