[Python-checkins] CVS: python/dist/src/Objects object.c,2.99,2.100
M.-A. Lemburg
python-dev@python.org
Mon, 18 Sep 2000 09:21:00 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory slayer.i.sourceforge.net:/tmp/cvs-serv16900/Objects
Modified Files:
object.c
Log Message:
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.
Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.99
retrieving revision 2.100
diff -C2 -r2.99 -r2.100
*** object.c 2000/09/01 23:29:27 2.99
--- object.c 2000/09/18 16:20:57 2.100
***************
*** 704,712 ****
}
PyObject *
PyObject_GetAttr(PyObject *v, PyObject *name)
{
! if (v->ob_type->tp_getattro != NULL)
! return (*v->ob_type->tp_getattro)(v, name);
if (!PyString_Check(name)) {
--- 704,723 ----
}
+ /* Internal API needed by PyObject_GetAttr(): */
+ extern
+ PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+ const char *errors);
+
PyObject *
PyObject_GetAttr(PyObject *v, PyObject *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)) {
***************
*** 715,718 ****
--- 726,732 ----
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));
}
***************
*** 734,751 ****
{
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);
}
! else {
PyErr_SetString(PyExc_TypeError,
"attribute name must be string");
err = -1;
}
Py_DECREF(name);
return err;
--- 748,777 ----
{
int err;
!
! /* 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
! 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;