https://github.com/python/cpython/commit/a2a45d7d13ceaf6d44b5b58392a36920937f63f7
commit: a2a45d7d13ceaf6d44b5b58392a36920937f63f7
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: vstinner <[email protected]>
date: 2026-03-20T16:44:19Z
summary:

[3.14] gh-146092: Raise MemoryError on allocation failure in _zoneinfo 
(GH-146165) (#146223)

gh-146092: Raise MemoryError on allocation failure in _zoneinfo (GH-146165)
(cherry picked from commit 6450b1d142b6254d2e3b2eba47d69125ca79b3fe)

Co-authored-by: Victor Stinner <[email protected]>

files:
M Modules/_zoneinfo.c

diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index 976b653c77a9f5..49e85473fdd881 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -272,6 +272,7 @@ zoneinfo_new_instance(zoneinfo_state *state, PyTypeObject 
*type, PyObject *key)
 
     goto cleanup;
 error:
+    assert(PyErr_Occurred());
     Py_CLEAR(self);
 cleanup:
     if (file_obj != NULL) {
@@ -458,6 +459,7 @@ zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, 
PyTypeObject *cls,
     return (PyObject *)self;
 
 error:
+    assert(PyErr_Occurred());
     Py_XDECREF(file_repr);
     Py_XDECREF(self);
     return NULL;
@@ -1040,10 +1042,12 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
     self->trans_list_utc =
         PyMem_Malloc(self->num_transitions * sizeof(int64_t));
     if (self->trans_list_utc == NULL) {
+        PyErr_NoMemory();
         goto error;
     }
     trans_idx = PyMem_Malloc(self->num_transitions * sizeof(Py_ssize_t));
     if (trans_idx == NULL) {
+        PyErr_NoMemory();
         goto error;
     }
 
@@ -1083,6 +1087,7 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
     isdst = PyMem_Malloc(self->num_ttinfos * sizeof(unsigned char));
 
     if (utcoff == NULL || isdst == NULL) {
+        PyErr_NoMemory();
         goto error;
     }
     for (size_t i = 0; i < self->num_ttinfos; ++i) {
@@ -1112,6 +1117,7 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
 
     dstoff = PyMem_Calloc(self->num_ttinfos, sizeof(long));
     if (dstoff == NULL) {
+        PyErr_NoMemory();
         goto error;
     }
 
@@ -1128,6 +1134,7 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
     // Build _ttinfo objects from utcoff, dstoff and abbr
     self->_ttinfos = PyMem_Malloc(self->num_ttinfos * sizeof(_ttinfo));
     if (self->_ttinfos == NULL) {
+        PyErr_NoMemory();
         goto error;
     }
     for (size_t i = 0; i < self->num_ttinfos; ++i) {
@@ -1148,6 +1155,7 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
     self->trans_ttinfos =
         PyMem_Calloc(self->num_transitions, sizeof(_ttinfo *));
     if (self->trans_ttinfos == NULL) {
+        PyErr_NoMemory();
         goto error;
     }
     for (size_t i = 0; i < self->num_transitions; ++i) {
@@ -1666,9 +1674,11 @@ parse_tz_str(zoneinfo_state *state, PyObject 
*tz_str_obj, _tzrule *out)
         p++;
 
         if (parse_transition_rule(&p, transitions[i])) {
-            PyErr_Format(PyExc_ValueError,
-                         "Malformed transition rule in TZ string: %R",
-                         tz_str_obj);
+            if (!PyErr_ExceptionMatches(PyExc_MemoryError)) {
+                PyErr_Format(PyExc_ValueError,
+                             "Malformed transition rule in TZ string: %R",
+                             tz_str_obj);
+            }
             goto error;
         }
     }
@@ -1868,6 +1878,7 @@ parse_transition_rule(const char **p, TransitionRuleType 
**out)
 
         CalendarRule *rv = PyMem_Calloc(1, sizeof(CalendarRule));
         if (rv == NULL) {
+            PyErr_NoMemory();
             return -1;
         }
 
@@ -1899,6 +1910,7 @@ parse_transition_rule(const char **p, TransitionRuleType 
**out)
 
         DayRule *rv = PyMem_Calloc(1, sizeof(DayRule));
         if (rv == NULL) {
+            PyErr_NoMemory();
             return -1;
         }
 
@@ -2132,6 +2144,7 @@ ts_to_local(size_t *trans_idx, int64_t *trans_utc, long 
*utcoff,
     for (size_t i = 0; i < 2; ++i) {
         trans_local[i] = PyMem_Malloc(num_transitions * sizeof(int64_t));
         if (trans_local[i] == NULL) {
+            PyErr_NoMemory();
             return -1;
         }
 

_______________________________________________
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