https://github.com/python/cpython/commit/cdc1472dfd1c105a827535bdde73126af7eef12a
commit: cdc1472dfd1c105a827535bdde73126af7eef12a
branch: 3.13
author: tonghuaroot (童话) <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-07-02T09:22:46+01:00
summary:
[3.13] gh-151763: Fix OOM-0013 crash when the parser or compiler fails to
allocate (GH-151968) (#152840)
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 f01cc1ed03f287e..98256046032a8df 100644
--- a/Parser/pegen.c
+++ b/Parser/pegen.c
@@ -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
diff --git a/Python/compile.c b/Python/compile.c
index 4ab1280e91de753..a2563a434232fca 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -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) {
_______________________________________________
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]