Commit dbc52f8a authored by Benjamin Peterson's avatar Benjamin Peterson

check for string attribute names in old-style classes (closes #14334)

parent 6e7832b0
...@@ -628,6 +628,13 @@ class ClassTests(unittest.TestCase): ...@@ -628,6 +628,13 @@ class ClassTests(unittest.TestCase):
a = A(hash(A.f.im_func)^(-1)) a = A(hash(A.f.im_func)^(-1))
hash(a.f) hash(a.f)
def testAttrSlots(self):
class C:
pass
for c in C, C():
self.assertRaises(TypeError, type(c).__getattribute__, c, [])
self.assertRaises(TypeError, type(c).__setattr__, c, [], [])
def test_main(): def test_main():
with test_support.check_py3k_warnings( with test_support.check_py3k_warnings(
(".+__(get|set|del)slice__ has been removed", DeprecationWarning), (".+__(get|set|del)slice__ has been removed", DeprecationWarning),
......
...@@ -10,7 +10,8 @@ Core and Builtins ...@@ -10,7 +10,8 @@ Core and Builtins
----------------- -----------------
- Issue #14334: Prevent in a segfault in type.__getattribute__ when it was not - Issue #14334: Prevent in a segfault in type.__getattribute__ when it was not
passed strings. passed strings. Also fix segfaults in the __getattribute__ and __setattr__
methods of old-style classes.
- Issue #14161: fix the __repr__ of file objects to escape the file name. - Issue #14161: fix the __repr__ of file objects to escape the file name.
......
...@@ -225,10 +225,16 @@ static PyObject * ...@@ -225,10 +225,16 @@ static PyObject *
class_getattr(register PyClassObject *op, PyObject *name) class_getattr(register PyClassObject *op, PyObject *name)
{ {
register PyObject *v; register PyObject *v;
register char *sname = PyString_AsString(name); register char *sname;
PyClassObject *klass; PyClassObject *klass;
descrgetfunc f; descrgetfunc f;
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
return NULL;
}
sname = PyString_AsString(name);
if (sname[0] == '_' && sname[1] == '_') { if (sname[0] == '_' && sname[1] == '_') {
if (strcmp(sname, "__dict__") == 0) { if (strcmp(sname, "__dict__") == 0) {
if (PyEval_GetRestricted()) { if (PyEval_GetRestricted()) {
...@@ -336,6 +342,10 @@ class_setattr(PyClassObject *op, PyObject *name, PyObject *v) ...@@ -336,6 +342,10 @@ class_setattr(PyClassObject *op, PyObject *name, PyObject *v)
"classes are read-only in restricted mode"); "classes are read-only in restricted mode");
return -1; return -1;
} }
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
return -1;
}
sname = PyString_AsString(name); sname = PyString_AsString(name);
if (sname[0] == '_' && sname[1] == '_') { if (sname[0] == '_' && sname[1] == '_') {
Py_ssize_t n = PyString_Size(name); Py_ssize_t n = PyString_Size(name);
...@@ -699,7 +709,14 @@ static PyObject * ...@@ -699,7 +709,14 @@ static PyObject *
instance_getattr1(register PyInstanceObject *inst, PyObject *name) instance_getattr1(register PyInstanceObject *inst, PyObject *name)
{ {
register PyObject *v; register PyObject *v;
register char *sname = PyString_AsString(name); register char *sname;
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
return NULL;
}
sname = PyString_AsString(name);
if (sname[0] == '_' && sname[1] == '_') { if (sname[0] == '_' && sname[1] == '_') {
if (strcmp(sname, "__dict__") == 0) { if (strcmp(sname, "__dict__") == 0) {
if (PyEval_GetRestricted()) { if (PyEval_GetRestricted()) {
...@@ -810,7 +827,14 @@ static int ...@@ -810,7 +827,14 @@ static int
instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v) instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
{ {
PyObject *func, *args, *res, *tmp; PyObject *func, *args, *res, *tmp;
char *sname = PyString_AsString(name); char *sname;
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
return -1;
}
sname = PyString_AsString(name);
if (sname[0] == '_' && sname[1] == '_') { if (sname[0] == '_' && sname[1] == '_') {
Py_ssize_t n = PyString_Size(name); Py_ssize_t n = PyString_Size(name);
if (sname[n-1] == '_' && sname[n-2] == '_') { if (sname[n-1] == '_' && sname[n-2] == '_') {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment