From ed038953fc2316117a3eaad066b93b0348131fd8 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 11 Jun 2023 13:01:18 -0700 Subject: [PATCH] [3.12] gh-105375: Improve error handling in PyUnicode_BuildEncodingMap() (GH-105491) (#105661) Bail on first error to prevent exceptions from possibly being overwritten. (cherry picked from commit 555be81026fe1205d16c02f6321221381174cd07) Co-authored-by: Erlend E. Aasland --- ...-06-08-09-25-52.gh-issue-105375.ocB7fT.rst | 2 ++ Objects/unicodeobject.c | 29 +++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst new file mode 100644 index 00000000000000..24fac2df4d0955 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-06-08-09-25-52.gh-issue-105375.ocB7fT.rst @@ -0,0 +1,2 @@ +Improve error handling in :c:func:`PyUnicode_BuildEncodingMap` where an +exception could end up being overwritten. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6f25f91c0ff28d..a0be85718119de 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7934,25 +7934,30 @@ PyUnicode_BuildEncodingMap(PyObject* string) if (need_dict) { PyObject *result = PyDict_New(); - PyObject *key, *value; if (!result) return NULL; for (i = 0; i < length; i++) { - key = PyLong_FromLong(PyUnicode_READ(kind, data, i)); - value = PyLong_FromLong(i); - if (!key || !value) - goto failed1; - if (PyDict_SetItem(result, key, value) == -1) - goto failed1; + Py_UCS4 c = PyUnicode_READ(kind, data, i); + PyObject *key = PyLong_FromLong(c); + if (key == NULL) { + Py_DECREF(result); + return NULL; + } + PyObject *value = PyLong_FromLong(i); + if (value == NULL) { + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } + int rc = PyDict_SetItem(result, key, value); Py_DECREF(key); Py_DECREF(value); + if (rc < 0) { + Py_DECREF(result); + return NULL; + } } return result; - failed1: - Py_XDECREF(key); - Py_XDECREF(value); - Py_DECREF(result); - return NULL; } /* Create a three-level trie */