]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Backport the Carlo Verre fix.
authorGuido van Rossum <guido@python.org>
Fri, 25 Apr 2003 05:40:32 +0000 (05:40 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 25 Apr 2003 05:40:32 +0000 (05:40 +0000)
Misc/NEWS
Objects/typeobject.c

index ed690b5cb0fd723ee0bdcc2545396399e6e4343f..e1ec2511916e609b23778f50bbc6f22db45ea3d4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,9 @@ What's New in Python 2.2.3 ?
 Release date: XX-XXX-2003
 ============================
 
+- It is no longer possible to use object.__setattr__ to circumvent the
+  restrictions on setting attributes of type objects.
+
 - Implemented os.fsync() for Windows, where it calls the MS _commit()
   function.  Before, there was no way in core Python to ensure file
   writes actually showed up on disk when necessary.
index b674c337783cb13c59b99bb3badc691160003924..e4b4c5c2d7486d5e3936dba257fa0c0bfc79c61c 100644 (file)
@@ -2594,6 +2594,24 @@ wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped)
        return PyInt_FromLong((long)res);
 }
 
+/* Helper to check for object.__setattr__ or __delattr__ applied to a type.
+   This is called the Carlo Verre hack after its discoverer. */
+static int
+hackcheck(PyObject *self, setattrofunc func, char *what)
+{
+       PyTypeObject *type = self->ob_type;
+       while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+               type = type->tp_base;
+       if (type->tp_setattro != func) {
+               PyErr_Format(PyExc_TypeError,
+                            "can't apply this %s to %s object",
+                            what,
+                            type->tp_name);
+               return 0;
+       }
+       return 1;
+}
+
 static PyObject *
 wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
 {
@@ -2603,6 +2621,8 @@ wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
 
        if (!PyArg_ParseTuple(args, "OO", &name, &value))
                return NULL;
+       if (!hackcheck(self, func, "__setattr__"))
+               return NULL;
        res = (*func)(self, name, value);
        if (res < 0)
                return NULL;
@@ -2619,6 +2639,8 @@ wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
 
        if (!PyArg_ParseTuple(args, "O", &name))
                return NULL;
+       if (!hackcheck(self, func, "__delattr__"))
+               return NULL;
        res = (*func)(self, name, NULL);
        if (res < 0)
                return NULL;