[Python-checkins] r76629 - in python/trunk: Objects/intobject.c Python/ceval.c

mark.dickinson python-checkins at python.org
Wed Dec 2 18:33:41 CET 2009


Author: mark.dickinson
Date: Wed Dec  2 18:33:41 2009
New Revision: 76629

Log:
Issue #7406:  Fix some occurrences of potential signed overflow in int
arithmetic.


Modified:
   python/trunk/Objects/intobject.c
   python/trunk/Python/ceval.c

Modified: python/trunk/Objects/intobject.c
==============================================================================
--- python/trunk/Objects/intobject.c	(original)
+++ python/trunk/Objects/intobject.c	Wed Dec  2 18:33:41 2009
@@ -461,7 +461,8 @@
 	register long a, b, x;
 	CONVERT_TO_LONG(v, a);
 	CONVERT_TO_LONG(w, b);
-	x = a + b;
+	/* casts in the line below avoid undefined behaviour on overflow */
+	x = (long)((unsigned long)a + b);
 	if ((x^a) >= 0 || (x^b) >= 0)
 		return PyInt_FromLong(x);
 	return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
@@ -473,7 +474,8 @@
 	register long a, b, x;
 	CONVERT_TO_LONG(v, a);
 	CONVERT_TO_LONG(w, b);
-	x = a - b;
+	/* casts in the line below avoid undefined behaviour on overflow */
+	x = (long)((unsigned long)a - b);
 	if ((x^a) >= 0 || (x^~b) >= 0)
 		return PyInt_FromLong(x);
 	return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v,
@@ -516,7 +518,8 @@
 
 	CONVERT_TO_LONG(v, a);
 	CONVERT_TO_LONG(w, b);
-	longprod = a * b;
+	/* casts in the next line avoid undefined behaviour on overflow */
+	longprod = (long)((unsigned long)a * b);
 	doubleprod = (double)a * (double)b;
 	doubled_longprod = (double)longprod;
 

Modified: python/trunk/Python/ceval.c
==============================================================================
--- python/trunk/Python/ceval.c	(original)
+++ python/trunk/Python/ceval.c	Wed Dec  2 18:33:41 2009
@@ -1321,7 +1321,9 @@
 				register long a, b, i;
 				a = PyInt_AS_LONG(v);
 				b = PyInt_AS_LONG(w);
-				i = a + b;
+				/* cast to avoid undefined behaviour
+				   on overflow */
+				i = (long)((unsigned long)a + b);
 				if ((i^a) < 0 && (i^b) < 0)
 					goto slow_add;
 				x = PyInt_FromLong(i);
@@ -1351,7 +1353,9 @@
 				register long a, b, i;
 				a = PyInt_AS_LONG(v);
 				b = PyInt_AS_LONG(w);
-				i = a - b;
+				/* cast to avoid undefined behaviour
+				   on overflow */
+				i = (long)((unsigned long)a - b);
 				if ((i^a) < 0 && (i^~b) < 0)
 					goto slow_sub;
 				x = PyInt_FromLong(i);


More information about the Python-checkins mailing list