[Python-checkins] python/dist/src/Python getargs.c,2.99,2.100

loewis@users.sourceforge.net loewis@users.sourceforge.net
Sat, 03 May 2003 03:00:27 -0700


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

Modified Files:
	getargs.c 
Log Message:
Patch #684981: Add cleanup capability for argument parsers. Fixes 501716.


Index: getargs.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v
retrieving revision 2.99
retrieving revision 2.100
diff -C2 -d -r2.99 -r2.100
*** getargs.c	18 Apr 2003 00:12:30 -0000	2.99
--- getargs.c	3 May 2003 10:00:22 -0000	2.100
***************
*** 18,25 ****
  static void seterror(int, char *, int *, char *, char *);
  static char *convertitem(PyObject *, char **, va_list *, int *, char *, 
! 			 size_t);
  static char *converttuple(PyObject *, char **, va_list *,
! 			  int *, char *, size_t, int);
! static char *convertsimple(PyObject *, char **, va_list *, char *, size_t);
  static int convertbuffer(PyObject *, void **p, char **);
  
--- 18,26 ----
  static void seterror(int, char *, int *, char *, char *);
  static char *convertitem(PyObject *, char **, va_list *, int *, char *, 
! 			 size_t, PyObject **);
  static char *converttuple(PyObject *, char **, va_list *,
! 			  int *, char *, size_t, int, PyObject **);
! static char *convertsimple(PyObject *, char **, va_list *, char *,
! 			   size_t, PyObject **);
  static int convertbuffer(PyObject *, void **p, char **);
  
***************
*** 73,76 ****
--- 74,120 ----
  
  
+ /* Handle cleanup of allocated memory in case of exception */
+ 
+ static int
+ addcleanup(void *ptr, PyObject **freelist)
+ {
+ 	PyObject *cobj;
+ 	if (!*freelist) {
+ 		*freelist = PyList_New(0);
+ 		if (!*freelist) {
+ 			PyMem_FREE(ptr);
+ 			return -1;
+ 		}
+ 	}
+ 	cobj = PyCObject_FromVoidPtr(ptr, NULL);
+ 	if (!cobj) {
+ 		PyMem_FREE(ptr);
+ 		return -1;
+ 	}
+ 	if(PyList_Append(*freelist, cobj)) {
+                 PyMem_FREE(ptr);
+ 		Py_DECREF(cobj);
+ 		return -1;
+ 	}
+         Py_DECREF(cobj);
+ 	return 0;
+ }
+ 
+ static int
+ cleanreturn(int retval, PyObject *freelist)
+ {
+ 	if(freelist) {
+ 		if((retval) == 0) {
+ 			int len = PyList_GET_SIZE(freelist), i;
+ 			for (i = 0; i < len; i++)
+                                 PyMem_FREE(PyCObject_AsVoidPtr(
+                                 		PyList_GET_ITEM(freelist, i)));
+ 		}
+ 		Py_DECREF(freelist);
+ 	}
+ 	return retval;
+ }
+ 
+ 
  static int
  vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
***************
*** 87,90 ****
--- 131,135 ----
  	int i, len;
  	char *msg;
+ 	PyObject *freelist = NULL;
  	
  	assert(compat || (args != (PyObject*)NULL));
***************
*** 158,166 ****
  			}
  			msg = convertitem(args, &format, p_va, levels, msgbuf,
! 					  sizeof(msgbuf));
  			if (msg == NULL)
! 				return 1;
  			seterror(levels[0], msg, levels+1, fname, message);
! 			return 0;
  		}
  		else {
--- 203,211 ----
  			}
  			msg = convertitem(args, &format, p_va, levels, msgbuf,
! 					  sizeof(msgbuf), &freelist);
  			if (msg == NULL)
! 				return cleanreturn(1, freelist);
  			seterror(levels[0], msg, levels+1, fname, message);
! 			return cleanreturn(0, freelist);
  		}
  		else {
***************
*** 201,208 ****
  			format++;
  		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
! 				  levels, msgbuf, sizeof(msgbuf));
  		if (msg) {
  			seterror(i+1, msg, levels, fname, message);
! 			return 0;
  		}
  	}
--- 246,253 ----
  			format++;
  		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
