From f70590f990e6b91c36c3aadd7da6fa6c0a9a5beb Mon Sep 17 00:00:00 2001
From: Guido van Rossum <guido@python.org>
Date: Fri, 7 Dec 2001 20:00:04 +0000
Subject: _PyTuple_Resize(): this dumped core on tuple(globals()) for me. 
 Turns out the for loop at the end intended to zero out new items wasn't doing
 anything, because sv->ob_size was already equal to newsize.  The fix slightly
 refactors the function, introducing a variable oldsize and doing away with
 sizediff (which was used only once), and using oldsize and newsize
 consistently.  I also added comments explaining what the two for loops do. 
 (Looking at the CVS annotation of this function, it's no miracle a bug crept
 in -- this has been patched by many different folks! :-)

---
 Objects/tupleobject.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 0b5507f..27598ed 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -598,7 +598,7 @@ _PyTuple_Resize(PyObject **pv, int newsize)
 	register PyTupleObject *v;
 	register PyTupleObject *sv;
 	int i;
-	int sizediff;
+	int oldsize;
 
 	v = (PyTupleObject *) *pv;
 	if (v == NULL || v->ob_type != &PyTuple_Type ||
@@ -608,11 +608,11 @@ _PyTuple_Resize(PyObject **pv, int newsize)
 		PyErr_BadInternalCall();
 		return -1;
 	}
-	sizediff = newsize - v->ob_size;
-	if (sizediff == 0)
+	oldsize = v->ob_size;
+	if (oldsize == newsize)
 		return 0;
 
-	if (v->ob_size == 0) {
+	if (oldsize == 0) {
 		/* Empty tuples are often shared, so we should never 
 		   resize them in-place even if we do own the only
 		   (current) reference */
@@ -627,7 +627,8 @@ _PyTuple_Resize(PyObject **pv, int newsize)
 #endif
 	_PyObject_GC_UNTRACK(v);
 	_Py_ForgetReference((PyObject *) v);
-	for (i = newsize; i < v->ob_size; i++) {
+	/* DECREF items deleted by shrinkage */
+	for (i = newsize; i < oldsize; i++) {
 		Py_XDECREF(v->ob_item[i]);
 		v->ob_item[i] = NULL;
 	}
@@ -638,7 +639,8 @@ _PyTuple_Resize(PyObject **pv, int newsize)
 		return -1;
 	}
 	_Py_NewReference((PyObject *) sv);
-	for (i = sv->ob_size; i < newsize; i++)
+	/* Zero out items added by growing */
+	for (i = oldsize; i < newsize; i++)
 		sv->ob_item[i] = NULL;
 	*pv = (PyObject *) sv;
 	_PyObject_GC_TRACK(sv);
-- 
cgit v0.12

