[Python-checkins] python/dist/src/Python bltinmodule.c,2.272,2.273

doerwalter@users.sourceforge.net doerwalter@users.sourceforge.net
Tue, 04 Feb 2003 08:28:02 -0800


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

Modified Files:
	bltinmodule.c 
Log Message:
filterstring() and filterunicode() in Python/bltinmodule.c
blindly assumed that tp_as_sequence->sq_item always returns
a str or unicode object. This might fail with str or unicode
subclasses.

This patch checks whether the object returned from __getitem__
is a str/unicode object and raises a TypeError if not (and
the filter function returned true).

Furthermore the result for __getitem__ can be more than one
character long, so checks for enough memory have to be done.


Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.272
retrieving revision 2.273
diff -C2 -d -r2.272 -r2.273
*** bltinmodule.c	3 Feb 2003 20:23:33 -0000	2.272
--- bltinmodule.c	4 Feb 2003 16:28:00 -0000	2.273
***************
*** 1893,1896 ****
--- 1893,1897 ----
  	register int i, j;
  	int len = PyString_Size(strobj);
+ 	int outlen = len;
  
  	if (func == Py_None) {
***************
*** 1922,1932 ****
  		ok = PyObject_IsTrue(good);
  		Py_DECREF(good);
! 		if (ok)
! 			PyString_AS_STRING((PyStringObject *)result)[j++] =
! 				PyString_AS_STRING((PyStringObject *)item)[0];
  		Py_DECREF(item);
  	}
  
! 	if (j < len)
  		_PyString_Resize(&result, j);
  
--- 1923,1963 ----
  		ok = PyObject_IsTrue(good);
  		Py_DECREF(good);
! 		if (ok) {
! 			int reslen;
! 			if (!PyString_Check(item)) {
! 				PyErr_SetString(PyExc_TypeError, "can't filter str to str:"
! 					" __getitem__ returned different type");
! 				Py_DECREF(item);
! 				goto Fail_1;
! 			}
! 			reslen = PyString_GET_SIZE(item);
! 			if (reslen == 1) {
! 				PyString_AS_STRING(result)[j++] =
! 					PyString_AS_STRING(item)[0];
! 			} else {
! 				/* do we need more space? */
! 				int need = j + reslen + len-i-1;
! 				if (need > outlen) {
! 					/* overallocate, to avoid reallocations */
! 					if (need<2*outlen)
! 						need = 2*outlen;
! 					if (_PyString_Resize(&result, need)) {
! 						Py_DECREF(item);
! 						return NULL;
! 					}
! 					outlen = need;
! 				}
! 				memcpy(
! 					PyString_AS_STRING(result) + j,
! 					PyString_AS_STRING(item),
! 					reslen
! 				);
! 				j += reslen;
! 			}
! 		}
  		Py_DECREF(item);
  	}
  
! 	if (j < outlen)
  		_PyString_Resize(&result, j);
  
***************
*** 1947,1950 ****
--- 1978,1982 ----
  	register int i, j;
  	int len = PyUnicode_GetSize(strobj);
+ 	int outlen = len;
  
  	if (func == Py_None) {
***************
*** 1976,1986 ****
  		ok = PyObject_IsTrue(good);
  		Py_DECREF(good);
! 		if (ok)
! 			PyUnicode_AS_UNICODE((PyStringObject *)result)[j++] =
! 				PyUnicode_AS_UNICODE((PyStringObject *)item)[0];
  		Py_DECREF(item);
  	}
  
! 	if (j < len)
  		PyUnicode_Resize(&result, j);
  
--- 2008,2048 ----
  		ok = PyObject_IsTrue(good);
  		Py_DECREF(good);
! 		if (ok) {
! 			int reslen;
! 			if (!PyUnicode_Check(item)) {
! 				PyErr_SetString(PyExc_TypeError, "can't filter unicode to unicode:"
! 					" __getitem__ returned different type");
! 				Py_DECREF(item);
! 				goto Fail_1;
! 			}
! 			reslen = PyUnicode_GET_SIZE(item);
! 			if (reslen == 1) {
! 				PyUnicode_AS_UNICODE(result)[j++] =
! 					PyUnicode_AS_UNICODE(item)[0];
! 			} else {
! 				/* do we need more space? */
! 				int need = j + reslen + len-i-1;
! 				if (need > outlen) {
! 					/* overallocate, to avoid reallocations */
! 					if (need<2*outlen)
! 						need = 2*outlen;
! 					if (PyUnicode_Resize(&result, need)) {
! 						Py_DECREF(item);
! 						return NULL;
! 					}
! 					outlen = need;
! 				}
! 				memcpy(
! 					PyUnicode_AS_UNICODE(result) + j,
! 					PyUnicode_AS_UNICODE(item),
! 					reslen*sizeof(Py_UNICODE)
! 				);
! 				j += reslen;
! 			}
! 		}
  		Py_DECREF(item);
  	}
  
! 	if (j < outlen)
  		PyUnicode_Resize(&result, j);