[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
Mon, 8 May 2000 14:58:19 -0700


On Mon, May 08, 2000 at 10:09:35AM -0400, Guido van Rossum wrote:
> > 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.
> 
> Did you look into unicodeobject.c?  It has similar methods with
> similar weaknesses!
> 

Here you go. I had a problem sending this (I apologize if you get this
twice).

Description:

Fix the unicode 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 unicode string methods to use the "O&" formatter with
the _PyEval_SliceIndex() function from ceval.c which is used to do the same
job for Python code slices (e.g. 'abcabcabc'[0:1000000000L]).

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:


diff -c3  /home/trentm/main/contrib/python/dist/src/Objects/unicodeobject.c ./Objects/unicodeobject.c
*** /home/trentm/main/contrib/python/dist/src/Objects/unicodeobject.c	Fri May  5 12:50:04 2000
--- ./Objects/unicodeobject.c	Mon May  8 13:47:56 2000
***************
*** 3023,3029 ****
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|ii:count", &substring, &start, &end))
          return NULL;
  
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
--- 3023,3030 ----
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:count", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
          return NULL;
  
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
***************
*** 3150,3156 ****
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|ii:find", &substring, &start, &end))
          return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
--- 3151,3158 ----
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:find", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
          return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
***************
*** 3212,3218 ****
      int start = 0;
      int end = INT_MAX;
  
!     if (!PyArg_ParseTuple(args, "O|ii:index", &substring, &start, &end))
          return NULL;
      
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
--- 3214,3221 ----
      int start = 0;
      int end = INT_MAX;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:index", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
          return NULL;
      
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
***************
*** 3642,3648 ****
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|ii:rfind", &substring, &start, &end))
          return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
--- 3645,3652 ----
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:rfind", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
          return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
***************
*** 3668,3674 ****
      int start = 0;
      int end = INT_MAX;
  
!     if (!PyArg_ParseTuple(args, "O|ii:rindex", &substring, &start, &end))
          return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
--- 3672,3679 ----
      int start = 0;
      int end = INT_MAX;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:rindex", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
          return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
***************
*** 3937,3943 ****
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|ii:startswith", &substring, &start, &end))
  	return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
--- 3942,3949 ----
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
  	return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
***************
*** 3967,3973 ****
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|ii:endswith", &substring, &start, &end))
  	return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);
--- 3973,3980 ----
      int end = INT_MAX;
      PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &substring,
! 		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
  	return NULL;
      substring = (PyUnicodeObject *)PyUnicode_FromObject(
  						(PyObject *)substring);

-- 
Trent Mick
trentm@activestate.com