From 167aa37ff204cd31492eb225ff4ab2c0d32a4efa Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 9 Jun 2023 21:12:14 +0300 Subject: [PATCH 1/7] gh-105375: Improve error handling in `zoneinfo` module --- ...-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst | 1 + Modules/_zoneinfo.c | 34 +++++++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst new file mode 100644 index 00000000000000..64798fa4ce6b7c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst @@ -0,0 +1 @@ +Improve error handling in :mod:`zoneinfo`. diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 0dcdb4da47d5db..af5f1ed208d909 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -693,15 +693,26 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) dt = tmp; } else { - PyObject *replace = PyObject_GetAttrString(tmp, "replace"); - PyObject *args = PyTuple_New(0); - PyObject *kwargs = PyDict_New(); + PyObject *replace; + PyObject *args; + PyObject *kwargs; - Py_DECREF(tmp); - if (args == NULL || kwargs == NULL || replace == NULL) { - Py_XDECREF(args); - Py_XDECREF(kwargs); - Py_XDECREF(replace); + replace = PyObject_GetAttrString(tmp, "replace"); + if (replace == NULL) { + Py_DECREF(tmp); + return NULL; + } + args = PyTuple_New(0); + if (replace == NULL) { + Py_DECREF(tmp); + Py_DECREF(replace); + return NULL; + } + kwargs = PyDict_New(); + if (kwargs == NULL) { + Py_DECREF(tmp); + Py_DECREF(replace); + Py_DECREF(args); return NULL; } @@ -1068,11 +1079,14 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj) // Load UTC offsets and isdst (size num_ttinfos) utcoff = PyMem_Malloc(self->num_ttinfos * sizeof(long)); + if (utcoff == NULL) { + goto error; + } isdst = PyMem_Malloc(self->num_ttinfos * sizeof(unsigned char)); - - if (utcoff == NULL || isdst == NULL) { + if (isdst == NULL) { goto error; } + for (size_t i = 0; i < self->num_ttinfos; ++i) { PyObject *num = PyTuple_GetItem(utcoff_list, i); if (num == NULL) { From 039543027100741240b924e0b31e30ee4ef54115 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 9 Jun 2023 22:58:20 +0300 Subject: [PATCH 2/7] Revert PyMem_Malloc change --- Modules/_zoneinfo.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index af5f1ed208d909..ccaf9b97dc0d41 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -1079,11 +1079,8 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj) // Load UTC offsets and isdst (size num_ttinfos) utcoff = PyMem_Malloc(self->num_ttinfos * sizeof(long)); - if (utcoff == NULL) { - goto error; - } isdst = PyMem_Malloc(self->num_ttinfos * sizeof(unsigned char)); - if (isdst == NULL) { + if (utcoff == NULL || isdst == NULL) { goto error; } From 1a4a68bd35b026fce1a0bd2bfcd87aecb91b8734 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 9 Jun 2023 22:58:34 +0300 Subject: [PATCH 3/7] Update Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst Co-authored-by: Erlend E. Aasland --- .../next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst b/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst index 64798fa4ce6b7c..4202b758d1db56 100644 --- a/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst +++ b/Misc/NEWS.d/next/Library/2023-06-09-21-11-28.gh-issue-105375.4Mxn7t.rst @@ -1 +1 @@ -Improve error handling in :mod:`zoneinfo`. +Fix bugs in :mod:`zoneinfo` where exceptions could be overwritten. From 9e28c5de8b799a003ae2d9aa51e65797e056d1ec Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 9 Jun 2023 23:19:07 +0300 Subject: [PATCH 4/7] Address review --- Modules/_zoneinfo.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index ccaf9b97dc0d41..450ea27ddf3592 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -693,22 +693,18 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) dt = tmp; } else { - PyObject *replace; - PyObject *args; - PyObject *kwargs; - - replace = PyObject_GetAttrString(tmp, "replace"); + PyObject *replace = PyObject_GetAttrString(tmp, "replace"); if (replace == NULL) { Py_DECREF(tmp); return NULL; } - args = PyTuple_New(0); + PyObject *args = PyTuple_New(0); if (replace == NULL) { Py_DECREF(tmp); Py_DECREF(replace); return NULL; } - kwargs = PyDict_New(); + PyObject *kwargs = PyDict_New(); if (kwargs == NULL) { Py_DECREF(tmp); Py_DECREF(replace); From 9e559e0ffecc5657d9e2642bc8c868d98089dae5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 22:21:35 +0200 Subject: [PATCH 5/7] Update Modules/_zoneinfo.c --- Modules/_zoneinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 450ea27ddf3592..9ce4c233f4d50f 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -699,7 +699,7 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) return NULL; } PyObject *args = PyTuple_New(0); - if (replace == NULL) { + if (args == NULL) { Py_DECREF(tmp); Py_DECREF(replace); return NULL; From 98ea01b83c239d8d66a0ade2f43bb11cfdb91a2d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 9 Jun 2023 22:25:19 +0200 Subject: [PATCH 6/7] Revert unneeded newline change --- Modules/_zoneinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 9ce4c233f4d50f..c85aa95cbdd891 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -1076,10 +1076,10 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj) // Load UTC offsets and isdst (size num_ttinfos) utcoff = PyMem_Malloc(self->num_ttinfos * sizeof(long)); isdst = PyMem_Malloc(self->num_ttinfos * sizeof(unsigned char)); + if (utcoff == NULL || isdst == NULL) { goto error; } - for (size_t i = 0; i < self->num_ttinfos; ++i) { PyObject *num = PyTuple_GetItem(utcoff_list, i); if (num == NULL) { From 8be2d2432cf89211acc14300b9e49783fe5b38a0 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 9 Jun 2023 23:46:49 +0300 Subject: [PATCH 7/7] Address review --- Modules/_zoneinfo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index c85aa95cbdd891..0ced9d08b9eb75 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -694,19 +694,17 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) } else { PyObject *replace = PyObject_GetAttrString(tmp, "replace"); + Py_DECREF(tmp); if (replace == NULL) { - Py_DECREF(tmp); return NULL; } PyObject *args = PyTuple_New(0); if (args == NULL) { - Py_DECREF(tmp); Py_DECREF(replace); return NULL; } PyObject *kwargs = PyDict_New(); if (kwargs == NULL) { - Py_DECREF(tmp); Py_DECREF(replace); Py_DECREF(args); return NULL;