]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-151763: Fix OOM-0013 crash when the parser or compiler fails to allocate...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 2 Jul 2026 08:23:07 +0000 (10:23 +0200)
committerGitHub <noreply@github.com>
Thu, 2 Jul 2026 08:23:07 +0000 (09:23 +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 7bd189d36eac001144a4d36ca5da35500877a646..608adf3694117abffa7a95a9a3f38e4f7e98cd60 100644 (file)
@@ -949,6 +949,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();
@@ -1004,7 +1009,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;
     }
@@ -1058,6 +1066,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
index ab2e532e43e8d180a8e0f5a0ac9acb085651498e..c210c823157dd1c8dd9164ab48eed5cf71116946 100644 (file)
@@ -167,6 +167,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) < 0) {