[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);
}