From fb5db7ec58624cab0797b4050735be865d380823 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 26 Oct 2020 08:43:39 +0200 Subject: bpo-42006: Stop using PyDict_GetItem, PyDict_GetItemString and _PyDict_GetItemId. (GH-22648) These functions are considered not safe because they suppress all internal errors and can return wrong result. PyDict_GetItemString and _PyDict_GetItemId can also silence current exception in rare cases. Remove no longer used _PyDict_GetItemId. Add _PyDict_ContainsId and rename _PyDict_Contains into _PyDict_Contains_KnownHash. --- Modules/_decimal/_decimal.c | 47 +++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'Modules/_decimal/_decimal.c') diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e7c44acba0..ea16c5a6cd 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3186,6 +3186,31 @@ dotsep_as_utf8(const char *s) return utf8; } +static int +dict_get_item_string(PyObject *dict, const char *key, PyObject **valueobj, const char **valuestr) +{ + *valueobj = NULL; + PyObject *keyobj = PyUnicode_FromString(key); + if (keyobj == NULL) { + return -1; + } + PyObject *value = PyDict_GetItemWithError(dict, keyobj); + Py_DECREF(keyobj); + if (value == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + value = PyUnicode_AsUTF8String(value); + if (value == NULL) { + return -1; + } + *valueobj = value; + *valuestr = PyBytes_AS_STRING(value); + return 0; +} + /* Formatted representation of a PyDecObject. */ static PyObject * dec_format(PyObject *dec, PyObject *args) @@ -3256,23 +3281,11 @@ dec_format(PyObject *dec, PyObject *args) "optional argument must be a dict"); goto finish; } - if ((dot = PyDict_GetItemString(override, "decimal_point"))) { - if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { - goto finish; - } - spec.dot = PyBytes_AS_STRING(dot); - } - if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { - if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { - goto finish; - } - spec.sep = PyBytes_AS_STRING(sep); - } - if ((grouping = PyDict_GetItemString(override, "grouping"))) { - if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) { - goto finish; - } - spec.grouping = PyBytes_AS_STRING(grouping); + if (dict_get_item_string(override, "decimal_point", &dot, &spec.dot) || + dict_get_item_string(override, "thousands_sep", &sep, &spec.sep) || + dict_get_item_string(override, "grouping", &grouping, &spec.grouping)) + { + goto finish; } if (mpd_validate_lconv(&spec) < 0) { PyErr_SetString(PyExc_ValueError, -- cgit v1.2.1