From: Serhiy Storchaka Date: Tue, 8 Nov 2016 21:13:36 +0000 (+0200) Subject: Fixed possible abort in ceval loop if _PyUnicode_FromId() fails. X-Git-Tag: v3.6.0b4~125 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4678b2f44876774b29720913657bb6c65e77e259;p=thirdparty%2FPython%2Fcpython.git Fixed possible abort in ceval loop if _PyUnicode_FromId() fails. Every opcode should end with DISPATCH() or goto error. --- 4678b2f44876774b29720913657bb6c65e77e259 diff --cc Python/ceval.c index 0add7ecc0938,7b405188d38c..b2c90cc3b48d --- a/Python/ceval.c +++ b/Python/ceval.c @@@ -2621,162 -2641,87 +2621,162 @@@ _PyEval_EvalFrameDefault(PyFrameObject DISPATCH(); } - TARGET_WITH_IMPL(BUILD_MAP_UNPACK_WITH_CALL, _build_map_unpack) - TARGET(BUILD_MAP_UNPACK) - _build_map_unpack: { - int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL; - int num_maps; - int i; - PyObject *sum = PyDict_New(); - if (sum == NULL) + TARGET(SETUP_ANNOTATIONS) { + _Py_IDENTIFIER(__annotations__); + int err; + PyObject *ann_dict; + if (f->f_locals == NULL) { + PyErr_Format(PyExc_SystemError, + "no locals found when setting up annotations"); goto error; - if (with_call) { - num_maps = oparg & 0xff; } - else { - num_maps = oparg; + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(f->f_locals)) { + ann_dict = _PyDict_GetItemId(f->f_locals, + &PyId___annotations__); + if (ann_dict == NULL) { + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + if (ann_dict == NULL) { + goto error; + } + err = _PyDict_SetItemId(f->f_locals, + &PyId___annotations__, ann_dict); + Py_DECREF(ann_dict); + if (err != 0) { + goto error; + } + } } - - for (i = num_maps; i > 0; i--) { - PyObject *arg = PEEK(i); - if (with_call) { - PyObject *intersection = _PyDictView_Intersect(sum, arg); - - if (intersection == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError) || - !PyMapping_Check(arg)) { - int function_location = (oparg>>8) & 0xff; - PyObject *func = ( - PEEK(function_location + num_maps)); - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - arg->ob_type->tp_name); - } - Py_DECREF(sum); + else { + /* do the same if locals() is not a dict */ + PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__); + if (ann_str == NULL) { - break; ++ goto error; + } + ann_dict = PyObject_GetItem(f->f_locals, ann_str); + if (ann_dict == NULL) { + if (!PyErr_ExceptionMatches(PyExc_KeyError)) { goto error; } - - if (PySet_GET_SIZE(intersection)) { - Py_ssize_t idx = 0; - PyObject *key; - int function_location = (oparg>>8) & 0xff; - PyObject *func = PEEK(function_location + num_maps); - Py_hash_t hash; - _PySet_NextEntry(intersection, &idx, &key, &hash); - if (!PyUnicode_Check(key)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s keywords must be strings", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func)); - } else { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s got multiple " - "values for keyword argument '%U'", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - key); - } - Py_DECREF(intersection); - Py_DECREF(sum); + PyErr_Clear(); + ann_dict = PyDict_New(); + if (ann_dict == NULL) { + goto error; + } + err = PyObject_SetItem(f->f_locals, ann_str, ann_dict); + Py_DECREF(ann_dict); + if (err != 0) { goto error; } - Py_DECREF(intersection); } + else { + Py_DECREF(ann_dict); + } + } + DISPATCH(); + } + + TARGET(BUILD_CONST_KEY_MAP) { + Py_ssize_t i; + PyObject *map; + PyObject *keys = TOP(); + if (!PyTuple_CheckExact(keys) || + PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { + PyErr_SetString(PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); + goto error; + } + map = _PyDict_NewPresized((Py_ssize_t)oparg); + if (map == NULL) { + goto error; + } + for (i = oparg; i > 0; i--) { + int err; + PyObject *key = PyTuple_GET_ITEM(keys, oparg - i); + PyObject *value = PEEK(i + 1); + err = PyDict_SetItem(map, key, value); + if (err != 0) { + Py_DECREF(map); + goto error; + } + } + + Py_DECREF(POP()); + while (oparg--) { + Py_DECREF(POP()); + } + PUSH(map); + DISPATCH(); + } + + TARGET(BUILD_MAP_UNPACK) { + Py_ssize_t i; + PyObject *sum = PyDict_New(); + if (sum == NULL) + goto error; + for (i = oparg; i > 0; i--) { + PyObject *arg = PEEK(i); if (PyDict_Update(sum, arg) < 0) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - if (with_call) { - int function_location = (oparg>>8) & 0xff; - PyObject *func = PEEK(function_location + num_maps); - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - arg->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not a mapping", + arg->ob_type->tp_name); + } + Py_DECREF(sum); + goto error; + } + } + + while (oparg--) + Py_DECREF(POP()); + PUSH(sum); + DISPATCH(); + } + + TARGET(BUILD_MAP_UNPACK_WITH_CALL) { + Py_ssize_t i; + PyObject *sum = PyDict_New(); + if (sum == NULL) + goto error; + + for (i = oparg; i > 0; i--) { + PyObject *arg = PEEK(i); + if (_PyDict_MergeEx(sum, arg, 2) < 0) { + PyObject *func = PEEK(2 + oparg); + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + arg->ob_type->tp_name); + } + else if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { + PyObject *key = PyTuple_GET_ITEM(val, 0); + if (!PyUnicode_Check(key)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } else { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); + } + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); } else { - PyErr_Format(PyExc_TypeError, - "'%.200s' object is not a mapping", - arg->ob_type->tp_name); + PyErr_Restore(exc, val, tb); } } Py_DECREF(sum);