Skip to content

Commit f89949e

Browse files
bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012)
(cherry picked from commit 08eb754) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 58a7e13 commit f89949e

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
@@ -2391,6 +2391,25 @@ scanner_dealloc(ScannerObject* self)
23912391
PyObject_DEL(self);
23922392
}
23932393

2394+
static int
2395+
scanner_begin(ScannerObject* self)
2396+
{
2397+
if (self->executing) {
2398+
PyErr_SetString(PyExc_ValueError,
2399+
"regular expression scanner already executing");
2400+
return 0;
2401+
}
2402+
self->executing = 1;
2403+
return 1;
2404+
}
2405+
2406+
static void
2407+
scanner_end(ScannerObject* self)
2408+
{
2409+
assert(self->executing);
2410+
self->executing = 0;
2411+
}
2412+
23942413
/*[clinic input]
23952414
_sre.SRE_Scanner.match
23962415
@@ -2404,16 +2423,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self)
24042423
PyObject* match;
24052424
Py_ssize_t status;
24062425

2407-
if (state->start == NULL)
2426+
if (!scanner_begin(self)) {
2427+
return NULL;
2428+
}
2429+
if (state->start == NULL) {
2430+
scanner_end(self);
24082431
Py_RETURN_NONE;
2432+
}
24092433

24102434
state_reset(state);
24112435

24122436
state->ptr = state->start;
24132437

24142438
status = sre_match(state, PatternObject_GetCode(self->pattern));
2415-
if (PyErr_Occurred())
2439+
if (PyErr_Occurred()) {
2440+
scanner_end(self);
24162441
return NULL;
2442+
}
24172443

24182444
match = pattern_new_match((PatternObject*) self->pattern,
24192445
state, status);
@@ -2425,6 +2451,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self)
24252451
state->start = state->ptr;
24262452
}
24272453

2454+
scanner_end(self);
24282455
return match;
24292456
}
24302457

@@ -2442,16 +2469,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self)
24422469
PyObject* match;
24432470
Py_ssize_t status;
24442471

2445-
if (state->start == NULL)
2472+
if (!scanner_begin(self)) {
2473+
return NULL;
2474+
}
2475+
if (state->start == NULL) {
2476+
scanner_end(self);
24462477
Py_RETURN_NONE;
2478+
}
24472479

24482480
state_reset(state);
24492481

24502482
state->ptr = state->start;
24512483

24522484
status = sre_search(state, PatternObject_GetCode(self->pattern));
2453-
if (PyErr_Occurred())
2485+
if (PyErr_Occurred()) {
2486+
scanner_end(self);
24542487
return NULL;
2488+
}
24552489

24562490
match = pattern_new_match((PatternObject*) self->pattern,
24572491
state, status);
@@ -2463,6 +2497,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self)
24632497
state->start = state->ptr;
24642498
}
24652499

2500+
scanner_end(self);
24662501
return match;
24672502
}
24682503

@@ -2476,6 +2511,7 @@ pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_
24762511
if (!scanner)
24772512
return NULL;
24782513
scanner->pattern = NULL;
2514+
scanner->executing = 0;
24792515

24802516
/* create search state object */
24812517
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)