! 				  levels, msgbuf, sizeof(msgbuf), &freelist);
  		if (msg) {
  			seterror(i+1, msg, levels, fname, message);
! 			return cleanreturn(0, freelist);
  		}
  	}
***************
*** 213,220 ****
  		PyErr_Format(PyExc_SystemError,
  			     "bad format string: %.200s", formatsave);
! 		return 0;
  	}
  	
! 	return 1;
  }
  
--- 258,265 ----
  		PyErr_Format(PyExc_SystemError,
  			     "bad format string: %.200s", formatsave);
! 		return cleanreturn(0, freelist);
  	}
  	
! 	return cleanreturn(1, freelist);
  }
  
***************
*** 278,282 ****
  static char *
  converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels,
! 	     char *msgbuf, size_t bufsize, int toplevel)
  {
  	int level = 0;
--- 323,327 ----
  static char *
  converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels,
! 	     char *msgbuf, size_t bufsize, int toplevel, PyObject **freelist)
  {
  	int level = 0;
***************
*** 328,332 ****
  		item = PySequence_GetItem(arg, i);
  		msg = convertitem(item, &format, p_va, levels+1, msgbuf,
! 				  bufsize);
  		/* PySequence_GetItem calls tp->sq_item, which INCREFs */
  		Py_XDECREF(item);
--- 373,377 ----
  		item = PySequence_GetItem(arg, i);
  		msg = convertitem(item, &format, p_va, levels+1, msgbuf,
! 				  bufsize, freelist);
  		/* PySequence_GetItem calls tp->sq_item, which INCREFs */
  		Py_XDECREF(item);
***************
*** 346,350 ****
  static char *
  convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels,
! 	    char *msgbuf, size_t bufsize)
  {
  	char *msg;
--- 391,395 ----
  static char *
  convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels,
! 	    char *msgbuf, size_t bufsize, PyObject **freelist)
  {
  	char *msg;
***************
*** 354,363 ****
  		format++;
  		msg = converttuple(arg, &format, p_va, levels, msgbuf, 
! 				   bufsize, 0);
  		if (msg == NULL)
  			format++;
  	}
  	else {
! 		msg = convertsimple(arg, &format, p_va, msgbuf, bufsize);
  		if (msg != NULL)
  			levels[0] = 0;
--- 399,409 ----
  		format++;
  		msg = converttuple(arg, &format, p_va, levels, msgbuf, 
! 				   bufsize, 0, freelist);
  		if (msg == NULL)
  			format++;
  	}
  	else {
! 		msg = convertsimple(arg, &format, p_va, msgbuf, bufsize,
! 				    freelist);
  		if (msg != NULL)
  			levels[0] = 0;
***************
*** 410,414 ****
  static char *
  convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
! 	      size_t bufsize)
  {
  	char *format = *p_format;
--- 456,460 ----
  static char *
  convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
! 	      size_t bufsize, PyObject **freelist)
  {
  	char *format = *p_format;
***************
*** 837,844 ****
  
  			format++;
! 			if (buffer_len == NULL)
  				return converterr(
  					"(buffer_len is NULL)",
  					arg, msgbuf, bufsize);
  			if (*buffer == NULL) {
  				*buffer = PyMem_NEW(char, size + 1);
--- 883,892 ----
  
  			format++;
! 			if (buffer_len == NULL) {
! 				Py_DECREF(s);
  				return converterr(
  					"(buffer_len is NULL)",
  					arg, msgbuf, bufsize);
+ 			}
  			if (*buffer == NULL) {
  				*buffer = PyMem_NEW(char, size + 1);
***************
*** 849,852 ****
--- 897,906 ----
  						arg, msgbuf, bufsize);
  				}
+ 				if(addcleanup(*buffer, freelist)) {
+ 					Py_DECREF(s);
+ 					return converterr(
+ 						"(cleanup problem)",
+ 						arg, msgbuf, bufsize);
+ 				}
  			} else {
  				if (size + 1 > *buffer_len) {
***************
*** 875,882 ****
  
  			*/
! 			if ((int)strlen(PyString_AS_STRING(s)) != size)
  				return converterr(
  					"(encoded string without NULL bytes)",
  					arg, msgbuf, bufsize);
  			*buffer = PyMem_NEW(char, size + 1);
  			if (*buffer == NULL) {
--- 929,938 ----
  
  			*/
! 			if ((int)strlen(PyString_AS_STRING(s)) != size) {
! 				Py_DECREF(s);
  				return converterr(
  					"(encoded string without NULL bytes)",
  					arg, msgbuf, bufsize);
+ 			}
  			*buffer = PyMem_NEW(char, size + 1);
  			if (*buffer == NULL) {
***************
*** 885,888 ****
--- 941,949 ----
  						  arg, msgbuf, bufsize);
  			}
+ 			if(addcleanup(*buffer, freelist)) {
+ 				Py_DECREF(s);
+ 				return converterr("(cleanup problem)",
+ 						arg, msgbuf, bufsize);
+ 			}
  			memcpy(*buffer,
  			       PyString_AS_STRING(s),
***************
*** 1104,1107 ****
--- 1165,1169 ----
  	int i, len, nargs, nkeywords;
  	char *msg, **p;
+ 	PyObject *freelist = NULL;
  
  	assert(args != NULL && PyTuple_Check(args));
***************
*** 1228,1235 ****
  			format++;
  		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
! 				 levels, msgbuf, sizeof(msgbuf));
  		if (msg) {
  			seterror(i+1, msg, levels, fname, message);
! 			return 0;
  		}
  	}
--- 1290,1297 ----
  			format++;
  		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
! 				  levels, msgbuf, sizeof(msgbuf), &freelist);
  		if (msg) {
  			seterror(i+1, msg, levels, fname, message);
! 			return cleanreturn(0, freelist);
  		}
  	}
