]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-151763: Fix OOM-0013 crash when the parser or compiler fails to allocate...
authortonghuaroot (童话) <tonghuaroot@gmail.com>
Thu, 2 Jul 2026 08:22:46 +0000 (16:22 +0800)
committerGitHub <noreply@github.com>
Thu, 2 Jul 2026 08:22:46 +0000 (09:22 +0100)
Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-12-03-55.gh-issue-151763.K7QfWG.rst [new file with mode: 0644]
Parser/pegen.c
Python/compile.c

diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-12-03-55.gh-issue-151763.K7QfWG.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-12-03-55.gh-issue-151763.K7QfWG.rst
new file mode 100644 (file)
index 0000000..64d0146
--- /dev/null
@@ -0,0 +1,3 @@
+Fix a potential crash in :func:`compile`, :func:`exec`, :func:`eval` and
+:func:`ast.parse` when an allocation fails: the parser or compiler could
+return without setting an exception.
index f01cc1ed03f287e23d876380a2fde11342c16b78..98256046032a8dfdda32490f224ecd0f6597d499 100644 (file)
@@ -894,6 +894,11 @@ _PyPegen_run_parser(Parser *p)
 {
     void *res = _PyPegen_parse(p);
     assert(p->level == 0);
+    if (res != NULL && PyErr_Occurred()) {
+        // Discard a result returned with an exception still pending
+        // (e.g. a MemoryError from a recovered-from allocation failure).
+        return NULL;
+    }
     if (res == NULL) {
         if ((p->flags & PyPARSE_ALLOW_INCOMPLETE_INPUT) &&  _is_end_of_source(p)) {
             PyErr_Clear();
@@ -944,7 +949,10 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena
     if (tok == NULL) {
         if (PyErr_Occurred()) {
             _PyPegen_raise_tokenizer_init_error(filename_ob);
-            return NULL;
+        }
+        else {
+            // The only silent tokenizer init failure is a failed allocation.
+            PyErr_NoMemory();
         }
         return NULL;
     }
@@ -998,6 +1006,10 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen
         if (PyErr_Occurred()) {
             _PyPegen_raise_tokenizer_init_error(filename_ob);
         }
+        else {
+            // The only silent tokenizer init failure is a failed allocation.
+            PyErr_NoMemory();
+        }
         return NULL;
     }
     // This transfers the ownership to the tokenizer
index 4ab1280e91de7536ba47a2c5945dd935992dc369..a2563a434232fcaa4c15ee780bf7ad7639ca9266 100644 (file)
@@ -430,6 +430,7 @@ new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
 {
     struct compiler *c = PyMem_Calloc(1, sizeof(struct compiler));
     if (c == NULL) {
+        PyErr_NoMemory();
         return NULL;
     }
     if (compiler_setup(c, mod, filename, pflags, optimize, arena) < 0) {