socket module htonl/ntohl bug

Donn Cave donn at drizzle.com
Thu Jun 13 01:13:28 EDT 2002


Quoth davidma at eskimo.com (David Margrave):

| The following statement should work, but does not, on python 1.5.2 and
| python 2.2:
|
| >>> socket.htonl(pow(2L,32)-1)
| Traceback (innermost last):
|   File "<stdin>", line 1, in ?
| OverflowError: long int too long to convert
|
| 2^32-1 is a valid 32-bit value, equal to 32 1s in binary, and htonl
| should be able to handle it.  This is not related to the argument
| being a long int and htonl not accepting that type, because
| socket.htonl(4294967295) raises the same exception, and 4294967295 can
| be represented as a regular int in python2 (but not 1.5).

I think you may understand this, but 2^31-1 is not a valid 32-bit
signed integer, and that's what Python's int is (on platforms where
C int is 32 bits.)  Since there is no unsigned int, you would have
to represent the value as a negative number (v - pow(2L,32).)
Arguably the htonl function might convert to unsigned int, to match
the C variable, but it's going to return a signed int anyway, so
there's an element of consistency here.

On a DEC Alpha, incidentally, even though Python supports an int
of that size, I get
  >>> x = socket.htonl(y)
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  OverflowError: signed integer is greater than maximum

while I get "long int too long to convert" with pow(2L, 64) - 1.
So in this particular context it looks like there's more going on
here than just an accidental collision with integer overflow.

	Donn Cave, donn at drizzle.com



More information about the Python-list mailing list