***************
*** 1237,1241 ****
  	/* handle no keyword parameters in call */	
  	if (nkeywords == 0)
! 		return 1; 
  
  	/* convert the keyword arguments; this uses the format 
--- 1299,1303 ----
  	/* handle no keyword parameters in call */	
  	if (nkeywords == 0)
! 		return cleanreturn(1, freelist);
  
  	/* convert the keyword arguments; this uses the format 
***************
*** 1249,1257 ****
  			Py_INCREF(item);
  			msg = convertitem(item, &format, p_va, levels, msgbuf,
! 					  sizeof(msgbuf));
  			Py_DECREF(item);
  			if (msg) {
  				seterror(i+1, msg, levels, fname, message);
! 				return 0;
  			}
  			--nkeywords;
--- 1311,1319 ----
  			Py_INCREF(item);
  			msg = convertitem(item, &format, p_va, levels, msgbuf,
! 					  sizeof(msgbuf), &freelist);
  			Py_DECREF(item);
  			if (msg) {
  				seterror(i+1, msg, levels, fname, message);
! 				return cleanreturn(0, freelist);
  			}
  			--nkeywords;
***************
*** 1260,1269 ****
  		}
  		else if (PyErr_Occurred())
! 			return 0;
  		else {
  			msg = skipitem(&format, p_va);
  			if (msg) {
  				seterror(i+1, msg, levels, fname, message);
! 				return 0;
  			}
  		}
--- 1322,1331 ----
  		}
  		else if (PyErr_Occurred())
! 			return cleanreturn(0, freelist);
  		else {
  			msg = skipitem(&format, p_va);
  			if (msg) {
  				seterror(i+1, msg, levels, fname, message);
! 				return cleanreturn(0, freelist);
  			}
  		}
***************
*** 1280,1284 ****
  				PyErr_SetString(PyExc_TypeError, 
  					        "keywords must be strings");
! 				return 0;
  			}
  			ks = PyString_AsString(key);
--- 1342,1346 ----
  				PyErr_SetString(PyExc_TypeError, 
  					        "keywords must be strings");
! 				return cleanreturn(0, freelist);
  			}
  			ks = PyString_AsString(key);
***************
*** 1294,1303 ****
  					     "argument for this function",
  					     ks);
! 				return 0;
  			}
  		}
  	}
  
! 	return 1;
  }
  
--- 1356,1365 ----
  					     "argument for this function",
  					     ks);
! 				return cleanreturn(0, freelist);
  			}
  		}
  	}
  
! 	return cleanreturn(1, freelist);
  }