summaryrefslogtreecommitdiffstats
path: root/Objects/object.c
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2000-09-18 16:20:57 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2000-09-18 16:20:57 (GMT)
commite44e507b0e60de842f57ca79b45696dd263f257f (patch)
tree7c2c0714e7bfa7231350b099e5bf8b1a0e0367d9 /Objects/object.c
parent1de8098ca685a2d9e9c5eb2e3ebaeb8190004b4c (diff)
downloadcpython-e44e507b0e60de842f57ca79b45696dd263f257f.zip
cpython-e44e507b0e60de842f57ca79b45696dd263f257f.tar.gz
cpython-e44e507b0e60de842f57ca79b45696dd263f257f.tar.bz2
PyObject_SetAttr() and PyObject_GetAttr() now also accept Unicode
objects for the attribute name. Unicode objects are converted to a string using the default encoding before trying the lookup. Note that previously it was allowed to pass arbitrary objects as attribute name in case the tp_getattro/setattro slots were defined. This patch fixes this by applying an explicit string check first: all uses of these slots expect string objects and do not check for the type resulting in a core dump. The tp_getattro/setattro are still useful as optimization for lookups using interned string objects though. This patch fixes bug #113829.
Diffstat (limited to 'Objects/object.c')
-rw-r--r--Objects/object.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/Objects/object.c b/Objects/object.c
index 150f357..3323906 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -703,17 +703,31 @@ PyObject_SetAttrString(PyObject *v, char *name, PyObject *w)
}
}
+/* Internal API needed by PyObject_GetAttr(): */
+extern
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+ const char *errors);
+
PyObject *
PyObject_GetAttr(PyObject *v, PyObject *name)
{
- if (v->ob_type->tp_getattro != NULL)
- return (*v->ob_type->tp_getattro)(v, name);
+ /* The Unicode to string conversion is done here because the
+ existing tp_getattro slots expect a string object as name
+ and we wouldn't want to break those. */
+ if (PyUnicode_Check(name)) {
+ name = _PyUnicode_AsDefaultEncodedString(name, NULL);
+ if (name == NULL)
+ return NULL;
+ }
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"attribute name must be string");
return NULL;
}
+ if (v->ob_type->tp_getattro != NULL)
+ return (*v->ob_type->tp_getattro)(v, name);
+ else
return PyObject_GetAttrString(v, PyString_AS_STRING(name));
}
@@ -733,20 +747,32 @@ int
PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
{
int err;
- Py_INCREF(name);
- if (PyString_Check(name))
- PyString_InternInPlace(&name);
- if (v->ob_type->tp_setattro != NULL)
- err = (*v->ob_type->tp_setattro)(v, name, value);
- else if (PyString_Check(name)) {
- err = PyObject_SetAttrString(
- v, PyString_AS_STRING(name), value);
+
+ /* The Unicode to string conversion is done here because the
+ existing tp_setattro slots expect a string object as name
+ and we wouldn't want to break those. */
+ if (PyUnicode_Check(name)) {
+ name = PyUnicode_AsEncodedString(name, NULL, NULL);
+ if (name == NULL)
+ return -1;
}
- else {
+ else
+ Py_INCREF(name);
+
+ if (!PyString_Check(name)){
PyErr_SetString(PyExc_TypeError,
"attribute name must be string");
err = -1;
}
+ else {
+ PyString_InternInPlace(&name);
+ if (v->ob_type->tp_setattro != NULL)
+ err = (*v->ob_type->tp_setattro)(v, name, value);
+ else
+ err = PyObject_SetAttrString(v,
+ PyString_AS_STRING(name), value);
+ }
+
Py_DECREF(name);
return err;
}