[Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.41,2.42 floatobject.c,2.92,2.93 longobject.c,1.97,1.98

Tim Peters tim_one@users.sourceforge.net
Mon, 03 Sep 2001 22:14:22 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv28101/python/Objects

Modified Files:
	complexobject.c floatobject.c longobject.c 
Log Message:
Raise OverflowError when appropriate on long->float conversion.  Most of
the fiddling is simply due to that no caller of PyLong_AsDouble ever
checked for failure (so that's fixing old bugs).  PyLong_AsDouble is much
faster for big inputs now too, but that's more of a happy consequence
than a design goal.


Index: complexobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v
retrieving revision 2.41
retrieving revision 2.42
diff -C2 -d -r2.41 -r2.42
*** complexobject.c	2001/09/04 03:50:47	2.41
--- complexobject.c	2001/09/04 05:14:19	2.42
***************
*** 523,526 ****
--- 523,528 ----
  	else if (PyLong_Check(*pw)) {
  		cval.real = PyLong_AsDouble(*pw);
+ 		if (cval.real == -1.0 && PyErr_Occurred())
+ 			return -1;
  		*pw = PyComplex_FromCComplex(cval);
  		Py_INCREF(*pv);

Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.92
retrieving revision 2.93
diff -C2 -d -r2.92 -r2.93
*** floatobject.c	2001/09/04 03:50:25	2.92
--- floatobject.c	2001/09/04 05:14:19	2.93
***************
*** 272,287 ****
  
  static int
! convert_to_double(PyObject **v,
! 		  double *dbl)
  {
  	register PyObject *obj = *v;
! 	
  	if (PyInt_Check(obj)) {
  		*dbl = (double)PyInt_AS_LONG(obj);
  	}
  	else if (PyLong_Check(obj)) {
- 		PyFPE_START_PROTECT("convert_to_double", {*v=NULL;return -1;})
  		*dbl = PyLong_AsDouble(obj);
! 		PyFPE_END_PROTECT(*dbl)
  	}
  	else {
--- 272,288 ----
  
  static int
! convert_to_double(PyObject **v, double *dbl)
  {
  	register PyObject *obj = *v;
! 
  	if (PyInt_Check(obj)) {
  		*dbl = (double)PyInt_AS_LONG(obj);
  	}
  	else if (PyLong_Check(obj)) {
  		*dbl = PyLong_AsDouble(obj);
! 		if (*dbl == -1.0 && PyErr_Occurred()) {
! 			*v = NULL;
! 			return -1;
! 		}
  	}
  	else {

Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -C2 -d -r1.97 -r1.98
*** longobject.c	2001/09/04 02:50:49	1.97
--- longobject.c	2001/09/04 05:14:19	1.98
***************
*** 532,556 ****
  PyLong_AsDouble(PyObject *vv)
  {
! 	register PyLongObject *v;
  	double x;
! 	double multiplier = (double) (1L << SHIFT);
! 	int i, sign;
! 	
  	if (vv == NULL || !PyLong_Check(vv)) {
  		PyErr_BadInternalCall();
  		return -1;
  	}
! 	v = (PyLongObject *)vv;
! 	i = v->ob_size;
! 	sign = 1;
! 	x = 0.0;
! 	if (i < 0) {
! 		sign = -1;
! 		i = -(i);
! 	}
! 	while (--i >= 0) {
! 		x = x*multiplier + (double)v->ob_digit[i];
! 	}
! 	return x * sign;
  }
  
--- 532,557 ----
  PyLong_AsDouble(PyObject *vv)
  {
! 	int e;
  	double x;
! 
  	if (vv == NULL || !PyLong_Check(vv)) {
  		PyErr_BadInternalCall();
  		return -1;
  	}
! 	x = _PyLong_AsScaledDouble(vv, &e);
! 	if (x == -1.0 && PyErr_Occurred())
! 		return -1.0;
! 	if (e > INT_MAX / SHIFT)
! 		goto overflow;
! 	errno = 0;
! 	x = ldexp(x, e * SHIFT);
! 	if (errno == ERANGE)
! 		goto overflow;
! 	return x;
! 
! overflow:
! 	PyErr_SetString(PyExc_OverflowError,
! 		"long int too large to convert to float");
! 	return -1.0;
  }
  
***************
*** 2099,2105 ****
  {
  	double result;
- 	PyFPE_START_PROTECT("long_float", return 0)
  	result = PyLong_AsDouble(v);
! 	PyFPE_END_PROTECT(result)
  	return PyFloat_FromDouble(result);
  }
--- 2100,2106 ----
  {
  	double result;
  	result = PyLong_AsDouble(v);
! 	if (result == -1.0 && PyErr_Occurred())
! 		return NULL;
  	return PyFloat_FromDouble(result);
  }