diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2020-10-26 06:43:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-26 06:43:39 (GMT) |
commit | fb5db7ec58624cab0797b4050735be865d380823 (patch) | |
tree | 7b0421bb759ba01f0d735296738472faa4ce11b8 /Modules/_decimal | |
parent | 96a9eed2457c05af6953890d89463704c9d99c57 (diff) | |
download | cpython-fb5db7ec58624cab0797b4050735be865d380823.zip cpython-fb5db7ec58624cab0797b4050735be865d380823.tar.gz cpython-fb5db7ec58624cab0797b4050735be865d380823.tar.bz2 |
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.
Diffstat (limited to 'Modules/_decimal')
-rw-r--r-- | Modules/_decimal/_decimal.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e7c44ac..ea16c5a 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, |