All three failures give the error message

OverflowError: Python int too large to convert to C long

from

File "sage/rings/polynomial/polynomial_integer_dense_flint.pyx", line 284, in 
sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint.__init__
 (build/cythonized/sage/rings/polynomial/polynomial_integer_dense_flint.cpp:6548)
         fmpz_poly_set_coeff_si(self.__poly, i, a)

Help on finding a fix would be appreciated.
On line 282 of that file (assuming the version at 
https://github.com/sagemath/sage/blob/master/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx
 is the same as the one in the Debian package).

"if type(a) is int:"

If that conditional is true then the code takes a fast path, which assumes that the value 
of "a" fits in a C long.

In python 2 "int" was a type limited to the size of a c long, so the check was 
appropriate. However in python 3 "int" is an arbitrary precision type, so we need to 
check if it will fit in the range of a C long.

There are several other conditionals on types being "int" in the file that presumably 
need fixing in the same way. I also spotted a "isinstance(x0, long):" which i'm pretty 
sure will fail in python 3 as there is no type long in python 3.

I have attached a completely untested patch.

Description: fix python integer type checks in polynomial_integer_dense_flint.pyx
 python 3 changes the standard integer types, in python2 a python "int" was
 equivilent to a C "long" and a python "long" was an arbitary precision type.
 
 In python 3 a python "int" is now an arbitary precision type and a python
 "long" does not exist any more.
 
 This patch adds additional checks that a python int will fit in the range of
 a C long before passing it to routines that require it to fit in one. It also
 locally defines long=int on python 3 so that isinstance(x0,long) will correctly
 test for an arbitary precision python integer.
Author: Peter Michael Green <plugw...@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2019-11-28

--- sagemath-8.9.orig/sage/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx
+++ sagemath-8.9/sage/src/sage/rings/polynomial/polynomial_integer_dense_flint.pyx
@@ -36,12 +36,21 @@ from __future__ import absolute_import,
 from cysignals.memory cimport sig_free
 from cysignals.signals cimport sig_on, sig_off
 
+from libc.limits cimport LONG_MIN
+from libc.limits cimport LONG_MAX
+
 include "sage/libs/ntl/decl.pxi"
 
 from cpython.int cimport PyInt_AS_LONG
 from sage.libs.gmp.mpz cimport *
 from sage.arith.long cimport pyobject_to_long
 
+import sys
+#we use this later in an isinstance test to detect a python arbitary precision
+#integer
+if sys.version_info.major > 3:
+    long = int
+
 from sage.rings.polynomial.polynomial_element cimport Polynomial
 from sage.structure.element cimport ModuleElement, Element
 from sage.structure.element import coerce_binop
@@ -241,7 +250,7 @@ cdef class Polynomial_integer_dense_flin
             # now fill them in
             for ii, a in x:
                 i = ii[0] if type(ii) is tuple else ii
-                if type(a) is int:
+                if (type(a) is int) and (LONG_MIN <= a <= LONG_MAX):
                     sig_on()
                     fmpz_poly_set_coeff_si(self.__poly, i, a)
                     sig_off()
@@ -279,7 +288,7 @@ cdef class Polynomial_integer_dense_flin
         sig_off()
         for i from 0 <= i < len(x):
             a = x[i]
-            if type(a) is int:
+            if (type(a) is int) && (LONG_MIN <= a <= LONG_MAX):
                 sig_on()
                 fmpz_poly_set_coeff_si(self.__poly, i, a)
                 sig_off()
@@ -398,7 +407,7 @@ cdef class Polynomial_integer_dense_flin
                     (<Polynomial_integer_dense_flint> x0).__poly)
                 sig_off()
                 return f
-            if isinstance(x0, int):
+            if isinstance(x0, int) and (LONG_MIN <= x0 <= LONG_MAX):
                 z = Integer.__new__(Integer)
                 sig_on()
                 fmpz_init(a_fmpz)
@@ -1287,7 +1296,7 @@ cdef class Polynomial_integer_dense_flin
         """
         if n < 0:
             raise IndexError("n must be >= 0")
-        if isinstance(value, int):
+        if isinstance(value, int) and (LONG_MIN <= value <= LONG_MAX):
             sig_on()
             fmpz_poly_set_coeff_si(self.__poly, n, value)
             sig_off()

Reply via email to