Package: python2.5
Version: 2.5.1-2
Severity: important
Tags: patch

python2.5 is unable to serialize a floating point variable which equals
Infinity or NaN on ARM using marshal. As it is the function used when
byte-compiling python source files, this breaks a lot of packages. For
example python-xml:

  Setting up python2.5-minimal (2.5.1-1) ...
  Traceback (most recent call last):
    File "/usr/bin/py_compilefiles", line 116, in <module>
      exit_status = int(not main())
    File "/usr/bin/py_compilefiles", line 108, in main
      elif not compile_files(files, ddir, force, rx, quiet, ignore):
    File "/usr/bin/py_compilefiles", line 38, in compile_files
      ok = py_compile.compile(fullname, None, dfile, True)
    File "/usr/lib/python2.5/py_compile.py", line 138, in compile
      marshal.dump(codeobject, fc)
  ValueError: unmarshallable object
  pycentral: pycentral rtinstall: package python-xml: error byte-compiling 
files (214)
  pycentral rtinstall: package python-xml: error byte-compiling files (214)

The problem is that python2.5 wants to manage the floating points in
memory by itself, and assume that they are only little and big endian
IEEE formats. Otherwise it fallback to a generic code, which does not
handle NaN or Infinity.

The attached patched fixed that by adding mixed-endian IEEE format, as
it can be found on ARM old-ABI.

Please fix this bug as soon as possible, as it make a lot of python
packages uninstallable on ARM.

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: arm (armv5tejl)

Kernel: Linux 2.6.18-4-versatile
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) (ignored: LC_ALL 
set to fr_FR.UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages python2.5 depends on:
ii  libbz2-1.0                    1.0.3-7    high-quality block-sorting file co
ii  libc6                         2.6-2      GNU C Library: Shared libraries
ii  libdb4.4                      4.4.20-8   Berkeley v4.4 Database Libraries [
ii  libncursesw5                  5.6-3      Shared libraries for terminal hand
ii  libreadline5                  5.2-3      GNU readline and history libraries
ii  libsqlite3-0                  3.3.17-1   SQLite 3 shared library
ii  libssl0.9.8                   0.9.8e-5   SSL shared libraries
ii  mime-support                  3.39-1     MIME files 'mime.types' & 'mailcap
ii  python2.5-minimal             2.5.1-2    A minimal subset of the Python lan

python2.5 recommends no packages.

-- no debconf information
diff -u python2.5-2.5.1/debian/rules python2.5-2.5.1/debian/rules
--- python2.5-2.5.1/debian/rules
+++ python2.5-2.5.1/debian/rules
@@ -915,6 +915,7 @@
        hotshot-import \
        subprocess-eintr-safety \
        webbrowser \
+       arm-float \
 
 #      pydebug-path \
 
only in patch2:
unchanged:
--- python2.5-2.5.1.orig/debian/patches/arm-float.dpatch
+++ python2.5-2.5.1/debian/patches/arm-float.dpatch
@@ -0,0 +1,119 @@
+#! /bin/sh -e
+
+# DP: Support mixed-endian IEEE floating point, as found in the ARM old-ABI.
+
+dir=
+if [ $# -eq 3 -a "$2" = '-d' ]; then
+    pdir="-d $3"
+    dir="$3/"
+elif [ $# -ne 1 ]; then
+    echo >&2 "usage: `basename $0`: -patch|-unpatch [-d <srcdir>]"
+    exit 1
+fi
+case "$1" in
+    -patch)
+        patch $pdir -f --no-backup-if-mismatch -p0 < $0
+        ;;
+    -unpatch)
+        patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
+        ;;
+    *)
+       echo >&2 "usage: `basename $0`: -patch|-unpatch [-d <srcdir>]"
+        exit 1
+esac
+exit 0
+
+--- Objects/floatobject.c.orig 2006-05-25 10:53:30.000000000 -0500
++++ Objects/floatobject.c      2007-07-27 06:43:15.000000000 -0500
+@@ -982,7 +982,7 @@
+ /* this is for the benefit of the pack/unpack routines below */
+ 
+ typedef enum {
+-      unknown_format, ieee_big_endian_format, ieee_little_endian_format
++      unknown_format, ieee_big_endian_format, ieee_little_endian_format, 
ieee_mixed_endian_format
+ } float_format_type;
+ 
+ static float_format_type double_format, float_format;
+@@ -1021,6 +1021,8 @@
+               return PyString_FromString("IEEE, little-endian");
+       case ieee_big_endian_format:
+               return PyString_FromString("IEEE, big-endian");
++      case ieee_mixed_endian_format:
++              return PyString_FromString("IEEE, mixed-endian");
+       default:
+               Py_FatalError("insane float_format or double_format");
+               return NULL;
+@@ -1073,11 +1075,14 @@
+       else if (strcmp(format, "IEEE, big-endian") == 0) {
+               f = ieee_big_endian_format;
+       }
++      else if (strcmp(format, "IEEE, mixed-endian") == 0) {
++              f = ieee_mixed_endian_format;
++      }
+       else {
+               PyErr_SetString(PyExc_ValueError,
+                               "__setformat__() argument 2 must be "
+-                              "'unknown', 'IEEE, little-endian' or "
+-                              "'IEEE, big-endian'");
++                              "'unknown', 'IEEE, little-endian', "
++                              "'IEEE, big-endian' or 'IEEE, mixed-endian'");
+               return NULL;
+ 
+       }
+@@ -1230,6 +1235,8 @@
+                       detected_double_format = ieee_big_endian_format;
+               else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
+                       detected_double_format = ieee_little_endian_format;
++              else if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0)
++                      detected_double_format = ieee_mixed_endian_format;
+               else 
+                       detected_double_format = unknown_format;
+       }
+@@ -1565,8 +1572,19 @@
+                       p += 7;
+                       incr = -1;
+               }
++              else if (double_format == ieee_mixed_endian_format) {
++                      if (le)
++                              p += 4;
++                      else {
++                              p += 3;
++                              incr = -1;
++                      }
++              }
+               
+               for (i = 0; i < 8; i++) {
++                      if (double_format == ieee_mixed_endian_format && i == 4)
++                              p += -8 * incr;
++
+                       *p = *s++;
+                       p += incr;
+               }
+@@ -1739,6 +1757,27 @@
+                       }
+                       memcpy(&x, buf, 8);
+               }
++              else if (double_format == ieee_mixed_endian_format) {
++                      char buf[8];
++                      char *d;
++                      int i, incr = 1;
++
++                      if (le)
++                              d = &buf[4];
++                      else
++                              d = &buf[3];
++                      
++                      for (i = 0; i < 4; i++) {
++                              *d = *p++;
++                              d += incr;
++                      }
++                      d += -8 * incr;
++                      for (i = 0; i < 4; i++) {
++                              *d = *p++;
++                              d += incr;
++                      }
++                      memcpy(&x, buf, 8);
++              }
+               else {
+                       memcpy(&x, p, 8);
+               }

Reply via email to