[Python-checkins] python/dist/src/Python bltinmodule.c,2.285,2.286

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Sun, 13 Apr 2003 15:13:11 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv27848/Python

Modified Files:
	bltinmodule.c 
Log Message:
handle_range_longs():  refcount handling is very delicate here, and
the code erroneously decrefed the istep argument in an error case.  This
caused a co_consts tuple to lose a float constant prematurely, which
eventually caused gc to try executing static data in floatobject.c (don't
ask <wink>).  So reworked this extensively to ensure refcount correctness.


Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.285
retrieving revision 2.286
diff -C2 -d -r2.285 -r2.286
*** bltinmodule.c	11 Apr 2003 18:43:06 -0000	2.285
--- bltinmodule.c	13 Apr 2003 22:13:08 -0000	2.286
***************
*** 1320,1326 ****
  {
  	PyObject *ilow;
! 	PyObject *ihigh;
! 	PyObject *zero = NULL;
  	PyObject *istep = NULL;
  	PyObject *curnum = NULL;
  	PyObject *v = NULL;
--- 1320,1326 ----
  {
  	PyObject *ilow;
! 	PyObject *ihigh = NULL;
  	PyObject *istep = NULL;
+ 
  	PyObject *curnum = NULL;
  	PyObject *v = NULL;
***************
*** 1329,1360 ****
  	int cmp_result;
  
! 	zero = PyLong_FromLong(0L);
  	if (zero == NULL)
  		return NULL;
  
! 	ilow = zero; /* Default lower bound */
! 	if (!PyArg_ParseTuple(args, "O", &ihigh, &istep)) {
! 		PyErr_Clear();
! 		if (!PyArg_ParseTuple(args,
! 			      "OO|O;range() requires 1-3 int arguments",
! 			      &ilow, &ihigh, &istep))
! 		goto Fail;
! 	}
! 
! 	if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"integer start argument expected, got float.");
! 		goto Fail;
  		return NULL;
  	}
  
! 	if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"integer end argument expected, got float.");
! 		goto Fail;
! 		return NULL;
  	}
  
! 	/* If no istep was supplied, default to 1. */
  	if (istep == NULL) {
  		istep = PyLong_FromLong(1L);
--- 1329,1361 ----
  	int cmp_result;
  
! 	PyObject *zero = PyLong_FromLong(0);
! 
  	if (zero == NULL)
  		return NULL;
  
! 	if (!PyArg_UnpackTuple(args, "range", 1, 3, &ilow, &ihigh, &istep)) {
! 		Py_DECREF(zero);
  		return NULL;
  	}
  
! 	/* Figure out which way we were called, supply defaults, and be
! 	 * sure to incref everything so that the decrefs at the end
! 	 * are correct.
! 	 */
! 	assert(ilow != NULL);
! 	if (ihigh == NULL) {
! 		/* only 1 arg -- it's the upper limit */
! 		ihigh = ilow;
! 		ilow = NULL;
  	}
+ 	assert(ihigh != NULL);
+ 	Py_INCREF(ihigh);
  
! 	/* ihigh correct now; do ilow */
! 	if (ilow == NULL)
! 		ilow = zero;
! 	Py_INCREF(ilow);
! 
! 	/* ilow and ihigh correct now; do istep */
  	if (istep == NULL) {
  		istep = PyLong_FromLong(1L);
***************
*** 1363,1378 ****
  	}
  	else {
- 		if (!PyInt_Check(istep) && !PyLong_Check(istep)) {
- 			PyErr_SetString(PyExc_ValueError,
- 				"integer step argument expected, got float.");
- 			goto Fail;
- 		}
  		Py_INCREF(istep);
  	}
  
! 	if (PyObject_Cmp(istep, zero, &cmp_result) == -1) {
  		goto Fail;
  	}
  
  	if (cmp_result == 0) {
  		PyErr_SetString(PyExc_ValueError,
--- 1364,1393 ----
  	}
  	else {
  		Py_INCREF(istep);
  	}
  
! 	/* XXX What reason do we have to believe that if an arg isn't an
! 	 * XXX int, it must be a float?
! 	 */
! 	if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"integer start argument expected, got float.");
! 		goto Fail;
! 	}
! 
! 	if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"integer end argument expected, got float.");
! 		goto Fail;
! 	}
! 
! 	if (!PyInt_Check(istep) && !PyLong_Check(istep)) {
! 		PyErr_SetString(PyExc_ValueError,
! 			"integer step argument expected, got float.");
  		goto Fail;
  	}
  
+ 	if (PyObject_Cmp(istep, zero, &cmp_result) == -1)
+ 		goto Fail;
  	if (cmp_result == 0) {
  		PyErr_SetString(PyExc_ValueError,
***************
*** 1420,1432 ****
  		curnum = tmp_num;
  	}
! 	Py_DECREF(curnum);
  	Py_DECREF(istep);
  	Py_DECREF(zero);
  	return v;
  
    Fail:
! 	Py_XDECREF(curnum);
  	Py_XDECREF(istep);
! 	Py_XDECREF(zero);
  	Py_XDECREF(v);
  	return NULL;
--- 1435,1451 ----
  		curnum = tmp_num;
  	}
! 	Py_DECREF(ilow);
! 	Py_DECREF(ihigh);
  	Py_DECREF(istep);
  	Py_DECREF(zero);
+ 	Py_DECREF(curnum);
  	return v;
  
    Fail:
! 	Py_DECREF(ilow);
! 	Py_DECREF(ihigh);
  	Py_XDECREF(istep);
! 	Py_DECREF(zero);
! 	Py_XDECREF(curnum);
  	Py_XDECREF(v);
  	return NULL;