[Python-Dev] [Python 2.4] PyInt_FromLong returning NULL

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
> PyInt_FromLong(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:

		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