https://github.com/python/cpython/commit/d13f5b27c8e1af059304c857986eec91de9146c8
commit: d13f5b27c8e1af059304c857986eec91de9146c8
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-07-02T09:23:23+01:00
summary:

[3.15] gh-151763: Fix OOM-0013 crash when the parser or compiler fails to 
allocate (GH-151968) (#152836)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-12-03-55.gh-issue-151763.K7QfWG.rst
M Parser/pegen.c
M 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
index 000000000000000..64d0146cb091016
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-23-12-03-55.gh-issue-151763.K7QfWG.rst
@@ -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.
diff --git a/Parser/pegen.c b/Parser/pegen.c
index bb222b50fc095f2..165dcb9f9950955 100644
--- a/Parser/pegen.c
+++ b/Parser/pegen.c
@@ -940,6 +940,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();
@@ -995,7 +1000,10 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int 
start_rule, PyObject *filena
     if (tok == NULL) {
         if (PyErr_Occurred()) {
             _PyTokenizer_raise_init_error(filename_ob);
-            return NULL;
+        }
+        else {
+            // The only silent tokenizer init failure is a failed allocation.
+            PyErr_NoMemory();
         }
         return NULL;
     }
@@ -1054,6 +1062,10 @@ _PyPegen_run_parser_from_string(const char *str, int 
start_rule, PyObject *filen
         if (PyErr_Occurred()) {
             _PyTokenizer_raise_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
diff --git a/Python/compile.c b/Python/compile.c
index e223ef42a42e22b..f2c1de5e0c07c63 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -174,6 +174,7 @@ new_compiler(mod_ty mod, PyObject *filename, 
PyCompilerFlags *pflags,
 {
     compiler *c = PyMem_Calloc(1, sizeof(compiler));
     if (c == NULL) {
+        PyErr_NoMemory();
         return NULL;
     }
     if (compiler_setup(c, mod, filename, pflags, optimize, arena, module) < 0) 
{

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to