]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 21 Mar 2022 11:28:31 +0000 (04:28 -0700)
committerGitHub <noreply@github.com>
Mon, 21 Mar 2022 11:28:31 +0000 (04:28 -0700)
(cherry picked from commit 08eb754d840696914928355014c2d424131f8835)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst [new file with mode: 0644]
Modules/_sre.c
Modules/sre.h

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 (file)
index 0000000..053a2b2
--- /dev/null
@@ -0,0 +1 @@
+Protect the :func:`re.finditer` iterator from re-entering.
index 8225c36da1a38968708c169ec31b391b8fe76354..338530e2dc9936d4adfc79e7f9ada47a61a9c51f 100644 (file)
@@ -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)) {
index 9b0d8b190426acf96d431de8ee9c6bd94e5a352c..785adbd003e7fd93d3f445e446992310ed194d54 100644 (file)
@@ -89,6 +89,7 @@ typedef struct {
     PyObject_HEAD
     PyObject* pattern;
     SRE_STATE state;
+    int executing;
 } ScannerObject;
 
 #endif