[Patches] fix string methods implementing slice-like arguments (was:issues with int/long on 64bit platforms - eg stringobject (PR#306))

Trent Mick trentm@activestate.com
Wed, 3 May 2000 16:18:11 -0700


Decription:

Fix the string methods that implement slice-like semantics with
optional args (count, find, endswith, etc.) to properly handle
indeces outside [INT_MIN, INT_MAX]. Previously the "i" formatter
for PyArg_ParseTuple was used to get the indeces. These could overflow.

This patch changes the string methods to use the "O&" formatter with
the slice_index() function from ceval.c which is used to do the same
job for Python code slices (e.g. 'abcabcabc'[0:1000000000L]). slice_index()
is renamed _PyEval_SliceIndex() and is now exported. As well, the return
values for success/fail were changed to make slice_index directly
usable as required by the "O&" formatter.


Legal:

I confirm that, to the best of my knowledge and belief, this
contribution is free of any claims of third parties under
copyright, patent or other rights or interests ("claims").  To
the extent that I have any such claims, I hereby grant to CNRI a
nonexclusive, irrevocable, royalty-free, worldwide license to
reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part
of the Python software and its related documentation, or any
derivative versions thereof, at no cost to CNRI or its licensed
users, and to authorize others to do so.

I acknowledge that CNRI may, at its sole discretion, decide
whether or not to incorporate this contribution in the Python
software and its related documentation.  I further grant CNRI
permission to use my name and other identifying information
provided to CNRI by me for use in connection with the Python
software and its related documentation.


Patch:


--- main/Apps/Perlium/Python/dist/src/Include/ceval.h.~1~	Wed May  3 15:45:50 2000
+++ main/Apps/Perlium/Python/dist/src/Include/ceval.h	Wed May  3 15:45:50 2000
@@ -144,6 +144,9 @@
 
 #endif /* !WITH_THREAD */
 
+extern DL_IMPORT(int) _PyEval_SliceIndex Py_PROTO((PyObject *, int *));
+
+
 #ifdef __cplusplus
 }
 #endif
--- main/Apps/Perlium/Python/dist/src/Objects/stringobject.c.~1~	Wed May  3 15:45:50 2000
+++ main/Apps/Perlium/Python/dist/src/Objects/stringobject.c	Wed May  3 15:45:50 2000
@@ -825,8 +825,8 @@
 	int n, i = 0, last = INT_MAX;
 	PyObject *subobj;
 
-	if (!PyArg_ParseTuple(args, "O|ii:find/rfind/index/rindex", 
-			      &subobj, &i, &last))
+	if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", 
+		&subobj, _PyEval_SliceIndex, &i, _PyEval_SliceIndex, &last))
 		return -2;
 	if (PyString_Check(subobj)) {
 		sub = PyString_AS_STRING(subobj);
@@ -1197,8 +1197,10 @@
 	int m, r;
 	PyObject *subobj;
 
-	if (!PyArg_ParseTuple(args, "O|ii:count", &subobj, &i, &last))
+	if (!PyArg_ParseTuple(args, "O|O&O&:count", &subobj,
+		_PyEval_SliceIndex, &i, _PyEval_SliceIndex, &last))
 		return NULL;
+
 	if (PyString_Check(subobj)) {
 		sub = PyString_AS_STRING(subobj);
 		n = PyString_GET_SIZE(subobj);
@@ -1620,7 +1622,8 @@
 	int end = -1;
 	PyObject *subobj;
 
-	if (!PyArg_ParseTuple(args, "O|ii:startswith", &subobj, &start, &end))
+	if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
 		return NULL;
 	if (PyString_Check(subobj)) {
 		prefix = PyString_AS_STRING(subobj);
@@ -1674,7 +1677,8 @@
 	int lower, upper;
 	PyObject *subobj;
 
-	if (!PyArg_ParseTuple(args, "O|ii:endswith", &subobj, &start, &end))
+	if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
+		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
 		return NULL;
 	if (PyString_Check(subobj)) {
 		suffix = PyString_AS_STRING(subobj);
--- main/Apps/Perlium/Python/dist/src/Python/ceval.c.~1~	Wed May  3 15:45:50 2000
+++ main/Apps/Perlium/Python/dist/src/Python/ceval.c	Wed May  3 15:45:50 2000
@@ -80,7 +80,6 @@
 static PyObject *call_builtin Py_PROTO((PyObject *, PyObject *, PyObject *));
 static PyObject *call_function Py_PROTO((PyObject *, PyObject *, PyObject *));
 static PyObject *loop_subscript Py_PROTO((PyObject *, PyObject *));
-static int slice_index Py_PROTO((PyObject *, int *));
 static PyObject *apply_slice Py_PROTO((PyObject *, PyObject *, PyObject *));
 static int assign_slice Py_PROTO((PyObject *, PyObject *,
 				  PyObject *, PyObject *));
@@ -2585,8 +2584,12 @@
 	return NULL;
 }
 
-static int
-slice_index(v, pi)
+/* Extract a slice index from a PyInt or PyLong, the index is bound to
+   the range [-INT_MAX+1, INTMAX]. Returns 0 and an exception if there is
+   and error. Returns 1 on success.*/
+
+int
+_PyEval_SliceIndex(v, pi)
 	PyObject *v;
 	int *pi;
 {
@@ -2602,7 +2605,7 @@
 				if (!PyErr_ExceptionMatches( PyExc_OverflowError ) ) {
 					/* It's not an overflow error, so just 
 					   signal an error */
-					return -1;
+					return 0;
 				}
 
 				/* It's an overflow error, so we need to 
@@ -2612,7 +2615,7 @@
 
 				/* Create a long integer with a value of 0 */
 				long_zero = PyLong_FromLong( 0L );
-				if (long_zero == NULL) return -1;
+				if (long_zero == NULL) return 0;
 
 				/* Check sign */
 				if (PyObject_Compare(long_zero, v) < 0)
@@ -2628,7 +2631,7 @@
 		} else {
 			PyErr_SetString(PyExc_TypeError,
 					"slice index must be int");
-			return -1;
+			return 0;
 		}
 		/* Truncate -- very long indices are truncated anyway */
 		if (x > INT_MAX)
@@ -2637,7 +2640,7 @@
 			x = 0;
 		*pi = x;
 	}
-	return 0;
+	return 1;
 }
 
 static PyObject *
@@ -2645,9 +2648,9 @@
 	PyObject *u, *v, *w;
 {
 	int ilow = 0, ihigh = INT_MAX;
-	if (slice_index(v, &ilow) != 0)
+	if (!_PyEval_SliceIndex(v, &ilow))
 		return NULL;
-	if (slice_index(w, &ihigh) != 0)
+	if (!_PyEval_SliceIndex(w, &ihigh))
 		return NULL;
 	return PySequence_GetSlice(u, ilow, ihigh);
 }
@@ -2657,9 +2660,9 @@
 	PyObject *u, *v, *w, *x;
 {
 	int ilow = 0, ihigh = INT_MAX;
-	if (slice_index(v, &ilow) != 0)
+	if (!_PyEval_SliceIndex(v, &ilow))
 		return -1;
-	if (slice_index(w, &ihigh) != 0)
+	if (!_PyEval_SliceIndex(w, &ihigh))
 		return -1;
 	if (x == NULL)
 		return PySequence_DelSlice(u, ilow, ihigh);
End of Patch.