[Python-checkins] cpython (2.7): check for string attribute names in old-style classes (closes #14334)

benjamin.peterson python-checkins at python.org
Fri Mar 16 16:58:57 CET 2012


http://hg.python.org/cpython/rev/3d4d52e47431
changeset: 75745:3d4d52e47431
branch: 2.7
parent: 75740:d1cf6008a565
user: Benjamin Peterson <benjamin at python.org>
date: Fri Mar 16 10:58:46 2012 -0500
summary:
 check for string attribute names in old-style classes (closes #14334)
files:
 Lib/test/test_class.py | 7 +++++++
 Misc/NEWS | 3 ++-
 Objects/classobject.c | 30 +++++++++++++++++++++++++++---
 3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -628,6 +628,13 @@
 a = A(hash(A.f.im_func)^(-1))
 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():
 with test_support.check_py3k_warnings(
 (".+__(get|set|del)slice__ has been removed", DeprecationWarning),
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,7 +10,8 @@
 -----------------
 
 - 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.
 
diff --git a/Objects/classobject.c b/Objects/classobject.c
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -225,10 +225,16 @@
 class_getattr(register PyClassObject *op, PyObject *name)
 {
 register PyObject *v;
- register char *sname = PyString_AsString(name);
+ register char *sname;
 PyClassObject *klass;
 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 (strcmp(sname, "__dict__") == 0) {
 if (PyEval_GetRestricted()) {
@@ -336,6 +342,10 @@
 "classes are read-only in restricted mode");
 return -1;
 }
+ 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] == '_') {
 Py_ssize_t n = PyString_Size(name);
@@ -699,7 +709,14 @@
 instance_getattr1(register PyInstanceObject *inst, PyObject *name)
 {
 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 (strcmp(sname, "__dict__") == 0) {
 if (PyEval_GetRestricted()) {
@@ -810,7 +827,14 @@
 instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
 {
 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] == '_') {
 Py_ssize_t n = PyString_Size(name);
 if (sname[n-1] == '_' && sname[n-2] == '_') {
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /