[Python-Dev] [Python 2.4] PyInt_FromLong returning NULL (original) (raw)

Tim Peters tim.peters at gmail.com
Tue Dec 7 18:58:12 CET 2004


[Andreas Jung]

While using Zope 2.7

Do you mean 2.7, or do you mean 2.7.3, or ...?

with Python 2.4 we discovered some strange behaviour of the security machinery. I could track this down to some Zope code in cAccessControl.c where an Unauthorized exception is raised because of a call to PyIntFromLong(1) which returns NULL. What could be the reason that such a "stupid" call return NULL in a reproducable way?

Any C function that returns a Python object can return NULL if malloc() says there's not enough memory to create a new object. PyInt_FromLong() actually allocates about 1KB at a time, and will return NULL if malloc() can't find that much.

OTOH, 1KB isn't big, and PyInt_FromLong(1) specifically should be returning a shared reference to a pre-existing PyIntObject (a number of small integer objects are constructed at Python initialization time, and PyInt_FromLong() returns references to them instead of allocating new memory).

So PyInt_FromLong(1) should have taken this path:

    v = small_ints[ival + NSMALLNEGINTS];

But if a wild store had stuffed NULL into 1's slot in the small_ints vector, the next line would have blown up with a NULL-pointer dereference before PyInt_FromLong() could have returned:

    Py_INCREF(v);
    return (PyObject *) v;

So, in all, it appears impossible for PyInt_FromLong(1) to return NULL.

If it's reproducible, run it under a debugger and step into the errant PyInt_FromLong(1) to see what's happening? Could be a compiler optimization bug (while rare, they have happened in Python).



More information about the Python-Dev mailing list