Zope3 security checker python and C code is inconsistent
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Zope 3 |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
Testing schooltool on python 2.5 I have noticed a strange bug, I was getting "Invalid value, None. for security checker" while displaying a view for Not Found exception, the traceback seemed to indicate that i was getting an error while trying to look up __parent__ for the context object (the not found exception) in a viewlet on that page. I could not find the error in python code, as it only exists in C code and was introduced in:
http://
What I found strange is that python code handles None differently from it's C counterpart. If I remove C modules - both python 2.4 and python 2.5 work properly.
Any ideas why the same C code can be acting differently with different pythons?
And why is the C code implementation of Checker.proxy different from python code?
The python code looks like this:
def proxy(self, value):
'See IChecker'
if type(value) is Proxy:
return value
checker = getattr(value, '__Security_
if checker is None:
checker = selectChecker(
if checker is None:
return Proxy(value, checker)
the C code:
/* def proxy(self, value): */
static PyObject *
Checker_
{
PyObject *checker, *r;
/* if type(value) is Proxy: */
/* return value */
if ((PyObject*
{
Py_
return value;
}
/* checker = getattr(value, '__Security_
checker = PyObject_
/* if checker is None: */
if (checker == NULL)
{
PyErr_
/* checker = selectChecker(
checker = selectChecker(NULL, value);
if (checker == NULL)
return NULL;
/* if checker is None: */
/* return value */
if (checker == Py_None)
{
return value;
}
}
else if (checker == Py_None)
{
PyObject *errv = Py_BuildValue("sO",
if (errv != NULL)
{
}
return NULL;
}
r = PyObject_
Py_DECREF(
return r;
}
Ok, continuing the investigation:
it seems that python2.5 and python2.4 diverged in a different place in the code, as __Security_ checker_ _ is a property not an attribute, the problem is in it's implementation. Which again is different in C from what it is in python...
The method selectChecker in C has:
/* if checker is _defaultChecker and isinstance(object, Exception): */
/* return None */
if (checker == _defaultChecker IsInstance( object, PyExc_Exception)) INCREF( Py_None) ;
&& PyObject_
{
Py_
return Py_None;
}
While there is no such line in the python implementation.
And that line seems to be triggered in python2.5 while it is not in python2.4
Any ideas?