[Patches] [ python-Patches-1038854 ] Fix struct.pack on 64-bit
archs (broken on 2.*)
SourceForge.net
noreply at sourceforge.net
Thu Nov 11 23:20:46 CET 2004
Patches item #1038854, was opened at 2004-10-02 07:07
Message generated for change (Comment added) made by sgatwasetde
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1038854&group_id=5470
Category: Modules
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Stefan Grundmann (sgatwasetde)
Assigned to: Nobody/Anonymous (nobody)
Summary: Fix struct.pack on 64-bit archs (broken on 2.*)
Initial Comment:
Description:
The code in the struct module assumes that sizeof(long)
== sizeof(int)
which is wrong on (most) 64-bit architectures (linux on
amd64 with a 32-bit userland is an exception).
How To Repeat:
on a 32-bit platform struct.pack behaves as expected:
$ uname -m -r -s
FreeBSD 4.10-STABLE i386
$ python -c "import struct; print repr(struct.pack('I',
4294967296))"
Traceback (most recent call last):
File "<string>", line 1, in ?
OverflowError: long int too large to convert
on a 64-bit platform it treats integers as longs
(it does not check for over/underflows and returns the
lower 4 byte):
$ uname -m -r -s
FreeBSD 5.2-CURRENT sparc64
$ python -c "import struct; print repr(struct.pack('I',
4294967296))"
'\x00\x00\x00\x00'
Fix:
in python/python/dist/src/Modules/structmodule.c:
np_uint() and np_int() have to check for
over/underflows using MAX_UINT, MAX_INT, MIN_INT as
np_ushort() and np_short() already do for MAX_USHORT, ...
the attached patch does this
(diff was generated using diff -rNu and Revision 2.62
of python/python/dist/src/Modules/structmodule.c)
----------------------------------------------------------------------
>Comment By: Stefan Grundmann (sgatwasetde)
Date: 2004-11-11 23:20
Message:
Logged In: YES
user_id=1131807
Issuing a warning instead of an error might be a good idea
(to give the user-base some time adapt).
But then we still have to deal with the fact that the some
python modules are broken on 64 bit (at least big-endian).
The gzip module for example does not work correctly even
with the old code (because of stuctmodule).
And there is user code out there that relies on correct
overflow detection (which was the reason i submitted the
patch).
Another way would be to omit the overflow detection
completely and heave the user take care of it. This will break
a lot of applications but is imho more consistent then the old
behavior (check some cases on some architectures).
Personally i would like to have a structmodule in python 2.4
that works a one would expect (overflow detection) but that
is not my decision to make. The fact that code which is
under control of the python project uses struct.pack (...) in
erroneous ways should be fixed (even if it does work on 32
bit archs atm).
----------------------------------------------------------------------
Comment By: Armin Rigo (arigo)
Date: 2004-11-10 22:31
Message:
Logged In: YES
user_id=4771
This indicate that similar breakage will probably occur in user code if we add range checking. Do we want to take the risk? It looks overkill, but what about issuing a warning and turning it into an error in the next version?
----------------------------------------------------------------------
Comment By: Stefan Grundmann (sgatwasetde)
Date: 2004-11-10 09:36
Message:
Logged In: YES
user_id=1131807
The patch breaks test_binhex on 32 and 64 bit architectures
because Lib/binhex.py is using struct.pack('>h' ...) to pack
an unsigned short (which is wrong but does work with the
current version of Modules/structmodule.c because of the
lack of range checking).
The patch breaks test_gzip (and test_tarfile) on 64 bit
architectures because Lib/gzip.py is using write32 (which
uses to pack('<l',...) ) to write an unsigned 32 bit checksum.
This should be fixed in Lib/gzip.py and Lib/binhex.py.
----------------------------------------------------------------------
Comment By: Neal Norwitz (nnorwitz)
Date: 2004-11-08 04:15
Message:
Logged In: YES
user_id=33168
This patch breaks 3 tests: test_binhex test_gzip test_tarfile.
tarfile breaks because of gzip.
Run on opterons. Can you update the patch so these tests pass?
----------------------------------------------------------------------
Comment By: Stefan Grundmann (sgatwasetde)
Date: 2004-10-08 08:07
Message:
Logged In: YES
user_id=1131807
The attached patch will fix the range-checking-code of the
integer pack functions for 64 and 32 bit architectures
(tested on i386 and Sparc64, 64-bit little-endian was not
tested 'cause of lack of hardware). All test cases worked as
expected, there is no more need for BUGGY_RANGE_CHECK.
I'm a bit unsure about the used method to get an unsigned
long from a Python_Long object with overflow checking...
PyLong_AsUnsignedLong(PyLong_FromLong(PyInt_AS_LONG(v)))
looks a rather excessive.
----------------------------------------------------------------------
Comment By: Stefan Grundmann (sgatwasetde)
Date: 2004-10-06 08:31
Message:
Logged In: YES
user_id=1131807
I removed the attached patch since it only handles overflows
for np_int/np_uint. bp_int/bp_uint and lp_int/lp_unit have
different issues (no overflow checking at all, unneccessary
loops - that will not be optimized by
the compiler). I'm working on a new patch that fixes these
problems
(and the rest of BUGGY_RANGE_CHECK ;) ).
----------------------------------------------------------------------
Comment By: Armin Rigo (arigo)
Date: 2004-10-05 15:31
Message:
Logged In: YES
user_id=4771
At a first glance, it appears that there is the same problem
in bp_int/bp_uint and lp_int/lp_unit. Can you check that
pack('<I',...) and pack('>I',...) fail to detect the
overflow in the same way? If so, can you also provide the
patch for these 4 other routines? Finally, it would be nice
to add a test case in Lib/test/test_struct.py.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1038854&group_id=5470
More information about the Patches
mailing list